@orthacms/content-server 0.4.3 → 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 (144) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/lib/content.module.d.ts.map +1 -1
  5. package/dist/lib/content.module.js +8 -0
  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/infrastructure/persistence/entry-writer.service.d.ts +22 -6
  50. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts.map +1 -1
  51. package/dist/lib/entries/infrastructure/persistence/entry-writer.service.js +71 -17
  52. package/dist/lib/insights/docs/describe-content-insights-api.d.ts +23 -0
  53. package/dist/lib/insights/docs/describe-content-insights-api.d.ts.map +1 -0
  54. package/dist/lib/insights/docs/describe-content-insights-api.js +329 -0
  55. package/dist/lib/mcp/content-tools.provider.d.ts.map +1 -1
  56. package/dist/lib/mcp/content-tools.provider.js +10 -9
  57. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts +14 -13
  58. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts.map +1 -1
  59. package/dist/lib/public-api/http/controllers/public-entry-writes.controller.js +62 -46
  60. package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts.map +1 -1
  61. package/dist/lib/public-api/http/guards/api-token-workspace.guard.js +8 -0
  62. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts +10 -9
  63. package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts.map +1 -1
  64. package/dist/lib/public-api/infrastructure/public-entry-writes.service.js +23 -24
  65. package/dist/lib/public-api/infrastructure/token-actor.d.ts +37 -0
  66. package/dist/lib/public-api/infrastructure/token-actor.d.ts.map +1 -0
  67. package/dist/lib/public-api/infrastructure/token-actor.js +58 -0
  68. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts.map +1 -1
  69. package/dist/lib/revisions/application/use-cases/restore-revision.use-case.js +12 -1
  70. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts +28 -0
  71. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts.map +1 -0
  72. package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.js +52 -0
  73. package/dist/lib/utils/content-plugin.d.ts.map +1 -1
  74. package/dist/lib/utils/content-plugin.js +10 -1
  75. package/dist/lib/utils/content-views-plugin.d.ts.map +1 -1
  76. package/dist/lib/utils/content-views-plugin.js +8 -0
  77. package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts +4 -1
  78. package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts.map +1 -1
  79. package/dist/lib/views/application/use-cases/create-saved-view.use-case.js +33 -9
  80. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts +4 -1
  81. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts.map +1 -1
  82. package/dist/lib/views/application/use-cases/delete-saved-view.use-case.js +24 -3
  83. package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts +4 -1
  84. package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts.map +1 -1
  85. package/dist/lib/views/application/use-cases/update-saved-view.use-case.js +32 -3
  86. package/dist/lib/views/domain/events/saved-view-events.d.ts +28 -0
  87. package/dist/lib/views/domain/events/saved-view-events.d.ts.map +1 -0
  88. package/dist/lib/views/domain/events/saved-view-events.js +38 -0
  89. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts +12 -3
  90. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts.map +1 -1
  91. package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.js +15 -5
  92. package/package.json +11 -11
  93. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts +0 -26
  94. package/dist/lib/entries/controllers/bulk-entries.controller.d.ts.map +0 -1
  95. package/dist/lib/entries/controllers/create-entry.controller.d.ts +0 -20
  96. package/dist/lib/entries/controllers/create-entry.controller.d.ts.map +0 -1
  97. package/dist/lib/entries/controllers/delete-entry.controller.d.ts +0 -24
  98. package/dist/lib/entries/controllers/delete-entry.controller.d.ts.map +0 -1
  99. package/dist/lib/entries/controllers/get-entry.controller.d.ts +0 -34
  100. package/dist/lib/entries/controllers/get-entry.controller.d.ts.map +0 -1
  101. package/dist/lib/entries/controllers/list-entries.controller.d.ts +0 -20
  102. package/dist/lib/entries/controllers/list-entries.controller.d.ts.map +0 -1
  103. package/dist/lib/entries/controllers/publish-entry.controller.d.ts +0 -19
  104. package/dist/lib/entries/controllers/publish-entry.controller.d.ts.map +0 -1
  105. package/dist/lib/entries/controllers/resolve-type.d.ts +0 -9
  106. package/dist/lib/entries/controllers/resolve-type.d.ts.map +0 -1
  107. package/dist/lib/entries/controllers/update-entry.controller.d.ts +0 -18
  108. package/dist/lib/entries/controllers/update-entry.controller.d.ts.map +0 -1
  109. package/dist/lib/entries/dto/bulk-ids.dto.d.ts +0 -11
  110. package/dist/lib/entries/dto/bulk-ids.dto.d.ts.map +0 -1
  111. package/dist/lib/entries/dto/list-entries-query.dto.d.ts +0 -46
  112. package/dist/lib/entries/dto/list-entries-query.dto.d.ts.map +0 -1
  113. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts +0 -19
  114. package/dist/lib/entries/dto/relation-delta-map.validator.d.ts.map +0 -1
  115. package/dist/lib/entries/dto/save-entry.dto.d.ts +0 -46
  116. package/dist/lib/entries/dto/save-entry.dto.d.ts.map +0 -1
  117. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts +0 -24
  118. package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts.map +0 -1
  119. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts +0 -40
  120. package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts.map +0 -1
  121. package/dist/lib/entries/services/entries.service.d.ts +0 -59
  122. package/dist/lib/entries/services/entries.service.d.ts.map +0 -1
  123. package/dist/lib/entries/services/entry-counter.service.d.ts +0 -31
  124. package/dist/lib/entries/services/entry-counter.service.d.ts.map +0 -1
  125. package/dist/lib/entries/services/entry-filter-schema.d.ts +0 -32
  126. package/dist/lib/entries/services/entry-filter-schema.d.ts.map +0 -1
  127. package/dist/lib/entries/services/entry-row.d.ts +0 -56
  128. package/dist/lib/entries/services/entry-row.d.ts.map +0 -1
  129. package/dist/lib/entries/services/entry-writer.service.d.ts +0 -193
  130. package/dist/lib/entries/services/entry-writer.service.d.ts.map +0 -1
  131. package/dist/lib/entries/services/relation-link.service.d.ts +0 -115
  132. package/dist/lib/entries/services/relation-link.service.d.ts.map +0 -1
  133. package/dist/lib/extension/entry-access-source.d.ts +0 -112
  134. package/dist/lib/extension/entry-access-source.d.ts.map +0 -1
  135. package/dist/lib/extension/entry-write-hook.d.ts +0 -98
  136. package/dist/lib/extension/entry-write-hook.d.ts.map +0 -1
  137. package/dist/lib/extension/per-locale-relation.d.ts +0 -18
  138. package/dist/lib/extension/per-locale-relation.d.ts.map +0 -1
  139. package/dist/lib/public/controllers/get-public-entry.controller.d.ts +0 -26
  140. package/dist/lib/public/controllers/get-public-entry.controller.d.ts.map +0 -1
  141. package/dist/lib/public/controllers/list-public-entries.controller.d.ts +0 -24
  142. package/dist/lib/public/controllers/list-public-entries.controller.d.ts.map +0 -1
  143. package/dist/lib/public/controllers/public-schema.controller.d.ts +0 -18
  144. package/dist/lib/public/controllers/public-schema.controller.d.ts.map +0 -1
@@ -9,6 +9,8 @@ const workspaces_server_1 = require("@orthacms/workspaces-server");
9
9
  const content_tokens_1 = require("../../../content.tokens");
10
10
  const workspace_grants_query_1 = require("../../../content-types/queries/workspace-grants.query");
11
11
  const public_entry_writes_service_1 = require("../../infrastructure/public-entry-writes.service");
12
+ const token_actor_1 = require("../../infrastructure/token-actor");
13
+ const current_api_token_decorator_1 = require("../decorators/current-api-token.decorator");
12
14
  const api_token_guard_1 = require("../guards/api-token.guard");
13
15
  const api_token_workspace_guard_1 = require("../guards/api-token-workspace.guard");
14
16
  const public_save_entry_dto_1 = require("../dto/public-save-entry.dto");
@@ -54,9 +56,9 @@ let PublicEntryWritesController = class PublicEntryWritesController {
54
56
  this.writes = writes;
55
57
  }
56
58
  /** `POST /api/v1/content/:typeName` — create a draft entry. */
57
- async create(typeName, body, workspaceId) {
59
+ async create(typeName, body, workspaceId, token) {
58
60
  const { type, granted } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
59
- return this.writes.create(type, body, workspaceId, granted);
61
+ return this.writes.create(type, body, workspaceId, granted, (0, token_actor_1.toTokenActor)(token));
60
62
  }
61
63
  // ---- batches -----------------------------------------------------------
62
64
  //
@@ -66,24 +68,24 @@ let PublicEntryWritesController = class PublicEntryWritesController {
66
68
  // that turns a mis-ordered match into a 400, not a substitute for the order.
67
69
  // Same arrangement, same reason, as the admin's `BulkEntriesController`.
68
70
  /** `POST /api/v1/content/:typeName/bulk` — create and/or update many entries. */
69
- async bulkSave(typeName, body, workspaceId) {
71
+ async bulkSave(typeName, body, workspaceId, token) {
70
72
  const { type, granted } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
71
- return this.writes.bulkSave(type, body.items, workspaceId, granted);
73
+ return this.writes.bulkSave(type, body.items, workspaceId, granted, (0, token_actor_1.toTokenActor)(token));
72
74
  }
73
75
  /** `POST /api/v1/content/:typeName/bulk/publish` — take many entries live. */
74
- async bulkPublish(typeName, body, workspaceId) {
76
+ async bulkPublish(typeName, body, workspaceId, token) {
75
77
  const { type } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
76
- return this.writes.bulkPublish(type, body.ids, workspaceId);
78
+ return this.writes.bulkPublish(type, body.ids, workspaceId, (0, token_actor_1.toTokenActor)(token));
77
79
  }
78
80
  /** `POST /api/v1/content/:typeName/bulk/unpublish` — take many off the air. */
79
- async bulkUnpublish(typeName, body, workspaceId) {
81
+ async bulkUnpublish(typeName, body, workspaceId, token) {
80
82
  const { type } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
81
- return this.writes.bulkUnpublish(type, body.ids, workspaceId);
83
+ return this.writes.bulkUnpublish(type, body.ids, workspaceId, (0, token_actor_1.toTokenActor)(token));
82
84
  }
83
85
  /** `POST /api/v1/content/:typeName/bulk/delete` — remove many entries. */
84
- async bulkRemove(typeName, body, workspaceId) {
86
+ async bulkRemove(typeName, body, workspaceId, token) {
85
87
  const { type } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
86
- return this.writes.bulkRemove(type, body.ids, workspaceId);
88
+ return this.writes.bulkRemove(type, body.ids, workspaceId, (0, token_actor_1.toTokenActor)(token));
87
89
  }
88
90
  // ---- addressed by translation group -----------------------------------
89
91
  //
@@ -91,60 +93,61 @@ let PublicEntryWritesController = class PublicEntryWritesController {
91
93
  // cannot collide on segment count, but Express matches in declaration order
92
94
  // and literal-prefixed routes belong ahead of wildcards.
93
95
  /** `PATCH /api/v1/content/:typeName/group/:localeGroupId` */
94
- updateByGroup(typeName, localeGroupId, body, query, workspaceId) {
95
- return this.applyUpdate(typeName, { localeGroupId }, body, workspaceId, query.locale);
96
+ updateByGroup(typeName, localeGroupId, body, query, workspaceId, token) {
97
+ return this.applyUpdate(typeName, { localeGroupId }, body, workspaceId, query.locale, token);
96
98
  }
97
99
  /** `POST /api/v1/content/:typeName/group/:localeGroupId/publish` */
98
- publishByGroup(typeName, localeGroupId, query, workspaceId) {
99
- return this.applyPublish(typeName, { localeGroupId }, workspaceId, query.locale, true);
100
+ publishByGroup(typeName, localeGroupId, query, workspaceId, token) {
101
+ return this.applyPublish(typeName, { localeGroupId }, workspaceId, query.locale, true, token);
100
102
  }
101
103
  /** `POST /api/v1/content/:typeName/group/:localeGroupId/unpublish` */
102
- unpublishByGroup(typeName, localeGroupId, query, workspaceId) {
103
- return this.applyPublish(typeName, { localeGroupId }, workspaceId, query.locale, false);
104
+ unpublishByGroup(typeName, localeGroupId, query, workspaceId, token) {
105
+ return this.applyPublish(typeName, { localeGroupId }, workspaceId, query.locale, false, token);
104
106
  }
105
107
  /** `DELETE /api/v1/content/:typeName/group/:localeGroupId` */
106
- removeByGroup(typeName, localeGroupId, query, workspaceId) {
107
- return this.applyRemove(typeName, { localeGroupId }, workspaceId, query.locale);
108
+ removeByGroup(typeName, localeGroupId, query, workspaceId, token) {
109
+ return this.applyRemove(typeName, { localeGroupId }, workspaceId, query.locale, token);
108
110
  }
109
111
  // ---- addressed by entry id ---------------------------------------------
110
112
  /** `PATCH /api/v1/content/:typeName/:id` — replace an entry's values. */
111
- update(typeName, id, body, workspaceId) {
113
+ update(typeName, id, body, workspaceId, token) {
112
114
  // No locale: an entry id already names exactly one row, in whatever
113
115
  // locale it happens to be.
114
- return this.applyUpdate(typeName, { id }, body, workspaceId, undefined);
116
+ return this.applyUpdate(typeName, { id }, body, workspaceId, undefined, token);
115
117
  }
116
118
  /** `POST /api/v1/content/:typeName/:id/publish` — take an entry live. */
117
- publish(typeName, id, workspaceId) {
118
- return this.applyPublish(typeName, { id }, workspaceId, undefined, true);
119
+ publish(typeName, id, workspaceId, token) {
120
+ return this.applyPublish(typeName, { id }, workspaceId, undefined, true, token);
119
121
  }
120
122
  /** `POST /api/v1/content/:typeName/:id/unpublish` — take it off the air. */
121
- unpublish(typeName, id, workspaceId) {
122
- return this.applyPublish(typeName, { id }, workspaceId, undefined, false);
123
+ unpublish(typeName, id, workspaceId, token) {
124
+ return this.applyPublish(typeName, { id }, workspaceId, undefined, false, token);
123
125
  }
124
126
  /** `DELETE /api/v1/content/:typeName/:id` — remove an entry. */
125
- remove(typeName, id, workspaceId) {
126
- return this.applyRemove(typeName, { id }, workspaceId, undefined);
127
+ remove(typeName, id, workspaceId, token) {
128
+ return this.applyRemove(typeName, { id }, workspaceId, undefined, token);
127
129
  }
128
130
  // ---- the shared handlers, one per write --------------------------------
129
131
  //
130
132
  // Each is called by both addressing forms, so the pair stays a routing
131
133
  // detail and never a behavioural fork — the same arrangement as the reads.
132
134
  /** @see update */
133
- async applyUpdate(typeName, locator, body, workspaceId, locale) {
135
+ async applyUpdate(typeName, locator, body, workspaceId, locale, token) {
134
136
  const { type, granted } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
135
- return this.writes.update(type, locator, body, workspaceId, granted, locale);
137
+ return this.writes.update(type, locator, body, workspaceId, granted, locale, (0, token_actor_1.toTokenActor)(token));
136
138
  }
137
139
  /** @see publish */
138
- async applyPublish(typeName, locator, workspaceId, locale, live) {
140
+ async applyPublish(typeName, locator, workspaceId, locale, live, token) {
139
141
  const { type, granted } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
142
+ const actor = (0, token_actor_1.toTokenActor)(token);
140
143
  return live
141
- ? this.writes.publish(type, locator, workspaceId, granted, locale)
142
- : this.writes.unpublish(type, locator, workspaceId, granted, locale);
144
+ ? this.writes.publish(type, locator, workspaceId, granted, locale, actor)
145
+ : this.writes.unpublish(type, locator, workspaceId, granted, locale, actor);
143
146
  }
144
147
  /** @see remove */
145
- async applyRemove(typeName, locator, workspaceId, locale) {
148
+ async applyRemove(typeName, locator, workspaceId, locale, token) {
146
149
  const { type } = await (0, resolve_granted_type_1.resolveGrantedType)(this.registry, this.grants, typeName, workspaceId);
147
- await this.writes.remove(type, locator, workspaceId, locale);
150
+ await this.writes.remove(type, locator, workspaceId, locale, (0, token_actor_1.toTokenActor)(token));
148
151
  }
149
152
  };
150
153
  exports.PublicEntryWritesController = PublicEntryWritesController;
@@ -158,8 +161,9 @@ tslib_1.__decorate([
158
161
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
159
162
  tslib_1.__param(1, (0, common_1.Body)()),
160
163
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
164
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
161
165
  tslib_1.__metadata("design:type", Function),
162
- tslib_1.__metadata("design:paramtypes", [String, public_save_entry_dto_1.PublicSaveEntryDto, String]),
166
+ tslib_1.__metadata("design:paramtypes", [String, public_save_entry_dto_1.PublicSaveEntryDto, String, Object]),
163
167
  tslib_1.__metadata("design:returntype", Promise)
164
168
  ], PublicEntryWritesController.prototype, "create", null);
165
169
  tslib_1.__decorate([
@@ -173,8 +177,9 @@ tslib_1.__decorate([
173
177
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
174
178
  tslib_1.__param(1, (0, common_1.Body)()),
175
179
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
180
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
176
181
  tslib_1.__metadata("design:type", Function),
177
- tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkSaveDto, String]),
182
+ tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkSaveDto, String, Object]),
178
183
  tslib_1.__metadata("design:returntype", Promise)
179
184
  ], PublicEntryWritesController.prototype, "bulkSave", null);
180
185
  tslib_1.__decorate([
@@ -188,8 +193,9 @@ tslib_1.__decorate([
188
193
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
189
194
  tslib_1.__param(1, (0, common_1.Body)()),
190
195
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
196
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
191
197
  tslib_1.__metadata("design:type", Function),
192
- tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String]),
198
+ tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String, Object]),
193
199
  tslib_1.__metadata("design:returntype", Promise)
194
200
  ], PublicEntryWritesController.prototype, "bulkPublish", null);
195
201
  tslib_1.__decorate([
@@ -203,8 +209,9 @@ tslib_1.__decorate([
203
209
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
204
210
  tslib_1.__param(1, (0, common_1.Body)()),
205
211
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
212
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
206
213
  tslib_1.__metadata("design:type", Function),
207
- tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String]),
214
+ tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String, Object]),
208
215
  tslib_1.__metadata("design:returntype", Promise)
209
216
  ], PublicEntryWritesController.prototype, "bulkUnpublish", null);
210
217
  tslib_1.__decorate([
@@ -218,8 +225,9 @@ tslib_1.__decorate([
218
225
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
219
226
  tslib_1.__param(1, (0, common_1.Body)()),
220
227
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
228
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
221
229
  tslib_1.__metadata("design:type", Function),
222
- tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String]),
230
+ tslib_1.__metadata("design:paramtypes", [String, public_bulk_dto_1.PublicBulkIdsDto, String, Object]),
223
231
  tslib_1.__metadata("design:returntype", Promise)
224
232
  ], PublicEntryWritesController.prototype, "bulkRemove", null);
225
233
  tslib_1.__decorate([
@@ -234,9 +242,10 @@ tslib_1.__decorate([
234
242
  tslib_1.__param(2, (0, common_1.Body)()),
235
243
  tslib_1.__param(3, (0, common_1.Query)()),
236
244
  tslib_1.__param(4, (0, workspaces_server_1.CurrentWorkspace)()),
245
+ tslib_1.__param(5, (0, current_api_token_decorator_1.CurrentApiToken)()),
237
246
  tslib_1.__metadata("design:type", Function),
238
247
  tslib_1.__metadata("design:paramtypes", [String, String, public_save_entry_dto_1.PublicSaveEntryDto,
239
- public_list_entries_query_dto_1.PublicEntryQueryDto, String]),
248
+ public_list_entries_query_dto_1.PublicEntryQueryDto, String, Object]),
240
249
  tslib_1.__metadata("design:returntype", Promise)
241
250
  ], PublicEntryWritesController.prototype, "updateByGroup", null);
242
251
  tslib_1.__decorate([
@@ -247,8 +256,9 @@ tslib_1.__decorate([
247
256
  tslib_1.__param(1, (0, common_1.Param)('localeGroupId', common_1.ParseUUIDPipe)),
248
257
  tslib_1.__param(2, (0, common_1.Query)()),
249
258
  tslib_1.__param(3, (0, workspaces_server_1.CurrentWorkspace)()),
259
+ tslib_1.__param(4, (0, current_api_token_decorator_1.CurrentApiToken)()),
250
260
  tslib_1.__metadata("design:type", Function),
251
- tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String]),
261
+ tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String, Object]),
252
262
  tslib_1.__metadata("design:returntype", Promise)
253
263
  ], PublicEntryWritesController.prototype, "publishByGroup", null);
254
264
  tslib_1.__decorate([
@@ -259,8 +269,9 @@ tslib_1.__decorate([
259
269
  tslib_1.__param(1, (0, common_1.Param)('localeGroupId', common_1.ParseUUIDPipe)),
260
270
  tslib_1.__param(2, (0, common_1.Query)()),
261
271
  tslib_1.__param(3, (0, workspaces_server_1.CurrentWorkspace)()),
272
+ tslib_1.__param(4, (0, current_api_token_decorator_1.CurrentApiToken)()),
262
273
  tslib_1.__metadata("design:type", Function),
263
- tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String]),
274
+ tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String, Object]),
264
275
  tslib_1.__metadata("design:returntype", Promise)
265
276
  ], PublicEntryWritesController.prototype, "unpublishByGroup", null);
266
277
  tslib_1.__decorate([
@@ -275,8 +286,9 @@ tslib_1.__decorate([
275
286
  tslib_1.__param(1, (0, common_1.Param)('localeGroupId', common_1.ParseUUIDPipe)),
276
287
  tslib_1.__param(2, (0, common_1.Query)()),
277
288
  tslib_1.__param(3, (0, workspaces_server_1.CurrentWorkspace)()),
289
+ tslib_1.__param(4, (0, current_api_token_decorator_1.CurrentApiToken)()),
278
290
  tslib_1.__metadata("design:type", Function),
279
- tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String]),
291
+ tslib_1.__metadata("design:paramtypes", [String, String, public_list_entries_query_dto_1.PublicEntryQueryDto, String, Object]),
280
292
  tslib_1.__metadata("design:returntype", Promise)
281
293
  ], PublicEntryWritesController.prototype, "removeByGroup", null);
282
294
  tslib_1.__decorate([
@@ -290,8 +302,9 @@ tslib_1.__decorate([
290
302
  tslib_1.__param(1, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
291
303
  tslib_1.__param(2, (0, common_1.Body)()),
292
304
  tslib_1.__param(3, (0, workspaces_server_1.CurrentWorkspace)()),
305
+ tslib_1.__param(4, (0, current_api_token_decorator_1.CurrentApiToken)()),
293
306
  tslib_1.__metadata("design:type", Function),
294
- tslib_1.__metadata("design:paramtypes", [String, String, public_save_entry_dto_1.PublicSaveEntryDto, String]),
307
+ tslib_1.__metadata("design:paramtypes", [String, String, public_save_entry_dto_1.PublicSaveEntryDto, String, Object]),
295
308
  tslib_1.__metadata("design:returntype", Promise)
296
309
  ], PublicEntryWritesController.prototype, "update", null);
297
310
  tslib_1.__decorate([
@@ -304,8 +317,9 @@ tslib_1.__decorate([
304
317
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
305
318
  tslib_1.__param(1, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
306
319
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
320
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
307
321
  tslib_1.__metadata("design:type", Function),
308
- tslib_1.__metadata("design:paramtypes", [String, String, String]),
322
+ tslib_1.__metadata("design:paramtypes", [String, String, String, Object]),
309
323
  tslib_1.__metadata("design:returntype", Promise)
310
324
  ], PublicEntryWritesController.prototype, "publish", null);
311
325
  tslib_1.__decorate([
@@ -318,8 +332,9 @@ tslib_1.__decorate([
318
332
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
319
333
  tslib_1.__param(1, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
320
334
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
335
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
321
336
  tslib_1.__metadata("design:type", Function),
322
- tslib_1.__metadata("design:paramtypes", [String, String, String]),
337
+ tslib_1.__metadata("design:paramtypes", [String, String, String, Object]),
323
338
  tslib_1.__metadata("design:returntype", Promise)
324
339
  ], PublicEntryWritesController.prototype, "unpublish", null);
325
340
  tslib_1.__decorate([
@@ -333,8 +348,9 @@ tslib_1.__decorate([
333
348
  tslib_1.__param(0, (0, common_1.Param)('typeName')),
334
349
  tslib_1.__param(1, (0, common_1.Param)('id', common_1.ParseUUIDPipe)),
335
350
  tslib_1.__param(2, (0, workspaces_server_1.CurrentWorkspace)()),
351
+ tslib_1.__param(3, (0, current_api_token_decorator_1.CurrentApiToken)()),
336
352
  tslib_1.__metadata("design:type", Function),
337
- tslib_1.__metadata("design:paramtypes", [String, String, String]),
353
+ tslib_1.__metadata("design:paramtypes", [String, String, String, Object]),
338
354
  tslib_1.__metadata("design:returntype", Promise)
339
355
  ], PublicEntryWritesController.prototype, "remove", null);
340
356
  exports.PublicEntryWritesController = PublicEntryWritesController = tslib_1.__decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"api-token-workspace.guard.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/guards/api-token-workspace.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,WAAW,EACX,gBAAgB,EAInB,MAAM,gBAAgB,CAAC;AAOxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,sBAAuB,YAAW,WAAW;IACtD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CAmClD"}
1
+ {"version":3,"file":"api-token-workspace.guard.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/guards/api-token-workspace.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,WAAW,EACX,gBAAgB,EAInB,MAAM,gBAAgB,CAAC;AAOxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,sBAAuB,YAAW,WAAW;IACtD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CA6ClD"}
@@ -38,6 +38,14 @@ let ApiTokenWorkspaceGuard = class ApiTokenWorkspaceGuard {
38
38
  request.workspaceId = token.workspaceIds[0];
39
39
  return true;
40
40
  }
41
+ // A token can end up covering *nothing*: deleting a workspace
42
+ // narrows every token's bucket and deliberately stops short of
43
+ // revoking the credential, which is not the purger's call to make.
44
+ // Asking that caller to name one of zero workspaces is advice they
45
+ // cannot follow, so say what is actually true instead.
46
+ if (token.workspaceIds.length === 0) {
47
+ throw new common_1.ForbiddenException('This token has no workspaces left — every workspace it covered has been deleted. Issue a new token.');
48
+ }
41
49
  throw new common_1.BadRequestException(`This token covers ${token.workspaceIds.length} workspaces — name the one you want with the X-Workspace-Id header.`);
42
50
  }
43
51
  if (!workspaces_server_1.WORKSPACE_ID_PATTERN.test(requested)) {
@@ -1,3 +1,4 @@
1
+ import type { EventActor } from '@orthacms/database';
1
2
  import type { AnyContentType } from '../../types/content-type';
2
3
  import { EntryWriterService } from '../../entries/infrastructure/persistence/entry-writer.service';
3
4
  import { PublishEntryUseCase } from '../../entries/application/use-cases/publish-entry.use-case';
@@ -56,7 +57,7 @@ export declare class PublicEntryWritesService {
56
57
  * of starting one, which is how a new locale of an existing record is
57
58
  * written.
58
59
  */
59
- create(type: AnyContentType, body: PublicSaveEntryDto, workspaceId: string, grantedTypes: ReadonlySet<string>): Promise<PublicEntry>;
60
+ create(type: AnyContentType, body: PublicSaveEntryDto, workspaceId: string, grantedTypes: ReadonlySet<string>, actor?: EventActor): Promise<PublicEntry>;
60
61
  /**
61
62
  * Update an entry's values and apply its relation deltas. On a publishable
62
63
  * type this moves a published row back to `draft` while its published
@@ -82,7 +83,7 @@ export declare class PublicEntryWritesService {
82
83
  * group write at the default-locale row. Which is exactly what it did, until
83
84
  * a live check caught a German update rewriting the English article.
84
85
  */
85
- update(type: AnyContentType, locator: EntryLocator, body: PublicSaveEntryDto, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string): Promise<PublicEntry>;
86
+ update(type: AnyContentType, locator: EntryLocator, body: PublicSaveEntryDto, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string, actor?: EventActor): Promise<PublicEntry>;
86
87
  /**
87
88
  * Save many entries of one type in a single request — the batch form of
88
89
  * {@link create} and {@link update}, and the reason it is one method rather
@@ -112,7 +113,7 @@ export declare class PublicEntryWritesService {
112
113
  * would spend a fan-out contending with itself; sequential also makes the
113
114
  * per-item results deterministic, which a caller diffing two runs relies on.
114
115
  */
115
- bulkSave(type: AnyContentType, items: readonly PublicBulkSaveItemDto[], workspaceId: string, grantedTypes: ReadonlySet<string>): Promise<PublicBulkSaveResult>;
116
+ bulkSave(type: AnyContentType, items: readonly PublicBulkSaveItemDto[], workspaceId: string, grantedTypes: ReadonlySet<string>, actor?: EventActor): Promise<PublicBulkSaveResult>;
116
117
  /**
117
118
  * The values bag an update submits: the stored values with the caller's
118
119
  * merged over them (see {@link update}), minus any single relation the
@@ -141,7 +142,7 @@ export declare class PublicEntryWritesService {
141
142
  * workspace-scoped, so an id from another workspace is reported as
142
143
  * `not-found` — the same answer an id that never existed gets.
143
144
  */
144
- bulkPublish(type: AnyContentType, ids: string[], workspaceId: string): Promise<BulkPublishResult>;
145
+ bulkPublish(type: AnyContentType, ids: string[], workspaceId: string, actor?: EventActor): Promise<BulkPublishResult>;
145
146
  /**
146
147
  * Take many entries off the air, reverting each to a draft.
147
148
  *
@@ -151,7 +152,7 @@ export declare class PublicEntryWritesService {
151
152
  * actually transitioned, and one `entry.unpublished` event is emitted per
152
153
  * transition — never per submitted id.
153
154
  */
154
- bulkUnpublish(type: AnyContentType, ids: string[], workspaceId: string): Promise<BulkActionResult>;
155
+ bulkUnpublish(type: AnyContentType, ids: string[], workspaceId: string, actor?: EventActor): Promise<BulkActionResult>;
155
156
  /**
156
157
  * Remove many entries — soft-deleting on a `paranoid` type (recoverable
157
158
  * from the admin's trash) and hard-deleting otherwise, exactly as
@@ -160,11 +161,11 @@ export declare class PublicEntryWritesService {
160
161
  * Rows, not records: on a localized type this deletes the listed locales
161
162
  * and leaves their siblings live.
162
163
  */
163
- bulkRemove(type: AnyContentType, ids: string[], workspaceId: string): Promise<BulkActionResult>;
164
+ bulkRemove(type: AnyContentType, ids: string[], workspaceId: string, actor?: EventActor): Promise<BulkActionResult>;
164
165
  /** Take an entry live. 422 when the stored draft no longer validates. */
165
- publish(type: AnyContentType, locator: EntryLocator, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string): Promise<PublicEntry>;
166
+ publish(type: AnyContentType, locator: EntryLocator, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string, actor?: EventActor): Promise<PublicEntry>;
166
167
  /** Take an entry back off the air, reverting it to a draft. */
167
- unpublish(type: AnyContentType, locator: EntryLocator, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string): Promise<PublicEntry>;
168
+ unpublish(type: AnyContentType, locator: EntryLocator, workspaceId: string, grantedTypes: ReadonlySet<string>, locale?: string, actor?: EventActor): Promise<PublicEntry>;
168
169
  /**
169
170
  * Remove an entry — soft delete on a `paranoid` type (recoverable from the
170
171
  * admin's trash), a hard delete otherwise. Either way it leaves the public
@@ -174,7 +175,7 @@ export declare class PublicEntryWritesService {
174
175
  * German article leaves the English one live. Deleting a whole group means
175
176
  * deleting each locale.
176
177
  */
177
- remove(type: AnyContentType, locator: EntryLocator, workspaceId: string, locale?: string): Promise<void>;
178
+ remove(type: AnyContentType, locator: EntryLocator, workspaceId: string, locale?: string, actor?: EventActor): Promise<void>;
178
179
  /**
179
180
  * Re-read a just-written row through the public projection.
180
181
  *
@@ -1 +1 @@
1
- {"version":3,"file":"public-entry-writes.service.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-entry-writes.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+DAA+D,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,4DAA4D,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,8DAA8D,CAAC;AACrG,OAAO,EAAE,yBAAyB,EAAE,MAAM,mEAAmE,CAAC;AAC9G,OAAO,EAAE,2BAA2B,EAAE,MAAM,qEAAqE,CAAC;AAClH,OAAO,KAAK,EACR,gBAAgB,EAChB,iBAAiB,EACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAKH,KAAK,oBAAoB,EAC5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,wBAAwB;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBALpB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,mBAAmB,EACjC,cAAc,EAAE,qBAAqB,EACrC,kBAAkB,EAAE,yBAAyB,EAC7C,oBAAoB,EAAE,2BAA2B;IAGtE;;;;;;;;OAQG;IACG,MAAM,CACR,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,kBAAkB,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAClC,OAAO,CAAC,WAAW,CAAC;IAkBvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,MAAM,CACR,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,kBAAkB,EACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;IAwBvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,QAAQ,CACV,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,SAAS,qBAAqB,EAAE,EACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAoDhC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,YAAY;IAqBpB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CACP,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,EAAE,EACb,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;;;;;;OAQG;IACH,aAAa,CACT,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,EAAE,EACb,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;;;;;OAOG;IACH,UAAU,CACN,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,EAAE,EACb,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,CAAC;IAI5B,yEAAyE;IACnE,OAAO,CACT,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;IAYvB,+DAA+D;IACzD,SAAS,CACX,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,EACjC,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;IAYvB;;;;;;;;OAQG;IACG,MAAM,CACR,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAUhB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;CAenB"}
1
+ {"version":3,"file":"public-entry-writes.service.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-entry-writes.service.ts"],"names":[],"mappings":"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"}
@@ -65,14 +65,13 @@ let PublicEntryWritesService = class PublicEntryWritesService {
65
65
  * of starting one, which is how a new locale of an existing record is
66
66
  * written.
67
67
  */
68
- async create(type, body, workspaceId, grantedTypes) {
68
+ async create(type, body, workspaceId, grantedTypes, actor) {
69
69
  const record = await this.writer.create(type, body.values, workspaceId, body.relations, body.locale, body.localeGroupId,
70
- // Revisions record a *user* id, and a token is not a user. Writing
71
- // the token id into that column would make the history resolve it to
72
- // a nonexistent person; null is the honest answer for "not a user".
73
- // Attributing a token's writes is a real gap it wants its own
74
- // column, not a misused one.
75
- null);
70
+ // The **token** is the actor. Its id never reaches the revision's
71
+ // `created_by` that column really is a `users` FK, and the writer's
72
+ // `revisionActorId` is what keeps the two apart but it does reach
73
+ // the audit row, which carries an `actor_type` saying what it names.
74
+ actor ?? null);
76
75
  return this.readBack(type, record.id, workspaceId, grantedTypes, body);
77
76
  }
78
77
  /**
@@ -100,7 +99,7 @@ let PublicEntryWritesService = class PublicEntryWritesService {
100
99
  * group write at the default-locale row. Which is exactly what it did, until
101
100
  * a live check caught a German update rewriting the English article.
102
101
  */
103
- async update(type, locator, body, workspaceId, grantedTypes, locale) {
102
+ async update(type, locator, body, workspaceId, grantedTypes, locale, actor) {
104
103
  const row = await this.entries.resolveWritableRow(type, locator, workspaceId, locale);
105
104
  const id = row['id'];
106
105
  await this.writer.update(type, id,
@@ -109,7 +108,7 @@ let PublicEntryWritesService = class PublicEntryWritesService {
109
108
  // column and are absent from it, which is correct: those move only
110
109
  // through `relations` deltas, and a delta left unsent changes
111
110
  // nothing by construction.
112
- this.mergedValues(type, row, body), workspaceId, body.relations, null);
111
+ this.mergedValues(type, row, body), workspaceId, body.relations, actor ?? null);
113
112
  return this.readBack(type, id, workspaceId, grantedTypes, { locale });
114
113
  }
115
114
  /**
@@ -141,7 +140,7 @@ let PublicEntryWritesService = class PublicEntryWritesService {
141
140
  * would spend a fan-out contending with itself; sequential also makes the
142
141
  * per-item results deterministic, which a caller diffing two runs relies on.
143
142
  */
144
- async bulkSave(type, items, workspaceId, grantedTypes) {
143
+ async bulkSave(type, items, workspaceId, grantedTypes, actor) {
145
144
  const results = [];
146
145
  for (const [index, item] of items.entries()) {
147
146
  // Resolved inside the loop, and inside the try: a malformed
@@ -154,8 +153,8 @@ let PublicEntryWritesService = class PublicEntryWritesService {
154
153
  const resolved = (0, bulk_save_op_1.resolveBulkSaveOp)(item);
155
154
  op = resolved.op;
156
155
  const entry = resolved.op === public_bulk_1.BULK_SAVE_OP.Create
157
- ? await this.create(type, item, workspaceId, grantedTypes)
158
- : await this.update(type, resolved.locator, item, workspaceId, grantedTypes, resolved.locale);
156
+ ? await this.create(type, item, workspaceId, grantedTypes, actor)
157
+ : await this.update(type, resolved.locator, item, workspaceId, grantedTypes, resolved.locale, actor);
159
158
  results.push({ index, op: resolved.op, ok: true, entry });
160
159
  }
161
160
  catch (error) {
@@ -215,8 +214,8 @@ let PublicEntryWritesService = class PublicEntryWritesService {
215
214
  * workspace-scoped, so an id from another workspace is reported as
216
215
  * `not-found` — the same answer an id that never existed gets.
217
216
  */
218
- bulkPublish(type, ids, workspaceId) {
219
- return this.bulkPublishEntries.execute(type, ids, workspaceId);
217
+ bulkPublish(type, ids, workspaceId, actor) {
218
+ return this.bulkPublishEntries.execute(type, ids, workspaceId, actor);
220
219
  }
221
220
  /**
222
221
  * Take many entries off the air, reverting each to a draft.
@@ -227,8 +226,8 @@ let PublicEntryWritesService = class PublicEntryWritesService {
227
226
  * actually transitioned, and one `entry.unpublished` event is emitted per
228
227
  * transition — never per submitted id.
229
228
  */
230
- bulkUnpublish(type, ids, workspaceId) {
231
- return this.bulkUnpublishEntries.execute(type, ids, workspaceId);
229
+ bulkUnpublish(type, ids, workspaceId, actor) {
230
+ return this.bulkUnpublishEntries.execute(type, ids, workspaceId, actor);
232
231
  }
233
232
  /**
234
233
  * Remove many entries — soft-deleting on a `paranoid` type (recoverable
@@ -238,21 +237,21 @@ let PublicEntryWritesService = class PublicEntryWritesService {
238
237
  * Rows, not records: on a localized type this deletes the listed locales
239
238
  * and leaves their siblings live.
240
239
  */
241
- bulkRemove(type, ids, workspaceId) {
242
- return this.writer.bulkRemove(type, ids, workspaceId);
240
+ bulkRemove(type, ids, workspaceId, actor) {
241
+ return this.writer.bulkRemove(type, ids, workspaceId, actor);
243
242
  }
244
243
  /** Take an entry live. 422 when the stored draft no longer validates. */
245
- async publish(type, locator, workspaceId, grantedTypes, locale) {
244
+ async publish(type, locator, workspaceId, grantedTypes, locale, actor) {
246
245
  const row = await this.entries.resolveWritableRow(type, locator, workspaceId, locale);
247
246
  const id = row['id'];
248
- await this.publishEntry.execute(type, id, workspaceId);
247
+ await this.publishEntry.execute(type, id, workspaceId, actor);
249
248
  return this.readBack(type, id, workspaceId, grantedTypes, { locale });
250
249
  }
251
250
  /** Take an entry back off the air, reverting it to a draft. */
252
- async unpublish(type, locator, workspaceId, grantedTypes, locale) {
251
+ async unpublish(type, locator, workspaceId, grantedTypes, locale, actor) {
253
252
  const row = await this.entries.resolveWritableRow(type, locator, workspaceId, locale);
254
253
  const id = row['id'];
255
- await this.unpublishEntry.execute(type, id, workspaceId);
254
+ await this.unpublishEntry.execute(type, id, workspaceId, actor);
256
255
  return this.readBack(type, id, workspaceId, grantedTypes, { locale });
257
256
  }
258
257
  /**
@@ -264,9 +263,9 @@ let PublicEntryWritesService = class PublicEntryWritesService {
264
263
  * German article leaves the English one live. Deleting a whole group means
265
264
  * deleting each locale.
266
265
  */
267
- async remove(type, locator, workspaceId, locale) {
266
+ async remove(type, locator, workspaceId, locale, actor) {
268
267
  const row = await this.entries.resolveWritableRow(type, locator, workspaceId, locale);
269
- await this.writer.remove(type, row['id'], workspaceId);
268
+ await this.writer.remove(type, row['id'], workspaceId, actor);
270
269
  }
271
270
  /**
272
271
  * Re-read a just-written row through the public projection.
@@ -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;CA0C1B"}
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"}