@orthacms/content-server 0.4.2 → 0.5.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 (246) hide show
  1. package/dist/index.d.ts +16 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +41 -1
  4. package/dist/lib/content.module.d.ts.map +1 -1
  5. package/dist/lib/content.module.js +31 -1
  6. package/dist/lib/copilot/entry-proposal.applier.d.ts.map +1 -1
  7. package/dist/lib/copilot/entry-proposal.applier.js +5 -4
  8. package/dist/lib/docs/describe-content-api.d.ts +7 -0
  9. package/dist/lib/docs/describe-content-api.d.ts.map +1 -1
  10. package/dist/lib/docs/describe-content-api.js +177 -53
  11. package/dist/lib/docs/describe-views-api.d.ts +19 -0
  12. package/dist/lib/docs/describe-views-api.d.ts.map +1 -0
  13. package/dist/lib/docs/describe-views-api.js +76 -0
  14. package/dist/lib/docs/field-schema.d.ts.map +1 -1
  15. package/dist/lib/docs/field-schema.js +36 -2
  16. package/dist/lib/docs/openapi-writer.d.ts +49 -0
  17. package/dist/lib/docs/openapi-writer.d.ts.map +1 -0
  18. package/dist/lib/docs/openapi-writer.js +76 -0
  19. package/dist/lib/docs/public-api-schemas.d.ts +45 -0
  20. package/dist/lib/docs/public-api-schemas.d.ts.map +1 -0
  21. package/dist/lib/docs/public-api-schemas.js +377 -0
  22. package/dist/lib/docs/views-schemas.d.ts +22 -0
  23. package/dist/lib/docs/views-schemas.d.ts.map +1 -0
  24. package/dist/lib/docs/views-schemas.js +156 -0
  25. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts +8 -2
  26. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts.map +1 -1
  27. package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.js +19 -4
  28. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts +2 -2
  29. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts.map +1 -1
  30. package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.js +14 -4
  31. package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts +6 -8
  32. package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts.map +1 -1
  33. package/dist/lib/entries/application/use-cases/publish-entry.use-case.js +10 -4
  34. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts +2 -5
  35. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts.map +1 -1
  36. package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.js +6 -1
  37. package/dist/lib/entries/domain/entry.d.ts +8 -1
  38. package/dist/lib/entries/domain/entry.d.ts.map +1 -1
  39. package/dist/lib/entries/domain/entry.js +12 -12
  40. package/dist/lib/entries/domain/events/entry-events.d.ts +47 -5
  41. package/dist/lib/entries/domain/events/entry-events.d.ts.map +1 -1
  42. package/dist/lib/entries/domain/events/entry-events.js +26 -10
  43. package/dist/lib/entries/entries.constants.d.ts +10 -2
  44. package/dist/lib/entries/entries.constants.d.ts.map +1 -1
  45. package/dist/lib/entries/entries.constants.js +11 -2
  46. package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts +2 -2
  47. package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts.map +1 -1
  48. package/dist/lib/entries/http/controllers/bulk-entries.controller.js +8 -6
  49. package/dist/lib/entries/http/controllers/create-entry.controller.d.ts.map +1 -1
  50. package/dist/lib/entries/http/controllers/create-entry.controller.js +1 -1
  51. package/dist/lib/entries/http/controllers/update-entry.controller.d.ts.map +1 -1
  52. package/dist/lib/entries/http/controllers/update-entry.controller.js +1 -1
  53. package/dist/lib/entries/http/dto/extension-bag.validator.d.ts +14 -0
  54. package/dist/lib/entries/http/dto/extension-bag.validator.d.ts.map +1 -0
  55. package/dist/lib/entries/http/dto/extension-bag.validator.js +42 -0
  56. package/dist/lib/entries/http/dto/save-entry.dto.d.ts +16 -0
  57. package/dist/lib/entries/http/dto/save-entry.dto.d.ts.map +1 -1
  58. package/dist/lib/entries/http/dto/save-entry.dto.js +30 -0
  59. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts +50 -8
  60. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts.map +1 -1
  61. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.js +183 -32
  62. package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts +38 -5
  63. package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts.map +1 -1
  64. package/dist/lib/entries/infrastructure/persistence/relation-link.service.js +38 -6
  65. package/dist/lib/entries/infrastructure/queries/entries.service.d.ts +3 -1
  66. package/dist/lib/entries/infrastructure/queries/entries.service.d.ts.map +1 -1
  67. package/dist/lib/entries/infrastructure/queries/entries.service.js +17 -5
  68. package/dist/lib/entries/infrastructure/queries/entry-match.query.d.ts +82 -0
  69. package/dist/lib/entries/infrastructure/queries/entry-match.query.d.ts.map +1 -0
  70. package/dist/lib/entries/infrastructure/queries/entry-match.query.js +152 -0
  71. package/dist/lib/extension/entry-filter-provider.d.ts +79 -0
  72. package/dist/lib/extension/entry-filter-provider.d.ts.map +1 -0
  73. package/dist/lib/extension/entry-filter-provider.js +149 -0
  74. package/dist/lib/extension/entry-write-extension.d.ts +185 -0
  75. package/dist/lib/extension/entry-write-extension.d.ts.map +1 -0
  76. package/dist/lib/extension/entry-write-extension.js +182 -0
  77. package/dist/lib/extension/read-scope.d.ts +107 -0
  78. package/dist/lib/extension/read-scope.d.ts.map +1 -0
  79. package/dist/lib/extension/read-scope.js +131 -0
  80. package/dist/lib/insights/docs/describe-content-insights-api.d.ts +23 -0
  81. package/dist/lib/insights/docs/describe-content-insights-api.d.ts.map +1 -0
  82. package/dist/lib/insights/docs/describe-content-insights-api.js +329 -0
  83. package/dist/lib/mcp/content-tools.provider.d.ts.map +1 -1
  84. package/dist/lib/mcp/content-tools.provider.js +10 -9
  85. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts +14 -13
  86. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts.map +1 -1
  87. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.js +62 -46
  88. package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts.map +1 -1
  89. package/dist/lib/public-api/http/guards/api-token-workspace.guard.js +8 -0
  90. package/dist/lib/public-api/infrastructure/public-entries.query.d.ts +14 -1
  91. package/dist/lib/public-api/infrastructure/public-entries.query.d.ts.map +1 -1
  92. package/dist/lib/public-api/infrastructure/public-entries.query.js +20 -3
  93. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts +10 -9
  94. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts.map +1 -1
  95. package/dist/lib/public-api/infrastructure/public-entry-writes.service.js +23 -24
  96. package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts +16 -4
  97. package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts.map +1 -1
  98. package/dist/lib/public-api/infrastructure/public-expansion.query.js +29 -9
  99. package/dist/lib/public-api/infrastructure/token-actor.d.ts +37 -0
  100. package/dist/lib/public-api/infrastructure/token-actor.d.ts.map +1 -0
  101. package/dist/lib/public-api/infrastructure/token-actor.js +58 -0
  102. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts.map +1 -1
  103. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.js +23 -1
  104. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts +7 -1
  105. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts.map +1 -1
  106. package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.js +9 -2
  107. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts +28 -0
  108. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts.map +1 -0
  109. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.js +52 -0
  110. package/dist/lib/revisions/types/revision-view.d.ts +11 -0
  111. package/dist/lib/revisions/types/revision-view.d.ts.map +1 -1
  112. package/dist/lib/utils/content-plugin.d.ts.map +1 -1
  113. package/dist/lib/utils/content-plugin.js +10 -1
  114. package/dist/lib/utils/content-views-plugin.d.ts +28 -0
  115. package/dist/lib/utils/content-views-plugin.d.ts.map +1 -0
  116. package/dist/lib/utils/content-views-plugin.js +37 -0
  117. package/dist/lib/views/application/queries/saved-views.query.d.ts +16 -0
  118. package/dist/lib/views/application/queries/saved-views.query.d.ts.map +1 -0
  119. package/dist/lib/views/application/queries/saved-views.query.js +46 -0
  120. package/dist/lib/views/application/saved-view-access.service.d.ts +30 -0
  121. package/dist/lib/views/application/saved-view-access.service.d.ts.map +1 -0
  122. package/dist/lib/views/application/saved-view-access.service.js +55 -0
  123. package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts +30 -0
  124. package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts.map +1 -0
  125. package/dist/lib/views/application/use-cases/create-saved-view.use-case.js +81 -0
  126. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts +18 -0
  127. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts.map +1 -0
  128. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.js +56 -0
  129. package/dist/lib/views/application/use-cases/set-default-view.use-case.d.ts +23 -0
  130. package/dist/lib/views/application/use-cases/set-default-view.use-case.d.ts.map +1 -0
  131. package/dist/lib/views/application/use-cases/set-default-view.use-case.js +51 -0
  132. package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts +24 -0
  133. package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts.map +1 -0
  134. package/dist/lib/views/application/use-cases/update-saved-view.use-case.js +90 -0
  135. package/dist/lib/views/application/view-scope.service.d.ts +25 -0
  136. package/dist/lib/views/application/view-scope.service.d.ts.map +1 -0
  137. package/dist/lib/views/application/view-scope.service.js +45 -0
  138. package/dist/lib/views/content-views.module.d.ts +22 -0
  139. package/dist/lib/views/content-views.module.d.ts.map +1 -0
  140. package/dist/lib/views/content-views.module.js +63 -0
  141. package/dist/lib/views/domain/errors/index.d.ts +6 -0
  142. package/dist/lib/views/domain/errors/index.d.ts.map +1 -0
  143. package/dist/lib/views/domain/errors/index.js +12 -0
  144. package/dist/lib/views/domain/errors/saved-view-forbidden.error.d.ts +10 -0
  145. package/dist/lib/views/domain/errors/saved-view-forbidden.error.d.ts.map +1 -0
  146. package/dist/lib/views/domain/errors/saved-view-forbidden.error.js +16 -0
  147. package/dist/lib/views/domain/errors/saved-view-limit-error.d.ts +9 -0
  148. package/dist/lib/views/domain/errors/saved-view-limit-error.d.ts.map +1 -0
  149. package/dist/lib/views/domain/errors/saved-view-limit-error.js +16 -0
  150. package/dist/lib/views/domain/errors/saved-view-name-taken.error.d.ts +5 -0
  151. package/dist/lib/views/domain/errors/saved-view-name-taken.error.d.ts.map +1 -0
  152. package/dist/lib/views/domain/errors/saved-view-name-taken.error.js +11 -0
  153. package/dist/lib/views/domain/errors/saved-view-not-found.error.d.ts +9 -0
  154. package/dist/lib/views/domain/errors/saved-view-not-found.error.d.ts.map +1 -0
  155. package/dist/lib/views/domain/errors/saved-view-not-found.error.js +15 -0
  156. package/dist/lib/views/domain/events/saved-view-events.d.ts +28 -0
  157. package/dist/lib/views/domain/events/saved-view-events.d.ts.map +1 -0
  158. package/dist/lib/views/domain/events/saved-view-events.js +38 -0
  159. package/dist/lib/views/domain/saved-view.d.ts +66 -0
  160. package/dist/lib/views/domain/saved-view.d.ts.map +1 -0
  161. package/dist/lib/views/domain/saved-view.js +18 -0
  162. package/dist/lib/views/domain/saved-view.repository.d.ts +77 -0
  163. package/dist/lib/views/domain/saved-view.repository.d.ts.map +1 -0
  164. package/dist/lib/views/domain/saved-view.repository.js +5 -0
  165. package/dist/lib/views/http/controllers/saved-views.controller.d.ts +45 -0
  166. package/dist/lib/views/http/controllers/saved-views.controller.d.ts.map +1 -0
  167. package/dist/lib/views/http/controllers/saved-views.controller.js +216 -0
  168. package/dist/lib/views/http/controllers/to-http-error.d.ts +10 -0
  169. package/dist/lib/views/http/controllers/to-http-error.d.ts.map +1 -0
  170. package/dist/lib/views/http/controllers/to-http-error.js +26 -0
  171. package/dist/lib/views/http/dto/save-view.dto.d.ts +54 -0
  172. package/dist/lib/views/http/dto/save-view.dto.d.ts.map +1 -0
  173. package/dist/lib/views/http/dto/save-view.dto.js +230 -0
  174. package/dist/lib/views/http/dto/view-payload.validator.d.ts +20 -0
  175. package/dist/lib/views/http/dto/view-payload.validator.d.ts.map +1 -0
  176. package/dist/lib/views/http/dto/view-payload.validator.js +52 -0
  177. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts +26 -0
  178. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts.map +1 -0
  179. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.js +135 -0
  180. package/dist/lib/views/infrastructure/schema/external-refs.d.ts +68 -0
  181. package/dist/lib/views/infrastructure/schema/external-refs.d.ts.map +1 -0
  182. package/dist/lib/views/infrastructure/schema/external-refs.js +29 -0
  183. package/dist/lib/views/infrastructure/schema/index.d.ts +8 -0
  184. package/dist/lib/views/infrastructure/schema/index.d.ts.map +1 -0
  185. package/dist/lib/views/infrastructure/schema/index.js +13 -0
  186. package/dist/lib/views/infrastructure/schema/saved-views.d.ts +275 -0
  187. package/dist/lib/views/infrastructure/schema/saved-views.d.ts.map +1 -0
  188. package/dist/lib/views/infrastructure/schema/saved-views.js +87 -0
  189. package/dist/lib/views/views.constants.d.ts +26 -0
  190. package/dist/lib/views/views.constants.d.ts.map +1 -0
  191. package/dist/lib/views/views.constants.js +28 -0
  192. package/dist/lib/views/views.tokens.d.ts +17 -0
  193. package/dist/lib/views/views.tokens.d.ts.map +1 -0
  194. package/dist/lib/views/views.tokens.js +21 -0
  195. package/migrations/0000_saved_views.sql +29 -0
  196. package/migrations/meta/0000_snapshot.json +256 -0
  197. package/migrations/meta/_journal.json +13 -0
  198. package/package.json +13 -12
  199. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts +0 -26
  200. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts.map +0 -1
  201. package/dist/lib/entries/controllers/create-entry.controller.d.ts +0 -20
  202. package/dist/lib/entries/controllers/create-entry.controller.d.ts.map +0 -1
  203. package/dist/lib/entries/controllers/delete-entry.controller.d.ts +0 -24
  204. package/dist/lib/entries/controllers/delete-entry.controller.d.ts.map +0 -1
  205. package/dist/lib/entries/controllers/get-entry.controller.d.ts +0 -34
  206. package/dist/lib/entries/controllers/get-entry.controller.d.ts.map +0 -1
  207. package/dist/lib/entries/controllers/list-entries.controller.d.ts +0 -20
  208. package/dist/lib/entries/controllers/list-entries.controller.d.ts.map +0 -1
  209. package/dist/lib/entries/controllers/publish-entry.controller.d.ts +0 -19
  210. package/dist/lib/entries/controllers/publish-entry.controller.d.ts.map +0 -1
  211. package/dist/lib/entries/controllers/resolve-type.d.ts +0 -9
  212. package/dist/lib/entries/controllers/resolve-type.d.ts.map +0 -1
  213. package/dist/lib/entries/controllers/update-entry.controller.d.ts +0 -18
  214. package/dist/lib/entries/controllers/update-entry.controller.d.ts.map +0 -1
  215. package/dist/lib/entries/dto/bulk-ids.dto.d.ts +0 -11
  216. package/dist/lib/entries/dto/bulk-ids.dto.d.ts.map +0 -1
  217. package/dist/lib/entries/dto/list-entries-query.dto.d.ts +0 -46
  218. package/dist/lib/entries/dto/list-entries-query.dto.d.ts.map +0 -1
  219. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts +0 -19
  220. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts.map +0 -1
  221. package/dist/lib/entries/dto/save-entry.dto.d.ts +0 -46
  222. package/dist/lib/entries/dto/save-entry.dto.d.ts.map +0 -1
  223. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts +0 -24
  224. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts.map +0 -1
  225. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts +0 -40
  226. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts.map +0 -1
  227. package/dist/lib/entries/services/entries.service.d.ts +0 -59
  228. package/dist/lib/entries/services/entries.service.d.ts.map +0 -1
  229. package/dist/lib/entries/services/entry-counter.service.d.ts +0 -31
  230. package/dist/lib/entries/services/entry-counter.service.d.ts.map +0 -1
  231. package/dist/lib/entries/services/entry-filter-schema.d.ts +0 -32
  232. package/dist/lib/entries/services/entry-filter-schema.d.ts.map +0 -1
  233. package/dist/lib/entries/services/entry-row.d.ts +0 -56
  234. package/dist/lib/entries/services/entry-row.d.ts.map +0 -1
  235. package/dist/lib/entries/services/entry-writer.service.d.ts +0 -193
  236. package/dist/lib/entries/services/entry-writer.service.d.ts.map +0 -1
  237. package/dist/lib/entries/services/relation-link.service.d.ts +0 -115
  238. package/dist/lib/entries/services/relation-link.service.d.ts.map +0 -1
  239. package/dist/lib/extension/per-locale-relation.d.ts +0 -18
  240. package/dist/lib/extension/per-locale-relation.d.ts.map +0 -1
  241. package/dist/lib/public/controllers/get-public-entry.controller.d.ts +0 -26
  242. package/dist/lib/public/controllers/get-public-entry.controller.d.ts.map +0 -1
  243. package/dist/lib/public/controllers/list-public-entries.controller.d.ts +0 -24
  244. package/dist/lib/public/controllers/list-public-entries.controller.d.ts.map +0 -1
  245. package/dist/lib/public/controllers/public-schema.controller.d.ts +0 -18
  246. package/dist/lib/public/controllers/public-schema.controller.d.ts.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { type Database } from '@orthacms/database';
2
2
  import { type AnyContentType } from '../../types/content-type';
3
3
  import { type MediaAssetResolver } from '../../extension/media-asset-resolver';
4
+ import { ContentReadScopeRegistry } from '../../extension/read-scope';
4
5
  import { RelationLinkService } from '../../entries/infrastructure/persistence/relation-link.service';
5
6
  import type { PublicMediaFieldView, PublicRelationFieldView } from '../types/public-expansion';
6
7
  /** A generated content row seen as a bag of values by property name. */
@@ -31,7 +32,16 @@ export declare class PublicExpansionQuery {
31
32
  private readonly db;
32
33
  private readonly relationLinks;
33
34
  private readonly media?;
34
- constructor(db: Database, relationLinks: RelationLinkService, media?: MediaAssetResolver | undefined);
35
+ private readonly readScopes?;
36
+ constructor(db: Database, relationLinks: RelationLinkService, media?: MediaAssetResolver | undefined, readScopes?: ContentReadScopeRegistry | undefined);
37
+ /**
38
+ * The read-scope fragments for one hop's target type.
39
+ *
40
+ * The target is a different content type from the one the request named, so
41
+ * the scope is asked about **it** — a scope keyed to the requested type
42
+ * would leave every relation target unguarded.
43
+ */
44
+ private readScopeWhere;
35
45
  /**
36
46
  * Validate a `?relationFields=` list: every name must be a relation field
37
47
  * on the type, and its target must be a content type the workspace was
@@ -47,9 +57,11 @@ export declare class PublicExpansionQuery {
47
57
  * One capped page of links per requested relation field, for every row on
48
58
  * the page, keyed by entry id.
49
59
  *
50
- * `publishedOnly` is the public difference: a draft target is neither shown
51
- * nor counted, so `total` is the number of links a caller can actually
52
- * reach.
60
+ * `publishedOnly` is the public difference: a draft target or one a bound
61
+ * read scope hides from this reader is neither shown **nor counted**, so
62
+ * `total` is the number of links this caller can actually reach. Counting
63
+ * them would leak the cardinality of what is hidden: "5 links, 2 visible"
64
+ * says three restricted records exist here.
53
65
  */
54
66
  relationsForRows(type: AnyContentType, fields: string[], rows: Row[], workspaceId: string, limit?: number): Promise<Map<string, Record<string, PublicRelationFieldView>>>;
55
67
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"public-expansion.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-expansion.query.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE7E,OAAO,EAEH,KAAK,kBAAkB,EAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAErG,OAAO,KAAK,EACR,oBAAoB,EAEpB,uBAAuB,EAC1B,MAAM,2BAA2B,CAAC;AAInC,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAKnC;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAwCtC;;;;;;;;;;;;GAYG;AACH,qBACa,oBAAoB;IAEP,OAAO,CAAC,QAAQ,CAAC,EAAE;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAG9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAJY,EAAE,EAAE,QAAQ,EAC9B,aAAa,EAAE,mBAAmB,EAGlC,KAAK,CAAC,EAAE,kBAAkB,YAAA;IAG/C;;;;;;;OAOG;IACH,mBAAmB,CACf,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,EAAE;IA8BX,yEAAyE;IACzE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE;IAiBzE;;;;;;;OAOG;IACG,gBAAgB,CAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAyChE;;;;OAIG;IACG,oBAAoB,CACtB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACjE,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAqBnD;;;;;;;;OAQG;YACW,iBAAiB;IAsD/B;;;;;;OAMG;IACG,YAAY,CACd,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IA+F7D;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAgBvB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;CA+BtB"}
1
+ {"version":3,"file":"public-expansion.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-expansion.query.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE7E,OAAO,EAEH,KAAK,kBAAkB,EAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAErG,OAAO,KAAK,EACR,oBAAoB,EAEpB,uBAAuB,EAC1B,MAAM,2BAA2B,CAAC;AAInC,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAKnC;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAwCtC;;;;;;;;;;;;GAYG;AACH,qBACa,oBAAoB;IAEP,OAAO,CAAC,QAAQ,CAAC,EAAE;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAG9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAKvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBATO,EAAE,EAAE,QAAQ,EAC9B,aAAa,EAAE,mBAAmB,EAGlC,KAAK,CAAC,EAAE,kBAAkB,YAAA,EAK1B,UAAU,CAAC,EAAE,wBAAwB,YAAA;IAG1D;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;OAOG;IACH,mBAAmB,CACf,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,EAAE;IA8BX,yEAAyE;IACzE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE;IAiBzE;;;;;;;;;OASG;IACG,gBAAgB,CAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IA6ChE;;;;OAIG;IACG,oBAAoB,CACtB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACjE,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAqBnD;;;;;;;;OAQG;YACW,iBAAiB;IAuD/B;;;;;;OAMG;IACG,YAAY,CACd,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IA+F7D;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAgBvB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;CA+BtB"}
@@ -9,6 +9,7 @@ const content_domain_1 = require("@orthacms/content-domain");
9
9
  const content_type_1 = require("../../types/content-type");
10
10
  const fields_1 = require("../../types/fields");
11
11
  const media_asset_resolver_1 = require("../../extension/media-asset-resolver");
12
+ const read_scope_1 = require("../../extension/read-scope");
12
13
  const relation_link_service_1 = require("../../entries/infrastructure/persistence/relation-link.service");
13
14
  const public_list_entries_query_dto_1 = require("../http/dto/public-list-entries-query.dto");
14
15
  const public_entry_row_1 = require("./public-entry-row");
@@ -73,10 +74,22 @@ let PublicExpansionQuery = class PublicExpansionQuery {
73
74
  db;
74
75
  relationLinks;
75
76
  media;
76
- constructor(db, relationLinks, media) {
77
+ readScopes;
78
+ constructor(db, relationLinks, media, readScopes) {
77
79
  this.db = db;
78
80
  this.relationLinks = relationLinks;
79
81
  this.media = media;
82
+ this.readScopes = readScopes;
83
+ }
84
+ /**
85
+ * The read-scope fragments for one hop's target type.
86
+ *
87
+ * The target is a different content type from the one the request named, so
88
+ * the scope is asked about **it** — a scope keyed to the requested type
89
+ * would leave every relation target unguarded.
90
+ */
91
+ readScopeWhere(type, workspaceId) {
92
+ return this.readScopes?.fragments({ type, workspaceId }) ?? [];
80
93
  }
81
94
  /**
82
95
  * Validate a `?relationFields=` list: every name must be a relation field
@@ -121,9 +134,11 @@ let PublicExpansionQuery = class PublicExpansionQuery {
121
134
  * One capped page of links per requested relation field, for every row on
122
135
  * the page, keyed by entry id.
123
136
  *
124
- * `publishedOnly` is the public difference: a draft target is neither shown
125
- * nor counted, so `total` is the number of links a caller can actually
126
- * reach.
137
+ * `publishedOnly` is the public difference: a draft target or one a bound
138
+ * read scope hides from this reader is neither shown **nor counted**, so
139
+ * `total` is the number of links this caller can actually reach. Counting
140
+ * them would leak the cardinality of what is hidden: "5 links, 2 visible"
141
+ * says three restricted records exist here.
127
142
  */
128
143
  async relationsForRows(type, fields, rows, workspaceId, limit = public_list_entries_query_dto_1.DEFAULT_EXPANSION_LIMIT) {
129
144
  const out = new Map();
@@ -140,9 +155,13 @@ let PublicExpansionQuery = class PublicExpansionQuery {
140
155
  for (const [field, value] of Object.entries(byField)) {
141
156
  const linked = entriesById.get(field);
142
157
  view[field] = {
143
- // Preserve the preview's link order, and drop any id the
144
- // hydration didn't return (it named a target the caller
145
- // can't see already excluded from `total` upstream).
158
+ // Preserve the preview's link order. Nothing should drop
159
+ // here any more `previewForEntries` applies the same
160
+ // visibility (published-only **and** the bound read scopes)
161
+ // inside its window, so an unreachable target is already
162
+ // out of both `items` and `total`. The filter stays as a
163
+ // belt: a hydration miss must never leave a hole in the
164
+ // array, and it is cheap to keep honest.
146
165
  items: value.items
147
166
  .map((ref) => linked?.get(ref.id))
148
167
  .filter((entry) => !!entry),
@@ -209,7 +228,7 @@ let PublicExpansionQuery = class PublicExpansionQuery {
209
228
  ? (0, drizzle_orm_1.eq)(cols['status'], content_type_1.ENTRY_STATUS.Published)
210
229
  : undefined, target.paranoid
211
230
  ? (0, drizzle_orm_1.isNull)(cols['deletedAt'])
212
- : undefined)));
231
+ : undefined, ...this.readScopeWhere(target, workspaceId))));
213
232
  out.set(field, new Map(rows.map((row) => [
214
233
  row['id'],
215
234
  (0, public_entry_row_1.toPublicEntry)(target, row)
@@ -358,7 +377,8 @@ exports.PublicExpansionQuery = PublicExpansionQuery = tslib_1.__decorate([
358
377
  tslib_1.__param(0, (0, database_1.InjectDatabase)()),
359
378
  tslib_1.__param(2, (0, common_1.Optional)()),
360
379
  tslib_1.__param(2, (0, media_asset_resolver_1.InjectMediaAssetResolver)()),
361
- tslib_1.__metadata("design:paramtypes", [Object, relation_link_service_1.RelationLinkService, Object])
380
+ tslib_1.__param(3, (0, common_1.Optional)()),
381
+ tslib_1.__metadata("design:paramtypes", [Object, relation_link_service_1.RelationLinkService, Object, read_scope_1.ContentReadScopeRegistry])
362
382
  ], PublicExpansionQuery);
363
383
  /** The asset ids stored in a media field — one id, or an ordered list. */
364
384
  function mediaRefsOf(value) {
@@ -0,0 +1,37 @@
1
+ import { type EventActor } from '@orthacms/database';
2
+ import type { ToolActor } from '@orthacms/tools-server';
3
+ import type { PublicApiToken } from '../http/api-token-request';
4
+ /**
5
+ * The API token as the {@link EventActor} a public-API write stamps onto its
6
+ * domain events.
7
+ *
8
+ * Every write over the public REST API, GraphQL and MCP used to reach the audit
9
+ * log with no actor at all and render as "System" — not an oversight but the
10
+ * only honest option at the time, since `actor_id` meant "a `users` row" and a
11
+ * token is not one. `activity_events.actor_type` is what makes naming the
12
+ * credential possible, so this is the seam that fills it.
13
+ *
14
+ * `email` carries the token's **label**, because that is the readable name a
15
+ * row needs and a token has no address; `actor_type` is what tells a client not
16
+ * to read it as one. The token id goes in `id` — the same handle the API Tokens
17
+ * page lists and the revoke button acts on, so a row leads straight to the
18
+ * credential it names.
19
+ *
20
+ * A revision's `created_by` still gets `null` for a token: that column really is
21
+ * a `users` FK. The split lives in `EntryWriterService`'s `revisionActorId`.
22
+ */
23
+ export declare function toTokenActor(token: PublicApiToken): EventActor;
24
+ /**
25
+ * The {@link EventActor} for a write made through the shared **tool registry** —
26
+ * an MCP client, or the copilot's own run loop.
27
+ *
28
+ * `ToolActor` already carries the distinction this needs (`kind`, `id`,
29
+ * `displayName`), which is the point of it being transport-neutral: one
30
+ * conversion covers both surfaces, and neither had any actor on its writes
31
+ * before. A token acts as itself here exactly as it does over REST — the
32
+ * minting user in `actor.userId` is attribution for a revision's `created_by`,
33
+ * not the principal that performed the call, and conflating them would name a
34
+ * person for every request an integration makes.
35
+ */
36
+ export declare function toToolEventActor(actor: ToolActor): EventActor;
37
+ //# sourceMappingURL=token-actor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-actor.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/token-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAO9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAa7D"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toTokenActor = toTokenActor;
4
+ exports.toToolEventActor = toToolEventActor;
5
+ const database_1 = require("@orthacms/database");
6
+ /**
7
+ * The API token as the {@link EventActor} a public-API write stamps onto its
8
+ * domain events.
9
+ *
10
+ * Every write over the public REST API, GraphQL and MCP used to reach the audit
11
+ * log with no actor at all and render as "System" — not an oversight but the
12
+ * only honest option at the time, since `actor_id` meant "a `users` row" and a
13
+ * token is not one. `activity_events.actor_type` is what makes naming the
14
+ * credential possible, so this is the seam that fills it.
15
+ *
16
+ * `email` carries the token's **label**, because that is the readable name a
17
+ * row needs and a token has no address; `actor_type` is what tells a client not
18
+ * to read it as one. The token id goes in `id` — the same handle the API Tokens
19
+ * page lists and the revoke button acts on, so a row leads straight to the
20
+ * credential it names.
21
+ *
22
+ * A revision's `created_by` still gets `null` for a token: that column really is
23
+ * a `users` FK. The split lives in `EntryWriterService`'s `revisionActorId`.
24
+ */
25
+ function toTokenActor(token) {
26
+ return {
27
+ id: token.id,
28
+ email: token.name,
29
+ type: database_1.EVENT_ACTOR_TYPE.ApiToken,
30
+ label: token.name
31
+ };
32
+ }
33
+ /**
34
+ * The {@link EventActor} for a write made through the shared **tool registry** —
35
+ * an MCP client, or the copilot's own run loop.
36
+ *
37
+ * `ToolActor` already carries the distinction this needs (`kind`, `id`,
38
+ * `displayName`), which is the point of it being transport-neutral: one
39
+ * conversion covers both surfaces, and neither had any actor on its writes
40
+ * before. A token acts as itself here exactly as it does over REST — the
41
+ * minting user in `actor.userId` is attribution for a revision's `created_by`,
42
+ * not the principal that performed the call, and conflating them would name a
43
+ * person for every request an integration makes.
44
+ */
45
+ function toToolEventActor(actor) {
46
+ return actor.kind === 'token'
47
+ ? {
48
+ id: actor.id,
49
+ email: actor.displayName,
50
+ type: database_1.EVENT_ACTOR_TYPE.ApiToken,
51
+ label: actor.displayName
52
+ }
53
+ : {
54
+ id: actor.id,
55
+ email: actor.displayName,
56
+ type: database_1.EVENT_ACTOR_TYPE.User
57
+ };
58
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"restore-revision.use-case.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/application/use-cases/restore-revision.use-case.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kEAAkE,CAAC;AACtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAEH,KAAK,aAAa,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;GASG;AACH,qBACa,sBAAsB;IAE3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACA,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,MAAM,EAAE,kBAAkB,EACH,KAAK,EAAE,aAAa;IAG1D,OAAO,CACT,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM;IACnB;;;;OAIG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE;QACN;;;;;WAKG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC;KAC5B,GACF,OAAO,CAAC,WAAW,CAAC;CA+B1B"}
1
+ {"version":3,"file":"restore-revision.use-case.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/application/use-cases/restore-revision.use-case.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kEAAkE,CAAC;AACtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAEH,KAAK,aAAa,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;GASG;AACH,qBACa,sBAAsB;IAE3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACA,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,MAAM,EAAE,kBAAkB,EACH,KAAK,EAAE,aAAa;IAG1D,OAAO,CACT,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM;IACnB;;;;OAIG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE;QACN;;;;;WAKG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC;KAC5B,GACF,OAAO,CAAC,WAAW,CAAC;CAoD1B"}
@@ -46,7 +46,29 @@ let RestoreRevisionUseCase = class RestoreRevisionUseCase {
46
46
  values[field] = ids;
47
47
  }
48
48
  }
49
- return this.writer.update(type, id, values, workspaceId, undefined, actor, options);
49
+ return this.writer.update(type, id, values, workspaceId, undefined,
50
+ // Restoring reaches the log as the `entry.updated` its save raises,
51
+ // naming the fields it put back — which is right, and used to be
52
+ // the whole story: nothing said the edit *was* a restore, or of
53
+ // which version. `via` carries that without inventing a kind, the
54
+ // same seam a copilot-applied change uses.
55
+ actor
56
+ ? {
57
+ ...actor,
58
+ via: { kind: 'revision_restore', revisionNumber: number }
59
+ }
60
+ : actor, {
61
+ ...options,
62
+ // Put back whatever the bound extensions held when this version was
63
+ // captured — segments' audiences, today. Without it "go back to
64
+ // Tuesday" would restore Tuesday's words in front of today's
65
+ // readers, which is the half of a restore nobody would think to
66
+ // check. A version captured before any extension existed carries no
67
+ // bag, and an absent bag changes nothing (an omitted key is left
68
+ // alone) — which is the right reading: that version knows nothing
69
+ // about audiences, it does not assert the entry had none.
70
+ extensions: detail.snapshot.extra
71
+ });
50
72
  }
51
73
  };
52
74
  exports.RestoreRevisionUseCase = RestoreRevisionUseCase;
@@ -11,7 +11,13 @@ type Row = Record<string, unknown>;
11
11
  * `relations` is read separately from the join tables — those links never travel
12
12
  * in the `values` bag — inside the save transaction, so the snapshot reflects
13
13
  * exactly what committed.
14
+ *
15
+ * `extra` is the same idea one plugin further out: state a **bound entry-write
16
+ * extension** owns in a table this package knows nothing about (segments'
17
+ * audiences), read back on the same transaction. It is omitted when there is
18
+ * none, so a snapshot on an installation with no extensions is byte-for-byte
19
+ * what it was before the port existed.
14
20
  */
15
- export declare function buildSnapshot(type: AnyContentType, row: Row, relations: Record<string, string[]>): RevisionSnapshot;
21
+ export declare function buildSnapshot(type: AnyContentType, row: Row, relations: Record<string, string[]>, extra?: Record<string, unknown>): RevisionSnapshot;
16
22
  export {};
17
23
  //# sourceMappingURL=revision-snapshot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"revision-snapshot.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/persistence/revision-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACpC,gBAAgB,CAKlB"}
1
+ {"version":3,"file":"revision-snapshot.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/persistence/revision-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,gBAAgB,CAMlB"}
@@ -11,10 +11,17 @@ const entry_row_1 = require("../../../entries/infrastructure/persistence/entry-r
11
11
  * `relations` is read separately from the join tables — those links never travel
12
12
  * in the `values` bag — inside the save transaction, so the snapshot reflects
13
13
  * exactly what committed.
14
+ *
15
+ * `extra` is the same idea one plugin further out: state a **bound entry-write
16
+ * extension** owns in a table this package knows nothing about (segments'
17
+ * audiences), read back on the same transaction. It is omitted when there is
18
+ * none, so a snapshot on an installation with no extensions is byte-for-byte
19
+ * what it was before the port existed.
14
20
  */
15
- function buildSnapshot(type, row, relations) {
21
+ function buildSnapshot(type, row, relations, extra) {
16
22
  return {
17
23
  values: (0, entry_row_1.toRecord)(type, row).values,
18
- relations
24
+ relations,
25
+ ...(extra ? { extra } : {})
19
26
  };
20
27
  }
@@ -0,0 +1,28 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { UnitOfWork } from '@orthacms/database';
3
+ import { WorkspacePurgeRegistry, type WorkspacePurger, type WorkspacePurgeOutcome } from '@orthacms/workspaces-server';
4
+ /**
5
+ * Removes a deleted workspace's entry revisions.
6
+ *
7
+ * Content is otherwise the plugin that does **not** purge: a workspace holding
8
+ * entries is refused (409), because entries are authored records someone must
9
+ * delete deliberately. Revisions fall outside that protection in both
10
+ * directions. They carry a plain `workspace_id` with no foreign key, and
11
+ * `countWorkspaceEntries` sums the live `content_<name>` tables only — so a
12
+ * workspace whose entries have all been deleted counts as empty, deletes
13
+ * cleanly, and leaves its whole revision history behind pointing at nothing.
14
+ *
15
+ * That history is not an authored record in its own right: it is the version
16
+ * timeline of rows that are already gone, unreachable once the workspace it was
17
+ * scoped to no longer opens. Purging it is the same call the folder tree and the
18
+ * token bucket get — scoping rows with no independent meaning left.
19
+ */
20
+ export declare class RevisionsWorkspacePurger implements WorkspacePurger, OnModuleInit {
21
+ private readonly uow;
22
+ private readonly registry?;
23
+ readonly purgeName = "content:entry-revisions";
24
+ constructor(uow: UnitOfWork, registry?: WorkspacePurgeRegistry | undefined);
25
+ onModuleInit(): void;
26
+ purge(workspaceId: string): Promise<WorkspacePurgeOutcome>;
27
+ }
28
+ //# sourceMappingURL=revisions-workspace.purger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revisions-workspace.purger.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/purge/revisions-workspace.purger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAY,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACH,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC7B,MAAM,6BAA6B,CAAC;AAGrC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,wBAAyB,YAAW,eAAe,EAAE,YAAY;IAItE,OAAO,CAAC,QAAQ,CAAC,GAAG;IACR,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAJ1C,QAAQ,CAAC,SAAS,6BAA6B;gBAG1B,GAAG,EAAE,UAAU,EACH,QAAQ,CAAC,EAAE,sBAAsB,YAAA;IAGlE,YAAY,IAAI,IAAI;IAId,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CASnE"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RevisionsWorkspacePurger = 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
+ const revision_table_1 = require("../persistence/revision-table");
10
+ /**
11
+ * Removes a deleted workspace's entry revisions.
12
+ *
13
+ * Content is otherwise the plugin that does **not** purge: a workspace holding
14
+ * entries is refused (409), because entries are authored records someone must
15
+ * delete deliberately. Revisions fall outside that protection in both
16
+ * directions. They carry a plain `workspace_id` with no foreign key, and
17
+ * `countWorkspaceEntries` sums the live `content_<name>` tables only — so a
18
+ * workspace whose entries have all been deleted counts as empty, deletes
19
+ * cleanly, and leaves its whole revision history behind pointing at nothing.
20
+ *
21
+ * That history is not an authored record in its own right: it is the version
22
+ * timeline of rows that are already gone, unreachable once the workspace it was
23
+ * scoped to no longer opens. Purging it is the same call the folder tree and the
24
+ * token bucket get — scoping rows with no independent meaning left.
25
+ */
26
+ let RevisionsWorkspacePurger = class RevisionsWorkspacePurger {
27
+ uow;
28
+ registry;
29
+ purgeName = 'content:entry-revisions';
30
+ constructor(uow, registry) {
31
+ this.uow = uow;
32
+ this.registry = registry;
33
+ }
34
+ onModuleInit() {
35
+ this.registry?.register(this);
36
+ }
37
+ async purge(workspaceId) {
38
+ const removed = await this.uow
39
+ .current()
40
+ .delete(revision_table_1.contentEntryRevisions)
41
+ .where((0, drizzle_orm_1.eq)(revision_table_1.contentEntryRevisions.workspaceId, workspaceId))
42
+ .returning({ id: revision_table_1.contentEntryRevisions.id });
43
+ return { rows: removed.length };
44
+ }
45
+ };
46
+ exports.RevisionsWorkspacePurger = RevisionsWorkspacePurger;
47
+ exports.RevisionsWorkspacePurger = RevisionsWorkspacePurger = tslib_1.__decorate([
48
+ (0, common_1.Injectable)(),
49
+ tslib_1.__param(1, (0, common_1.Optional)()),
50
+ tslib_1.__metadata("design:paramtypes", [database_1.UnitOfWork,
51
+ workspaces_server_1.WorkspacePurgeRegistry])
52
+ ], RevisionsWorkspacePurger);
@@ -17,6 +17,17 @@ export interface RevisionSnapshot {
17
17
  * never travel in {@link values}.
18
18
  */
19
19
  relations: Record<string, string[]>;
20
+ /**
21
+ * What each bound **entry-write extension** held for the entry at capture
22
+ * time, keyed by its `key` — state a different plugin owns in a table this
23
+ * package knows nothing about (`segments` records who could read the entry).
24
+ *
25
+ * Opaque here: content-server stores it, hands it back on a restore, and
26
+ * never looks inside. Absent on an installation with no extensions, and on
27
+ * every version captured before one was installed — so a reader must treat
28
+ * a missing bag as "nothing is known", never as "the entry had none".
29
+ */
30
+ extra?: Record<string, unknown>;
20
31
  }
21
32
  /**
22
33
  * One revision as served to the admin timeline — the metadata, without the
@@ -1 +1 @@
1
- {"version":3,"file":"revision-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/revisions/types/revision-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EACR,QAAQ,EACR,WAAW,EACd,MAAM,qCAAqC,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,wDAAwD;IACxD,WAAW,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAe,SAAQ,eAAe;IACnD,6BAA6B;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC1C;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"revision-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/revisions/types/revision-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EACR,QAAQ,EACR,WAAW,EACd,MAAM,qCAAqC,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,wDAAwD;IACxD,WAAW,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAe,SAAQ,eAAe;IACnD,6BAA6B;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC1C;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACjC,iEAAiE;IACjE,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;CAC3C;AAED,kEAAkE;AAClE,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACrD,QAAQ,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,oBAAoB,GAC9B,mBAAmB,CAerB"}
1
+ {"version":3,"file":"content-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACjC,iEAAiE;IACjE,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;CAC3C;AAED,kEAAkE;AAClE,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACrD,QAAQ,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,oBAAoB,GAC9B,mBAAmB,CAsBrB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ContentPlugin = ContentPlugin;
4
4
  const content_module_1 = require("../content.module");
5
5
  const describe_content_api_1 = require("../docs/describe-content-api");
6
+ const describe_content_insights_api_1 = require("../insights/docs/describe-content-insights-api");
6
7
  const content_type_registry_1 = require("../registry/content-type-registry");
7
8
  /**
8
9
  * Content plugin factory. Builds the registry eagerly — duplicate names
@@ -29,7 +30,15 @@ function ContentPlugin(options) {
29
30
  // can see; the registry is what knows `article` from `home_page`. This
30
31
  // hook is where the code-defined types become OpenAPI schemas.
31
32
  docs: {
32
- decorate: (document) => (0, describe_content_api_1.describeContentApi)(document, registry.serializeAll())
33
+ decorate: (document) => {
34
+ (0, describe_content_api_1.describeContentApi)(document, registry.serializeAll());
35
+ // The Insights widgets are a second surface with a fixed
36
+ // contract — six unlike payloads whose views are `interface`s,
37
+ // so the scanner emits an empty 200 for each. Described from
38
+ // their own module rather than folded into the pass above:
39
+ // they are grouped under the `insights` tag, not `content`.
40
+ (0, describe_content_insights_api_1.describeContentInsightsApi)(document);
41
+ }
33
42
  }
34
43
  };
35
44
  }
@@ -0,0 +1,28 @@
1
+ import type { ServerPlugin } from '@orthacms/bootstrap-server';
2
+ import type { ContentServerPlugin } from './content-plugin';
3
+ /** Options for {@link ContentViewsPlugin}. */
4
+ export interface ContentViewsPluginOptions {
5
+ /**
6
+ * The content plugin this rides on — its registry is what turns a view's
7
+ * `content:<typeName>` scope back into a known content type. Taking the
8
+ * whole plugin (rather than a bare registry) makes the dependency visible
9
+ * at the composition root: the entry has to be listed *after* the content
10
+ * one, which is also the migration order its foreign keys need.
11
+ */
12
+ content: ContentServerPlugin;
13
+ }
14
+ /**
15
+ * Saved list views — the named filter/sort/column slices an editor returns to.
16
+ *
17
+ * A **separate `ServerPlugin` entry from the same package** as `ContentPlugin`,
18
+ * and deliberately so. `ServerPlugin.migrations` is one descriptor, and
19
+ * content's is already carrying the HOST's generated collection tables; a
20
+ * second entry is how this package ships its own fixed tables without touching
21
+ * that contract. The host applies both under their own tracking tables.
22
+ *
23
+ * Order matters at the composition root: `saved_views` has foreign keys into
24
+ * identity's `users` and workspaces' `workspaces`, and nothing declares that
25
+ * dependency — list this after both, and after `ContentPlugin` itself.
26
+ */
27
+ export declare function ContentViewsPlugin(options: ContentViewsPluginOptions): ServerPlugin;
28
+ //# sourceMappingURL=content-views-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-views-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-views-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB;IACtC;;;;;;OAMG;IACH,OAAO,EAAE,mBAAmB,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,yBAAyB,GACnC,YAAY,CAqBd"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContentViewsPlugin = ContentViewsPlugin;
4
+ const node_path_1 = require("node:path");
5
+ const content_views_module_1 = require("../views/content-views.module");
6
+ const describe_views_api_1 = require("../docs/describe-views-api");
7
+ /**
8
+ * Saved list views — the named filter/sort/column slices an editor returns to.
9
+ *
10
+ * A **separate `ServerPlugin` entry from the same package** as `ContentPlugin`,
11
+ * and deliberately so. `ServerPlugin.migrations` is one descriptor, and
12
+ * content's is already carrying the HOST's generated collection tables; a
13
+ * second entry is how this package ships its own fixed tables without touching
14
+ * that contract. The host applies both under their own tracking tables.
15
+ *
16
+ * Order matters at the composition root: `saved_views` has foreign keys into
17
+ * identity's `users` and workspaces' `workspaces`, and nothing declares that
18
+ * dependency — list this after both, and after `ContentPlugin` itself.
19
+ */
20
+ function ContentViewsPlugin(options) {
21
+ return {
22
+ name: 'content-views',
23
+ module: content_views_module_1.ContentViewsModule.forRoot(options.content.registry),
24
+ // src/lib/utils → ../../../migrations = <pkg>/migrations.
25
+ migrations: {
26
+ dir: () => (0, node_path_1.join)(__dirname, '../../../migrations'),
27
+ table: '__drizzle_migrations_content_views'
28
+ },
29
+ // `SavedView` is a framework-free `interface` (ADR-0003 forbids
30
+ // decorating it) and its `scope` is `content:<typeName>`, which only
31
+ // the registry knows — so the swagger scanner sees neither the shape
32
+ // nor the values, and this hook is where both become visible.
33
+ docs: {
34
+ decorate: (document) => (0, describe_views_api_1.describeViewsApi)(document, options.content.registry.serializeAll())
35
+ }
36
+ };
37
+ }
@@ -0,0 +1,16 @@
1
+ import type { SavedView } from '../../domain/saved-view';
2
+ import { type SavedViewRecord, type SavedViewRepository } from '../../domain/saved-view.repository';
3
+ /**
4
+ * The read side: every view a caller may see for one list, with the two
5
+ * per-caller flags the switcher renders from (`isOwn` gates Save and Delete,
6
+ * `isDefault` marks the row and drives the landing view).
7
+ */
8
+ export declare class SavedViewsQuery {
9
+ private readonly repository;
10
+ constructor(repository: SavedViewRepository);
11
+ /** Views visible to `readerId` in this workspace + scope. */
12
+ list(workspaceId: string, scope: string, readerId: string): Promise<SavedView[]>;
13
+ }
14
+ /** Projects a stored row into the API shape for one reader. */
15
+ export declare function toSavedView(record: SavedViewRecord, readerId: string, defaultId: string | null): SavedView;
16
+ //# sourceMappingURL=saved-views.query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-views.query.d.ts","sourceRoot":"","sources":["../../../../../src/lib/views/application/queries/saved-views.query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAEH,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAC3B,MAAM,oCAAoC,CAAC;AAE5C;;;;GAIG;AACH,qBACa,eAAe;IAGpB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,mBAAmB;IAGpD,6DAA6D;IACvD,IAAI,CACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC;CAS1B;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CACvB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAAG,IAAI,GACzB,SAAS,CAYX"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SavedViewsQuery = void 0;
4
+ exports.toSavedView = toSavedView;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const saved_view_repository_1 = require("../../domain/saved-view.repository");
8
+ /**
9
+ * The read side: every view a caller may see for one list, with the two
10
+ * per-caller flags the switcher renders from (`isOwn` gates Save and Delete,
11
+ * `isDefault` marks the row and drives the landing view).
12
+ */
13
+ let SavedViewsQuery = class SavedViewsQuery {
14
+ repository;
15
+ constructor(repository) {
16
+ this.repository = repository;
17
+ }
18
+ /** Views visible to `readerId` in this workspace + scope. */
19
+ async list(workspaceId, scope, readerId) {
20
+ const [records, defaultId] = await Promise.all([
21
+ this.repository.listVisible(workspaceId, scope, readerId),
22
+ this.repository.findDefaultId(readerId, scope)
23
+ ]);
24
+ return records.map((record) => toSavedView(record, readerId, defaultId));
25
+ }
26
+ };
27
+ exports.SavedViewsQuery = SavedViewsQuery;
28
+ exports.SavedViewsQuery = SavedViewsQuery = tslib_1.__decorate([
29
+ (0, common_1.Injectable)(),
30
+ tslib_1.__param(0, (0, common_1.Inject)(saved_view_repository_1.SAVED_VIEW_REPOSITORY)),
31
+ tslib_1.__metadata("design:paramtypes", [Object])
32
+ ], SavedViewsQuery);
33
+ /** Projects a stored row into the API shape for one reader. */
34
+ function toSavedView(record, readerId, defaultId) {
35
+ return {
36
+ id: record.id,
37
+ scope: record.scope,
38
+ name: record.name,
39
+ visibility: record.visibility,
40
+ ownerId: record.ownerId,
41
+ isOwn: record.ownerId === readerId,
42
+ isDefault: record.id === defaultId,
43
+ payload: record.payload,
44
+ updatedAt: record.updatedAt.toISOString()
45
+ };
46
+ }