@actuate-media/cms-core 0.20.0 → 0.22.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 (150) hide show
  1. package/LICENSE +21 -21
  2. package/dist/__tests__/actions/document-crud.test.js +74 -2
  3. package/dist/__tests__/actions/document-crud.test.js.map +1 -1
  4. package/dist/__tests__/api/cache-headers.test.d.ts +2 -0
  5. package/dist/__tests__/api/cache-headers.test.d.ts.map +1 -0
  6. package/dist/__tests__/api/cache-headers.test.js +135 -0
  7. package/dist/__tests__/api/cache-headers.test.js.map +1 -0
  8. package/dist/__tests__/api/comments-routes.test.d.ts +2 -0
  9. package/dist/__tests__/api/comments-routes.test.d.ts.map +1 -0
  10. package/dist/__tests__/api/comments-routes.test.js +266 -0
  11. package/dist/__tests__/api/comments-routes.test.js.map +1 -0
  12. package/dist/__tests__/api/notifications-routes.test.d.ts +2 -0
  13. package/dist/__tests__/api/notifications-routes.test.d.ts.map +1 -0
  14. package/dist/__tests__/api/notifications-routes.test.js +225 -0
  15. package/dist/__tests__/api/notifications-routes.test.js.map +1 -0
  16. package/dist/__tests__/api/preview-and-scheduling.test.js +53 -0
  17. package/dist/__tests__/api/preview-and-scheduling.test.js.map +1 -1
  18. package/dist/__tests__/fields/component-block.test.d.ts +2 -0
  19. package/dist/__tests__/fields/component-block.test.d.ts.map +1 -0
  20. package/dist/__tests__/fields/component-block.test.js +129 -0
  21. package/dist/__tests__/fields/component-block.test.js.map +1 -0
  22. package/dist/__tests__/fields/relations.test.js +62 -8
  23. package/dist/__tests__/fields/relations.test.js.map +1 -1
  24. package/dist/__tests__/preview-event-bus.test.d.ts +2 -0
  25. package/dist/__tests__/preview-event-bus.test.d.ts.map +1 -0
  26. package/dist/__tests__/preview-event-bus.test.js +89 -0
  27. package/dist/__tests__/preview-event-bus.test.js.map +1 -0
  28. package/dist/__tests__/preview-sse-stream.test.d.ts +2 -0
  29. package/dist/__tests__/preview-sse-stream.test.d.ts.map +1 -0
  30. package/dist/__tests__/preview-sse-stream.test.js +117 -0
  31. package/dist/__tests__/preview-sse-stream.test.js.map +1 -0
  32. package/dist/__tests__/realtime/comments.test.d.ts +2 -0
  33. package/dist/__tests__/realtime/comments.test.d.ts.map +1 -0
  34. package/dist/__tests__/realtime/comments.test.js +508 -0
  35. package/dist/__tests__/realtime/comments.test.js.map +1 -0
  36. package/dist/__tests__/realtime/gateway-ws-integration.test.d.ts +2 -0
  37. package/dist/__tests__/realtime/gateway-ws-integration.test.d.ts.map +1 -0
  38. package/dist/__tests__/realtime/gateway-ws-integration.test.js +170 -0
  39. package/dist/__tests__/realtime/gateway-ws-integration.test.js.map +1 -0
  40. package/dist/__tests__/realtime/gateway.test.d.ts +2 -0
  41. package/dist/__tests__/realtime/gateway.test.d.ts.map +1 -0
  42. package/dist/__tests__/realtime/gateway.test.js +402 -0
  43. package/dist/__tests__/realtime/gateway.test.js.map +1 -0
  44. package/dist/__tests__/realtime/notifications.test.d.ts +2 -0
  45. package/dist/__tests__/realtime/notifications.test.d.ts.map +1 -0
  46. package/dist/__tests__/realtime/notifications.test.js +317 -0
  47. package/dist/__tests__/realtime/notifications.test.js.map +1 -0
  48. package/dist/__tests__/realtime/persistence.test.d.ts +2 -0
  49. package/dist/__tests__/realtime/persistence.test.d.ts.map +1 -0
  50. package/dist/__tests__/realtime/persistence.test.js +124 -0
  51. package/dist/__tests__/realtime/persistence.test.js.map +1 -0
  52. package/dist/__tests__/schema-preview-features.test.d.ts +2 -0
  53. package/dist/__tests__/schema-preview-features.test.d.ts.map +1 -0
  54. package/dist/__tests__/schema-preview-features.test.js +42 -0
  55. package/dist/__tests__/schema-preview-features.test.js.map +1 -0
  56. package/dist/actions.d.ts.map +1 -1
  57. package/dist/actions.js +71 -26
  58. package/dist/actions.js.map +1 -1
  59. package/dist/api/handlers.d.ts.map +1 -1
  60. package/dist/api/handlers.js +734 -188
  61. package/dist/api/handlers.js.map +1 -1
  62. package/dist/cache/__tests__/http.test.d.ts +2 -0
  63. package/dist/cache/__tests__/http.test.d.ts.map +1 -0
  64. package/dist/cache/__tests__/http.test.js +285 -0
  65. package/dist/cache/__tests__/http.test.js.map +1 -0
  66. package/dist/cache/http.d.ts +119 -0
  67. package/dist/cache/http.d.ts.map +1 -0
  68. package/dist/cache/http.js +188 -0
  69. package/dist/cache/http.js.map +1 -0
  70. package/dist/config/types.d.ts +153 -1
  71. package/dist/config/types.d.ts.map +1 -1
  72. package/dist/fields/component-block.d.ts +23 -0
  73. package/dist/fields/component-block.d.ts.map +1 -0
  74. package/dist/fields/component-block.js +137 -0
  75. package/dist/fields/component-block.js.map +1 -0
  76. package/dist/fields/index.d.ts.map +1 -1
  77. package/dist/fields/index.js +2 -0
  78. package/dist/fields/index.js.map +1 -1
  79. package/dist/fields/relations.d.ts.map +1 -1
  80. package/dist/fields/relations.js +43 -11
  81. package/dist/fields/relations.js.map +1 -1
  82. package/dist/index.d.ts +5 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +2 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/page-builder/schema.d.ts +2 -2
  87. package/dist/preview/event-bus.d.ts +39 -0
  88. package/dist/preview/event-bus.d.ts.map +1 -0
  89. package/dist/preview/event-bus.js +73 -0
  90. package/dist/preview/event-bus.js.map +1 -0
  91. package/dist/preview/sse-stream.d.ts +50 -0
  92. package/dist/preview/sse-stream.d.ts.map +1 -0
  93. package/dist/preview/sse-stream.js +120 -0
  94. package/dist/preview/sse-stream.js.map +1 -0
  95. package/dist/realtime/comments.d.ts +217 -0
  96. package/dist/realtime/comments.d.ts.map +1 -0
  97. package/dist/realtime/comments.js +282 -0
  98. package/dist/realtime/comments.js.map +1 -0
  99. package/dist/realtime/gateway.d.ts +107 -0
  100. package/dist/realtime/gateway.d.ts.map +1 -0
  101. package/dist/realtime/gateway.js +215 -0
  102. package/dist/realtime/gateway.js.map +1 -0
  103. package/dist/realtime/index.d.ts +18 -0
  104. package/dist/realtime/index.d.ts.map +1 -0
  105. package/dist/realtime/index.js +18 -0
  106. package/dist/realtime/index.js.map +1 -0
  107. package/dist/realtime/notifications.d.ts +209 -0
  108. package/dist/realtime/notifications.d.ts.map +1 -0
  109. package/dist/realtime/notifications.js +209 -0
  110. package/dist/realtime/notifications.js.map +1 -0
  111. package/dist/realtime/persistence.d.ts +72 -0
  112. package/dist/realtime/persistence.d.ts.map +1 -0
  113. package/dist/realtime/persistence.js +53 -0
  114. package/dist/realtime/persistence.js.map +1 -0
  115. package/package.json +13 -4
  116. package/prisma/cms-schema.prisma +437 -306
  117. package/prisma/migrations/0001_init/migration.sql +384 -384
  118. package/prisma/migrations/0002_folders/migration.sql +39 -39
  119. package/prisma/migrations/0003_search_and_webhooks/migration.sql +50 -50
  120. package/prisma/migrations/0004_script_tags/migration.sql +21 -21
  121. package/prisma/migrations/0005_password_reset_tokens/migration.sql +20 -20
  122. package/prisma/migrations/0006_page_builder/migration.sql +38 -38
  123. package/prisma/migrations/migration_lock.toml +3 -3
  124. package/prisma/schema.prisma +563 -549
  125. package/generated/browser.ts +0 -109
  126. package/generated/client.ts +0 -133
  127. package/generated/commonInputTypes.ts +0 -709
  128. package/generated/enums.ts +0 -125
  129. package/generated/internal/class.ts +0 -376
  130. package/generated/internal/prismaNamespace.ts +0 -2617
  131. package/generated/internal/prismaNamespaceBrowser.ts +0 -611
  132. package/generated/models/ApiKey.ts +0 -1550
  133. package/generated/models/AuditLog.ts +0 -1206
  134. package/generated/models/BackupRecord.ts +0 -1250
  135. package/generated/models/ContentLock.ts +0 -1472
  136. package/generated/models/ContentTemplate.ts +0 -1416
  137. package/generated/models/Document.ts +0 -3005
  138. package/generated/models/Folder.ts +0 -1904
  139. package/generated/models/FormSubmission.ts +0 -1200
  140. package/generated/models/InAppNotification.ts +0 -1457
  141. package/generated/models/Media.ts +0 -2340
  142. package/generated/models/MediaUsage.ts +0 -1472
  143. package/generated/models/OAuthAccount.ts +0 -1463
  144. package/generated/models/Redirect.ts +0 -1284
  145. package/generated/models/Session.ts +0 -1492
  146. package/generated/models/Site.ts +0 -1206
  147. package/generated/models/User.ts +0 -3513
  148. package/generated/models/Version.ts +0 -1511
  149. package/generated/models/WorkflowState.ts +0 -1514
  150. package/generated/models.ts +0 -29
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ export { dispatch as dispatchWebhook, createEndpoint as createWebhookEndpoint, l
16
16
  export { buildLocaleFilter, buildLocaleFallbackQuery, getLocales, resolveLocale, } from './i18n/index.js';
17
17
  // Cache
18
18
  export { cached, revalidateTag, buildCacheKey, getDocumentCacheTags } from './cache/index.js';
19
+ export { ACTUATE_TAG_ROOT, actuateTag, invalidationTagsForDocumentWrite, invalidationTagsForGlobalWrite, publicReadCacheControl, } from './cache/http.js';
19
20
  // Content
20
21
  export { extractPlainText, extractExcerpt, hashContent, registerSchemaType, getSchemaType, generateJsonLd, renderJsonLdScript, buildContentGraph, serializeGraph, findIncomingReferences, handleContentApiRequest, sanitizeForPublicApi, } from './content/index.js';
21
22
  // Codegen
@@ -50,6 +51,7 @@ export { advanceWorkflow, rejectWorkflowStep, getWorkflowState } from './workflo
50
51
  export { canTransition, getAvailableTransitions, transitionDocument } from './workflow/index.js';
51
52
  // Presence
52
53
  export { createSSEPresenceAdapter } from './presence/index.js';
54
+ export { createPrismaDocumentPersistence, createRealtimeGateway } from './realtime/index.js';
53
55
  // Scheduling
54
56
  export { getScheduleCalendar, processScheduledPublish, processScheduledUnpublish, schedulingCronHandler, } from './scheduling/index.js';
55
57
  // Templates
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA0BhD,cAAc;AACd,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAA;AAG/B,SAAS;AACT,OAAO,EACL,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAQ1B,OAAO;AACP,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AAWxB,WAAW;AACX,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,mBAAmB,GACpB,MAAM,qBAAqB,CAAA;AAE5B,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGnD,WAAW;AACX,OAAO,EACL,QAAQ,IAAI,eAAe,EAC3B,cAAc,IAAI,qBAAqB,EACvC,aAAa,IAAI,oBAAoB,EACrC,cAAc,IAAI,qBAAqB,EACvC,cAAc,IAAI,qBAAqB,EACvC,aAAa,IAAI,oBAAoB,EACrC,cAAc,IAAI,qBAAqB,EACvC,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAG5B,OAAO;AACP,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,UAAU,EACV,aAAa,GACd,MAAM,iBAAiB,CAAA;AAExB,QAAQ;AACR,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAC7F,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,gCAAgC,EAChC,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,iBAAiB,CAAA;AAIxB,UAAU;AACV,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAW3B,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,iBAAiB;AACjB,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,SAAS,EACT,YAAY,GACb,MAAM,cAAc,CAAA;AAGrB,sBAAsB;AACtB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExD,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAGrD,uBAAuB;AACvB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAExD,oBAAoB;AACpB,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,GACf,MAAM,wBAAwB,CAAA;AAG/B,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAW7C,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAS1E,uEAAuE;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAGzD,UAAU;AACV,OAAO,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAQ3B,gBAAgB;AAChB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAG3F,gBAAgB;AAChB,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAGrE,iBAAiB;AACjB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAG1F,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG5F,6BAA6B;AAC7B,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAGhG,WAAW;AACX,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,EAAE,+BAA+B,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAW5F,aAAa;AACb,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,uBAAuB,CAAA;AAG9B,YAAY;AACZ,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGxF,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGhG,gBAAgB;AAChB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAG9D,SAAS;AACT,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAGxD,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAGzF,UAAU;AACV,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAGzD,oBAAoB;AACpB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGxF,QAAQ;AACR,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAA;AAGzB,qCAAqC;AACrC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAGzE,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAG/E,MAAM;AACN,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGhD,UAAU;AACV,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAGzD,eAAe;AACf,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,gBAAgB,CAAA;AAGvB,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,MAAM;AACN,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAChB,MAAM,gBAAgB,CAAA;AAYvB,eAAe;AACf,OAAO,EACL,WAAW,EACX,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,OAAO,EACP,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,aAAa,EACb,eAAe,EACf,SAAS,EACT,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,yBAAyB,CAAA"}
@@ -26,8 +26,8 @@ export declare const blockNodeSchema: z.ZodObject<{
26
26
  data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
27
27
  }, "strip", z.ZodTypeAny, {
28
28
  type: "block";
29
- data: Record<string, unknown>;
30
29
  id: string;
30
+ data: Record<string, unknown>;
31
31
  settings: {
32
32
  blockType: string;
33
33
  variant?: string | undefined;
@@ -40,8 +40,8 @@ export declare const blockNodeSchema: z.ZodObject<{
40
40
  } | undefined;
41
41
  }, {
42
42
  type: "block";
43
- data: Record<string, unknown>;
44
43
  id: string;
44
+ data: Record<string, unknown>;
45
45
  settings: {
46
46
  blockType: string;
47
47
  variant?: string | undefined;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * In-process pub/sub for live-preview update events.
3
+ *
4
+ * The admin emits `notifyPreviewUpdate(collection, id, payload)` whenever a
5
+ * draft document changes (today: the `PUT /collections/:slug/:id` route).
6
+ * Active SSE streams subscribe via `subscribePreviewUpdates(collection, id, listener)`
7
+ * and forward every payload through to their connected `EventSource`
8
+ * clients.
9
+ *
10
+ * The bus is intentionally single-instance and in-memory:
11
+ *
12
+ * - Self-hosted single-node deployments get push-to-iframe updates
13
+ * "for free" with zero extra infrastructure.
14
+ * - Multi-node deployments will see each node deliver only its own
15
+ * update events — fine for the Phase 2 finish-line. A future Slice
16
+ * can swap this for a Redis/postgres-listen backed bus without
17
+ * changing the public contract (`notifyPreviewUpdate` /
18
+ * `subscribePreviewUpdates`).
19
+ *
20
+ * The bus is keyed by `${collection}:${documentId}` so two simultaneously
21
+ * open previews for different docs don't see each other's traffic.
22
+ */
23
+ export interface PreviewUpdateEvent {
24
+ collection: string;
25
+ documentId: string;
26
+ /** Free-form payload — the SSE handler stringifies it as the event data. */
27
+ payload: Record<string, unknown>;
28
+ /** Server-side emission timestamp; useful for clients to detect skew. */
29
+ at: number;
30
+ }
31
+ export type PreviewUpdateListener = (event: PreviewUpdateEvent) => void;
32
+ export declare function subscribePreviewUpdates(collection: string, documentId: string, listener: PreviewUpdateListener): () => void;
33
+ export declare function notifyPreviewUpdate(collection: string, documentId: string, payload: Record<string, unknown>): void;
34
+ export declare function previewSubscriberCount(collection: string, documentId: string): number;
35
+ /**
36
+ * Test helper. Drops every subscription. Production code never calls this.
37
+ */
38
+ export declare function __resetPreviewEventBus(): void;
39
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/preview/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAA;AAQvE,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,qBAAqB,GAC9B,MAAM,IAAI,CAcZ;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI,CAiBN;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAErF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * In-process pub/sub for live-preview update events.
3
+ *
4
+ * The admin emits `notifyPreviewUpdate(collection, id, payload)` whenever a
5
+ * draft document changes (today: the `PUT /collections/:slug/:id` route).
6
+ * Active SSE streams subscribe via `subscribePreviewUpdates(collection, id, listener)`
7
+ * and forward every payload through to their connected `EventSource`
8
+ * clients.
9
+ *
10
+ * The bus is intentionally single-instance and in-memory:
11
+ *
12
+ * - Self-hosted single-node deployments get push-to-iframe updates
13
+ * "for free" with zero extra infrastructure.
14
+ * - Multi-node deployments will see each node deliver only its own
15
+ * update events — fine for the Phase 2 finish-line. A future Slice
16
+ * can swap this for a Redis/postgres-listen backed bus without
17
+ * changing the public contract (`notifyPreviewUpdate` /
18
+ * `subscribePreviewUpdates`).
19
+ *
20
+ * The bus is keyed by `${collection}:${documentId}` so two simultaneously
21
+ * open previews for different docs don't see each other's traffic.
22
+ */
23
+ const listenersByKey = new Map();
24
+ function keyOf(collection, documentId) {
25
+ return `${collection}:${documentId}`;
26
+ }
27
+ export function subscribePreviewUpdates(collection, documentId, listener) {
28
+ const key = keyOf(collection, documentId);
29
+ let set = listenersByKey.get(key);
30
+ if (!set) {
31
+ set = new Set();
32
+ listenersByKey.set(key, set);
33
+ }
34
+ set.add(listener);
35
+ return () => {
36
+ const current = listenersByKey.get(key);
37
+ if (!current)
38
+ return;
39
+ current.delete(listener);
40
+ if (current.size === 0)
41
+ listenersByKey.delete(key);
42
+ };
43
+ }
44
+ export function notifyPreviewUpdate(collection, documentId, payload) {
45
+ const set = listenersByKey.get(keyOf(collection, documentId));
46
+ if (!set || set.size === 0)
47
+ return;
48
+ const event = {
49
+ collection,
50
+ documentId,
51
+ payload,
52
+ at: Date.now(),
53
+ };
54
+ for (const listener of [...set]) {
55
+ try {
56
+ listener(event);
57
+ }
58
+ catch {
59
+ // listener throws are isolated — one buggy stream must not take down
60
+ // every other subscriber for the same doc.
61
+ }
62
+ }
63
+ }
64
+ export function previewSubscriberCount(collection, documentId) {
65
+ return listenersByKey.get(keyOf(collection, documentId))?.size ?? 0;
66
+ }
67
+ /**
68
+ * Test helper. Drops every subscription. Production code never calls this.
69
+ */
70
+ export function __resetPreviewEventBus() {
71
+ listenersByKey.clear();
72
+ }
73
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../src/preview/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAaH,MAAM,cAAc,GAAG,IAAI,GAAG,EAAsC,CAAA;AAEpE,SAAS,KAAK,CAAC,UAAkB,EAAE,UAAkB;IACnD,OAAO,GAAG,UAAU,IAAI,UAAU,EAAE,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAkB,EAClB,UAAkB,EAClB,QAA+B;IAE/B,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IACzC,IAAI,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;QACf,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC9B,CAAC;IACD,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACjB,OAAO,GAAG,EAAE;QACV,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACxB,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACpD,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,UAAkB,EAClB,UAAkB,EAClB,OAAgC;IAEhC,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;IAC7D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAM;IAClC,MAAM,KAAK,GAAuB;QAChC,UAAU;QACV,UAAU;QACV,OAAO;QACP,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;KACf,CAAA;IACD,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;YACrE,2CAA2C;QAC7C,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,UAAkB;IAC3E,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAA;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,cAAc,CAAC,KAAK,EAAE,CAAA;AACxB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { PreviewSession } from './index.js';
2
+ /**
3
+ * Default keepalive interval. 25 s sits safely under the most aggressive
4
+ * proxy/idle timeouts we've encountered in production (Cloudflare 30 s,
5
+ * Vercel Serverless 30 s, most reverse-proxies 60 s).
6
+ */
7
+ export declare const PREVIEW_SSE_HEARTBEAT_MS = 25000;
8
+ /**
9
+ * Maximum stream lifetime in ms. After this, the server closes the stream
10
+ * cleanly so EventSource will reconnect — important because some platforms
11
+ * (Vercel Fluid Compute, Cloudflare Workers) cap any single response at a
12
+ * few minutes regardless of activity.
13
+ */
14
+ export declare const PREVIEW_SSE_MAX_LIFETIME_MS: number;
15
+ export interface PreviewStreamOptions {
16
+ /** Override for tests so we don't have to wait 25 seconds. */
17
+ heartbeatMs?: number;
18
+ /** Override for tests so we don't tie up the suite for 4 minutes. */
19
+ maxLifetimeMs?: number;
20
+ }
21
+ /**
22
+ * Encode a single SSE message. `event` is optional; when omitted the
23
+ * default `message` event is used.
24
+ */
25
+ export declare function encodeSseEvent(data: unknown, event?: string): string;
26
+ /**
27
+ * Build a `ReadableStream` of Server-Sent Events for the given preview
28
+ * session. The stream:
29
+ *
30
+ * 1. Emits an `event: ready` frame with the session's collection/id.
31
+ * Lets the client confirm the server-side subscription is wired up
32
+ * before it starts treating the absence of events as "stale".
33
+ * 2. Forwards every `notifyPreviewUpdate(collection, id, payload)` to
34
+ * the client as `event: update` with `payload` as JSON data.
35
+ * 3. Sends `: heartbeat\n\n` keepalive comments on
36
+ * `PREVIEW_SSE_HEARTBEAT_MS` intervals.
37
+ * 4. Cleanly closes after `PREVIEW_SSE_MAX_LIFETIME_MS` and lets the
38
+ * browser reconnect, sidestepping platform idle/max-duration caps.
39
+ *
40
+ * The returned stream MUST be wrapped in a `Response` with the SSE
41
+ * headers — `createPreviewStreamResponse` does this for typical callers.
42
+ */
43
+ export declare function createPreviewStream(session: Pick<PreviewSession, 'collection' | 'documentId'>, opts?: PreviewStreamOptions): ReadableStream<Uint8Array>;
44
+ /**
45
+ * Standard SSE response headers. Exposed for callers (and tests) that want
46
+ * to wrap the stream themselves.
47
+ */
48
+ export declare const PREVIEW_SSE_HEADERS: Record<string, string>;
49
+ export declare function createPreviewStreamResponse(session: Pick<PreviewSession, 'collection' | 'documentId'>, opts?: PreviewStreamOptions): Response;
50
+ //# sourceMappingURL=sse-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-stream.d.ts","sourceRoot":"","sources":["../../src/preview/sse-stream.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAUhD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAA;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,QAAgB,CAAA;AAExD,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAUpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,YAAY,CAAC,EAC1D,IAAI,GAAE,oBAAyB,GAC9B,cAAc,CAAC,UAAU,CAAC,CAwD5B;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOtD,CAAA;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,YAAY,CAAC,EAC1D,IAAI,CAAC,EAAE,oBAAoB,GAC1B,QAAQ,CAKV"}
@@ -0,0 +1,120 @@
1
+ import { subscribePreviewUpdates } from './event-bus.js';
2
+ /**
3
+ * SSE wire format helpers. We keep them small and pure so the route handler
4
+ * can build a `ReadableStream<Uint8Array>` without pulling in any extra
5
+ * dependencies (this also keeps the file edge-compatible).
6
+ */
7
+ const encoder = new TextEncoder();
8
+ /**
9
+ * Default keepalive interval. 25 s sits safely under the most aggressive
10
+ * proxy/idle timeouts we've encountered in production (Cloudflare 30 s,
11
+ * Vercel Serverless 30 s, most reverse-proxies 60 s).
12
+ */
13
+ export const PREVIEW_SSE_HEARTBEAT_MS = 25_000;
14
+ /**
15
+ * Maximum stream lifetime in ms. After this, the server closes the stream
16
+ * cleanly so EventSource will reconnect — important because some platforms
17
+ * (Vercel Fluid Compute, Cloudflare Workers) cap any single response at a
18
+ * few minutes regardless of activity.
19
+ */
20
+ export const PREVIEW_SSE_MAX_LIFETIME_MS = 4 * 60 * 1000;
21
+ /**
22
+ * Encode a single SSE message. `event` is optional; when omitted the
23
+ * default `message` event is used.
24
+ */
25
+ export function encodeSseEvent(data, event) {
26
+ const lines = [];
27
+ if (event)
28
+ lines.push(`event: ${event}`);
29
+ const serialized = typeof data === 'string' ? data : JSON.stringify(data);
30
+ for (const line of serialized.split('\n')) {
31
+ lines.push(`data: ${line}`);
32
+ }
33
+ lines.push('');
34
+ lines.push('');
35
+ return lines.join('\n');
36
+ }
37
+ /**
38
+ * Build a `ReadableStream` of Server-Sent Events for the given preview
39
+ * session. The stream:
40
+ *
41
+ * 1. Emits an `event: ready` frame with the session's collection/id.
42
+ * Lets the client confirm the server-side subscription is wired up
43
+ * before it starts treating the absence of events as "stale".
44
+ * 2. Forwards every `notifyPreviewUpdate(collection, id, payload)` to
45
+ * the client as `event: update` with `payload` as JSON data.
46
+ * 3. Sends `: heartbeat\n\n` keepalive comments on
47
+ * `PREVIEW_SSE_HEARTBEAT_MS` intervals.
48
+ * 4. Cleanly closes after `PREVIEW_SSE_MAX_LIFETIME_MS` and lets the
49
+ * browser reconnect, sidestepping platform idle/max-duration caps.
50
+ *
51
+ * The returned stream MUST be wrapped in a `Response` with the SSE
52
+ * headers — `createPreviewStreamResponse` does this for typical callers.
53
+ */
54
+ export function createPreviewStream(session, opts = {}) {
55
+ const heartbeatMs = opts.heartbeatMs ?? PREVIEW_SSE_HEARTBEAT_MS;
56
+ const maxLifetimeMs = opts.maxLifetimeMs ?? PREVIEW_SSE_MAX_LIFETIME_MS;
57
+ let heartbeat;
58
+ let lifetime;
59
+ let unsubscribe;
60
+ return new ReadableStream({
61
+ start(controller) {
62
+ const enqueue = (chunk) => {
63
+ try {
64
+ controller.enqueue(encoder.encode(chunk));
65
+ }
66
+ catch {
67
+ // Controller can be closed mid-emit if the client disconnected
68
+ // between the `notifyPreviewUpdate` call and the enqueue. Swallow.
69
+ }
70
+ };
71
+ enqueue(encodeSseEvent({ collection: session.collection, documentId: session.documentId }, 'ready'));
72
+ unsubscribe = subscribePreviewUpdates(session.collection, session.documentId, (event) => {
73
+ enqueue(encodeSseEvent({
74
+ collection: event.collection,
75
+ documentId: event.documentId,
76
+ at: event.at,
77
+ ...event.payload,
78
+ }, 'update'));
79
+ });
80
+ heartbeat = setInterval(() => {
81
+ enqueue(`: heartbeat\n\n`);
82
+ }, heartbeatMs);
83
+ lifetime = setTimeout(() => {
84
+ try {
85
+ controller.close();
86
+ }
87
+ catch {
88
+ // Already closed; nothing to do.
89
+ }
90
+ }, maxLifetimeMs);
91
+ },
92
+ cancel() {
93
+ if (heartbeat)
94
+ clearInterval(heartbeat);
95
+ if (lifetime)
96
+ clearTimeout(lifetime);
97
+ if (unsubscribe)
98
+ unsubscribe();
99
+ },
100
+ });
101
+ }
102
+ /**
103
+ * Standard SSE response headers. Exposed for callers (and tests) that want
104
+ * to wrap the stream themselves.
105
+ */
106
+ export const PREVIEW_SSE_HEADERS = {
107
+ 'Content-Type': 'text/event-stream; charset=utf-8',
108
+ 'Cache-Control': 'no-cache, no-transform',
109
+ Connection: 'keep-alive',
110
+ // Discourage proxies/CDNs from buffering — without this nginx will hold
111
+ // events back until 4 KB of payload accumulates.
112
+ 'X-Accel-Buffering': 'no',
113
+ };
114
+ export function createPreviewStreamResponse(session, opts) {
115
+ return new Response(createPreviewStream(session, opts), {
116
+ status: 200,
117
+ headers: PREVIEW_SSE_HEADERS,
118
+ });
119
+ }
120
+ //# sourceMappingURL=sse-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-stream.js","sourceRoot":"","sources":["../../src/preview/sse-stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Document comments — anchored, threaded discussion attached to documents.
3
+ *
4
+ * This module owns the *pure* comment logic: validation, normalization, and
5
+ * the storage-agnostic CRUD entry points. The HTTP layer in `api/handlers.ts`
6
+ * is a thin wrapper that handles auth + JSON envelope; everything else lives
7
+ * here so the unit tests don't need a Request loop.
8
+ *
9
+ * Storage shape — see `packages/cms-core/prisma/cms-schema.prisma`,
10
+ * model `DocumentComment`. We require only a minimal Prisma surface so the
11
+ * helpers can be tested against an in-memory fake.
12
+ *
13
+ * Anchors are Yjs *relative positions* serialised as Base64. Storing them in
14
+ * a JSON column (rather than Bytes) keeps the REST contract trivial: the
15
+ * client posts `{ from: "AQ...", to: "AQ..." }`, we round-trip the strings.
16
+ * Slice 5 reconstitutes them with `Y.createAbsolutePositionFromRelativePosition`
17
+ * to paint anchored highlights in the editor; nothing in the API layer needs
18
+ * to interpret the bytes.
19
+ */
20
+ /** Maximum length we accept for a comment body (markdown source). */
21
+ export declare const MAX_COMMENT_BODY_LENGTH = 10000;
22
+ /** Cap on returned comments per `listComments` call. */
23
+ export declare const MAX_COMMENT_LIST_PAGE_SIZE = 200;
24
+ /** Default page size when the caller does not request one. */
25
+ export declare const DEFAULT_COMMENT_LIST_PAGE_SIZE = 100;
26
+ /**
27
+ * Yjs relative-position anchor. The two ends are Base64-encoded
28
+ * `Y.encodeRelativePosition` bytes; slice 5 turns them back into absolute
29
+ * positions for rendering.
30
+ *
31
+ * Slice 4 (this module) treats the anchor as opaque: we only validate that
32
+ * each side is a reasonably short string so we don't store arbitrary blobs.
33
+ */
34
+ export interface CommentAnchor {
35
+ from: string;
36
+ to: string;
37
+ }
38
+ /**
39
+ * Public REST shape of a comment. Mirrors the Prisma row plus a derived
40
+ * `isResolved` flag so the client doesn't have to repeat the null check.
41
+ */
42
+ export interface CommentDTO {
43
+ id: string;
44
+ documentId: string;
45
+ parentId: string | null;
46
+ userId: string | null;
47
+ body: string;
48
+ anchor: CommentAnchor | null;
49
+ resolvedAt: string | null;
50
+ resolvedById: string | null;
51
+ deletedAt: string | null;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ isResolved: boolean;
55
+ }
56
+ /** Input for creating a new comment. */
57
+ export interface CreateCommentInput {
58
+ documentId: string;
59
+ userId: string;
60
+ body: string;
61
+ anchor?: CommentAnchor | null;
62
+ parentId?: string | null;
63
+ }
64
+ /** Input for updating an existing comment. Only the body is editable. */
65
+ export interface UpdateCommentInput {
66
+ body: string;
67
+ }
68
+ /** Filter passed to `listComments`. */
69
+ export interface ListCommentsFilter {
70
+ documentId: string;
71
+ /** Include resolved threads. Default: `false`. */
72
+ includeResolved?: boolean;
73
+ /** Include soft-deleted comments. Default: `false`. */
74
+ includeDeleted?: boolean;
75
+ /** Page size (1..`MAX_COMMENT_LIST_PAGE_SIZE`). */
76
+ pageSize?: number;
77
+ }
78
+ /**
79
+ * Minimal Prisma surface we depend on. The real `PrismaClient` satisfies it,
80
+ * but tests inject a small in-memory fake.
81
+ */
82
+ export interface CommentsDB {
83
+ documentComment: {
84
+ findUnique: (args: {
85
+ where: {
86
+ id: string;
87
+ };
88
+ [key: string]: unknown;
89
+ }) => Promise<DocumentCommentRow | null>;
90
+ findMany: (args: {
91
+ where: Record<string, unknown>;
92
+ orderBy?: Record<string, 'asc' | 'desc'>;
93
+ take?: number;
94
+ }) => Promise<DocumentCommentRow[]>;
95
+ create: (args: {
96
+ data: {
97
+ documentId: string;
98
+ userId: string | null;
99
+ body: string;
100
+ anchor: CommentAnchor | null;
101
+ parentId: string | null;
102
+ };
103
+ }) => Promise<DocumentCommentRow>;
104
+ update: (args: {
105
+ where: {
106
+ id: string;
107
+ };
108
+ data: Partial<{
109
+ body: string;
110
+ resolvedAt: Date | null;
111
+ resolvedById: string | null;
112
+ deletedAt: Date | null;
113
+ }>;
114
+ }) => Promise<DocumentCommentRow>;
115
+ };
116
+ }
117
+ /** Row shape returned by Prisma. We accept Date or ISO strings so fakes are cheap. */
118
+ export interface DocumentCommentRow {
119
+ id: string;
120
+ documentId: string;
121
+ parentId: string | null;
122
+ userId: string | null;
123
+ body: string;
124
+ anchor: CommentAnchor | null;
125
+ resolvedAt: Date | string | null;
126
+ resolvedById: string | null;
127
+ deletedAt: Date | string | null;
128
+ createdAt: Date | string;
129
+ updatedAt: Date | string;
130
+ }
131
+ /** Discriminated result type used by the service entry points. */
132
+ export type CommentsResult<T> = {
133
+ ok: true;
134
+ value: T;
135
+ } | {
136
+ ok: false;
137
+ error: CommentsError;
138
+ };
139
+ export interface CommentsError {
140
+ /**
141
+ * Stable machine-readable code. The HTTP layer maps each to a status:
142
+ * - validation → 400
143
+ * - not_found → 404
144
+ * - forbidden → 403
145
+ * - conflict → 409 (e.g. resolving an already-resolved thread)
146
+ */
147
+ code: 'validation' | 'not_found' | 'forbidden' | 'conflict';
148
+ message: string;
149
+ }
150
+ /**
151
+ * Strip a comment row down to the public DTO. Centralised so the response
152
+ * shape stays consistent between create / list / update / resolve.
153
+ */
154
+ export declare function toCommentDTO(row: DocumentCommentRow): CommentDTO;
155
+ /**
156
+ * Parse + validate an anchor blob coming from an untrusted client. Returns
157
+ * `null` when the caller did not provide one (document-level comments).
158
+ */
159
+ export declare function parseAnchor(input: unknown): CommentsResult<CommentAnchor | null>;
160
+ /** Normalize whitespace + enforce length limits on a posted body. */
161
+ export declare function normaliseBody(input: unknown): CommentsResult<string>;
162
+ /**
163
+ * Create a comment. Enforces:
164
+ * - body validation (non-empty, length-capped)
165
+ * - anchor shape validation
166
+ * - single-level threading: a `parentId` must reference an existing,
167
+ * non-deleted, non-reply comment under the same document.
168
+ *
169
+ * The caller (HTTP handler) is responsible for auth — once we reach here we
170
+ * trust the supplied `userId`.
171
+ */
172
+ export declare function createComment(db: CommentsDB, input: CreateCommentInput): Promise<CommentsResult<CommentDTO>>;
173
+ /**
174
+ * List comments for a document. Returns the rows ordered oldest-first so a
175
+ * naive client can render threads top-down. Pagination is "show the first
176
+ * N"; the higher-level UI in slice 5 will switch to cursor pagination once
177
+ * volume justifies it.
178
+ */
179
+ export declare function listComments(db: CommentsDB, filter: ListCommentsFilter): Promise<CommentsResult<CommentDTO[]>>;
180
+ /**
181
+ * Edit a comment body. Only the author can edit, and only if the comment is
182
+ * not soft-deleted. Resolved threads remain editable so a moderator can
183
+ * append context.
184
+ */
185
+ export declare function updateComment(db: CommentsDB, id: string, input: UpdateCommentInput, actor: {
186
+ userId: string;
187
+ isAdmin: boolean;
188
+ }): Promise<CommentsResult<CommentDTO>>;
189
+ /**
190
+ * Mark a comment thread as resolved. Either the comment's author or any
191
+ * admin / write-role caller can resolve. Resolving an already-resolved
192
+ * comment is a no-op (returns the existing row) so a duplicate click in the
193
+ * UI does not surface as an error.
194
+ */
195
+ export declare function resolveComment(db: CommentsDB, id: string, actor: {
196
+ userId: string;
197
+ canResolve: boolean;
198
+ }): Promise<CommentsResult<CommentDTO>>;
199
+ /**
200
+ * Re-open a resolved thread. Same permission as `resolveComment`.
201
+ */
202
+ export declare function reopenComment(db: CommentsDB, id: string, actor: {
203
+ userId: string;
204
+ canResolve: boolean;
205
+ }): Promise<CommentsResult<CommentDTO>>;
206
+ /**
207
+ * Soft-delete a comment. The row is preserved (so replies don't lose their
208
+ * thread root) but stops being returned by `listComments` unless explicitly
209
+ * requested with `includeDeleted: true`.
210
+ *
211
+ * Only the author or an admin may delete.
212
+ */
213
+ export declare function deleteComment(db: CommentsDB, id: string, actor: {
214
+ userId: string;
215
+ isAdmin: boolean;
216
+ }): Promise<CommentsResult<CommentDTO>>;
217
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/realtime/comments.ts"],"names":[],"mappings":"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"}