@happyvertical/smrt-comments 0.57.1 → 0.57.3
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.
- package/README.md +72 -0
- package/dist/chunks/participation-LA_cfrM2.js +276 -0
- package/dist/chunks/participation-LA_cfrM2.js.map +1 -0
- package/dist/collections/CommentReportCollection.d.ts +6 -0
- package/dist/collections/CommentReportCollection.d.ts.map +1 -0
- package/dist/collections/CommentRevisionCollection.d.ts +6 -0
- package/dist/collections/CommentRevisionCollection.d.ts.map +1 -0
- package/dist/collections/ParticipationCollection.d.ts +14 -0
- package/dist/collections/ParticipationCollection.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +364 -59
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1853 -224
- package/dist/models/Comment.d.ts +8 -1
- package/dist/models/Comment.d.ts.map +1 -1
- package/dist/models/CommentReport.d.ts +10 -0
- package/dist/models/CommentReport.d.ts.map +1 -0
- package/dist/models/CommentRevision.d.ts +9 -0
- package/dist/models/CommentRevision.d.ts.map +1 -0
- package/dist/models/ParticipationBan.d.ts +12 -0
- package/dist/models/ParticipationBan.d.ts.map +1 -0
- package/dist/models/ParticipationPolicy.d.ts +13 -0
- package/dist/models/ParticipationPolicy.d.ts.map +1 -0
- package/dist/models/ParticipationRateBucket.d.ts +8 -0
- package/dist/models/ParticipationRateBucket.d.ts.map +1 -0
- package/dist/participation-contract.d.ts +37 -0
- package/dist/participation-contract.d.ts.map +1 -0
- package/dist/participation.d.ts +4 -0
- package/dist/participation.d.ts.map +1 -0
- package/dist/participation.js +2 -0
- package/dist/recipes.d.ts +6 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/services/CommentService.d.ts +10 -1
- package/dist/services/CommentService.d.ts.map +1 -1
- package/dist/services/ParticipationService.d.ts +25 -0
- package/dist/services/ParticipationService.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +477 -12
- package/dist/svelte/ModerationQueue.svelte +60 -0
- package/dist/svelte/ModerationQueue.svelte.d.ts +17 -0
- package/dist/svelte/ModerationQueue.svelte.d.ts.map +1 -0
- package/dist/svelte/RecordComments.svelte +21 -6
- package/dist/svelte/RecordComments.svelte.d.ts +2 -0
- package/dist/svelte/RecordComments.svelte.d.ts.map +1 -1
- package/dist/svelte/index.d.ts +2 -0
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +1 -0
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -5
package/dist/index.js
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as ParticipationRateBucketCollection, c as ParticipationBan, i as ParticipationPolicyCollection, n as ParticipationDeniedError, o as ParticipationRateBucket, r as ParticipationBanCollection, s as ParticipationPolicy, t as ParticipationService } from "./chunks/participation-LA_cfrM2.js";
|
|
2
|
+
import { SmrtCollection, SmrtObject, SmrtPolymorphicAssociation, SmrtRecipe, crossPackageRef, digestRunOnceContent, field, foreignKey, runOnce, smrt } from "@happyvertical/smrt-core";
|
|
2
3
|
import { TenantIsolationError, TenantScoped, getCurrentTenant, tenantId, withTenant } from "@happyvertical/smrt-tenancy";
|
|
3
|
-
//#region src/__smrt-register__.ts
|
|
4
|
-
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-comments","packageVersion":"0.57.1","objects":{"@happyvertical/smrt-comments:CommentCollection":{"name":"commentcollection","className":"CommentCollection","qualifiedName":"@happyvertical/smrt-comments:CommentCollection","collection":"comments","filePath":"/home/runner/work/smrt/smrt/packages/comments/src/collections/CommentCollection.ts","packageName":"@happyvertical/smrt-comments","fields":{},"methods":{"listForRecord":{"name":"listForRecord","async":true,"parameters":[{"name":"recordType","type":"string","optional":false},{"name":"recordId","type":"string","optional":false}],"returnType":"Promise<Comment[]>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"record_comments","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"Comment","exportName":"CommentCollection","collectionExportName":"CommentCollectionCollection","schema":{"tableName":"record_comments","ddl":"CREATE TABLE IF NOT EXISTS \\"record_comments\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"meta_type\\" TEXT NOT NULL,\\n \\"meta_id\\" TEXT NOT NULL,\\n \\"role\\" TEXT NOT NULL,\\n \\"sort_order\\" INTEGER DEFAULT 0,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"author_user_id\\" UUID NOT NULL,\\n \\"body\\" TEXT NOT NULL,\\n \\"mentions\\" TEXT,\\n \\"idempotency_key\\" TEXT,\\n \\"retry_tenant_id\\" TEXT,\\n \\"request_digest\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"meta_type":{"type":"TEXT","notNull":true,"unique":false},"meta_id":{"type":"TEXT","notNull":true,"unique":false},"role":{"type":"TEXT","notNull":true,"unique":false},"sort_order":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"author_user_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"body":{"type":"TEXT","notNull":true,"unique":false},"mentions":{"type":"TEXT","notNull":false,"unique":false},"idempotency_key":{"type":"TEXT","notNull":false,"unique":false},"retry_tenant_id":{"type":"TEXT","notNull":false,"unique":false},"request_digest":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"record_comments_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"record_comments_tenant_request_key","columns":["retry_tenant_id","idempotency_key"],"unique":true},{"name":"record_comments_record_created_idx","columns":["tenant_id","meta_type","meta_id","created_at"]},{"name":"record_comments_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"record_comments_meta_type_meta_id_idx","columns":["meta_type","meta_id"]},{"name":"record_comments_author_user_id_idx","columns":["author_user_id"]}],"version":"5095dfc9"},"importPath":"@happyvertical/smrt-comments"},"@happyvertical/smrt-comments:Comment":{"name":"comment","className":"Comment","qualifiedName":"@happyvertical/smrt-comments:Comment","collection":"comments","filePath":"/home/runner/work/smrt/smrt/packages/comments/src/models/Comment.ts","packageName":"@happyvertical/smrt-comments","fields":{"metaType":{"type":"text","required":true,"_meta":{"required":true}},"metaId":{"type":"text","required":true,"_meta":{"required":true}},"role":{"type":"text","required":true,"_meta":{"required":true}},"sortOrder":{"type":"integer","required":false,"default":0},"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"authorUserId":{"type":"crossPackageRef","required":true,"related":"@happyvertical/smrt-users:User"},"body":{"type":"text","required":true,"_meta":{"required":true}},"mentions":{"type":"text","required":false},"idempotencyKey":{"type":"text","required":false,"_meta":{"nullable":true,"readonly":true},"readonly":true},"retryTenantId":{"type":"text","required":false,"_meta":{"nullable":true,"readonly":true},"readonly":true},"requestDigest":{"type":"text","required":false,"_meta":{"nullable":true,"readonly":true},"readonly":true}},"methods":{"hydrate":{"name":"hydrate","async":true,"parameters":[],"returnType":"Promise<T | null>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"record_comments","api":false,"mcp":false,"cli":false,"indexes":[{"name":"record_comments_tenant_request_key","columns":["retryTenantId","idempotencyKey"],"unique":true},{"name":"record_comments_record_created_idx","columns":["tenantId","metaType","metaId","createdAt"]}],"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtPolymorphicAssociation","exportName":"Comment","collectionExportName":"CommentCollection","validationRules":[{"field":"metaType","rule":"required","fieldType":"text"},{"field":"metaId","rule":"required","fieldType":"text"},{"field":"role","rule":"required","fieldType":"text"},{"field":"authorUserId","rule":"required","fieldType":"crossPackageRef"},{"field":"body","rule":"required","fieldType":"text"}],"schema":{"tableName":"record_comments","ddl":"CREATE TABLE IF NOT EXISTS \\"record_comments\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"meta_type\\" TEXT NOT NULL,\\n \\"meta_id\\" TEXT NOT NULL,\\n \\"role\\" TEXT NOT NULL,\\n \\"sort_order\\" INTEGER DEFAULT 0,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"author_user_id\\" UUID NOT NULL,\\n \\"body\\" TEXT NOT NULL,\\n \\"mentions\\" TEXT,\\n \\"idempotency_key\\" TEXT,\\n \\"retry_tenant_id\\" TEXT,\\n \\"request_digest\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"meta_type":{"type":"TEXT","notNull":true,"unique":false},"meta_id":{"type":"TEXT","notNull":true,"unique":false},"role":{"type":"TEXT","notNull":true,"unique":false},"sort_order":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"author_user_id":{"type":"UUID","referenceKind":"crossPackageRef","notNull":true,"unique":false},"body":{"type":"TEXT","notNull":true,"unique":false},"mentions":{"type":"TEXT","notNull":false,"unique":false},"idempotency_key":{"type":"TEXT","notNull":false,"unique":false},"retry_tenant_id":{"type":"TEXT","notNull":false,"unique":false},"request_digest":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"record_comments_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"record_comments_tenant_request_key","columns":["retry_tenant_id","idempotency_key"],"unique":true},{"name":"record_comments_record_created_idx","columns":["tenant_id","meta_type","meta_id","created_at"]},{"name":"record_comments_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"record_comments_meta_type_meta_id_idx","columns":["meta_type","meta_id"]},{"name":"record_comments_author_user_id_idx","columns":["author_user_id"]}],"version":"5095dfc9"},"importPath":"@happyvertical/smrt-comments"}},"moduleType":"smrt","recipes":[{"id":"comments.records","className":"RecordCommentsRecipe","label":"Record comments","summary":"Discuss work directly on the records it concerns.","synonyms":["comments","mentions","discussion"],"models":["@happyvertical/smrt-comments:Comment"],"nav":[],"requires":[],"group":{"id":"comments","label":"Comments","summary":"Keep discussions alongside the records your team works on."},"help":{"markdown":"## Overview\\n\\nRecord comments keep a discussion next to the work it concerns. Open a record\\nyou can access to read its discussion or add a comment. Comments are part of\\nthe record page, rather than a separate list of every discussion.\\n\\n## Tasks\\n\\n### Add a comment\\n\\nOpen the record, find Comments, write your message and choose Post comment.\\nYour app controls who can read the record and who can contribute to its discussion.\\n\\n### Mention someone\\n\\nIf your app provides mention selection, choose a teammate who can access the\\nrecord. When mention notifications are connected, that person receives a\\nnotification. Typing a name alone does not select a recipient.\\n\\n### Check a failed post\\n\\nIf posting reports an error, refresh the discussion before trying again. A\\ncomment may have been saved even when its mention notification could not be\\ndelivered. If it appears in the discussion, do not post it a second time.\\n","fieldRefs":[]},"surfaces":[{"kind":"playground","export":"@happyvertical/smrt-comments/svelte#RecordCommentsPlayground","label":"Record discussion preview"}],"runtime":"both","demoSeed":{"export":"@happyvertical/smrt-comments/svelte#recordCommentsDemo"},"demo":{"mode":"server","reasons":["Needs a server because its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624)."]}}],"smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-messages","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3624"],"via":["@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
|
|
5
|
-
//#endregion
|
|
6
4
|
//#region src/models/Comment.ts
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
5
|
+
var __defProp$2 = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {
|
|
10
8
|
enumerable: true,
|
|
11
9
|
configurable: true,
|
|
12
10
|
writable: true,
|
|
13
11
|
value
|
|
14
12
|
}) : obj[key] = value;
|
|
15
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
16
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
13
|
+
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
14
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
17
15
|
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
18
|
-
if (kind && result) __defProp(target, key, result);
|
|
16
|
+
if (kind && result) __defProp$2(target, key, result);
|
|
19
17
|
return result;
|
|
20
18
|
};
|
|
21
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
19
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
20
|
var MAX_MENTIONS = 50;
|
|
23
21
|
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24
22
|
var Comment = class extends SmrtPolymorphicAssociation {
|
|
@@ -30,6 +28,10 @@ var Comment = class extends SmrtPolymorphicAssociation {
|
|
|
30
28
|
idempotencyKey = null;
|
|
31
29
|
retryTenantId = null;
|
|
32
30
|
requestDigest = null;
|
|
31
|
+
parentCommentId = null;
|
|
32
|
+
status = "visible";
|
|
33
|
+
participationSnapshot = null;
|
|
34
|
+
editedAt = null;
|
|
33
35
|
constructor(options = {}) {
|
|
34
36
|
super(options);
|
|
35
37
|
if (options.tenantId !== void 0) this.tenantId = options.tenantId;
|
|
@@ -38,6 +40,9 @@ var Comment = class extends SmrtPolymorphicAssociation {
|
|
|
38
40
|
if (options.idempotencyKey !== void 0) this.idempotencyKey = options.idempotencyKey;
|
|
39
41
|
if (options.retryTenantId !== void 0) this.retryTenantId = options.retryTenantId;
|
|
40
42
|
if (options.requestDigest !== void 0) this.requestDigest = options.requestDigest;
|
|
43
|
+
if (options.parentCommentId !== void 0) this.parentCommentId = options.parentCommentId;
|
|
44
|
+
if (options.status !== void 0) this.status = options.status;
|
|
45
|
+
if (options.participationSnapshot !== void 0) this.participationSnapshot = options.participationSnapshot;
|
|
41
46
|
const mentions = options.mentions;
|
|
42
47
|
if (Array.isArray(mentions)) this.mentionUserIds = mentions;
|
|
43
48
|
else if (typeof mentions === "string") this.mentions = mentions;
|
|
@@ -56,43 +61,77 @@ var Comment = class extends SmrtPolymorphicAssociation {
|
|
|
56
61
|
this.mentions = JSON.stringify(unique);
|
|
57
62
|
}
|
|
58
63
|
};
|
|
59
|
-
__publicField(Comment, "__smrtPackage__", "@happyvertical/smrt-comments");
|
|
60
|
-
__decorateClass([tenantId()], Comment.prototype, "tenantId", 2);
|
|
61
|
-
__decorateClass([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], Comment.prototype, "authorUserId", 2);
|
|
62
|
-
__decorateClass([field({ required: true })], Comment.prototype, "body", 2);
|
|
63
|
-
__decorateClass([field({
|
|
64
|
+
__publicField$2(Comment, "__smrtPackage__", "@happyvertical/smrt-comments");
|
|
65
|
+
__decorateClass$2([tenantId()], Comment.prototype, "tenantId", 2);
|
|
66
|
+
__decorateClass$2([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], Comment.prototype, "authorUserId", 2);
|
|
67
|
+
__decorateClass$2([field({ required: true })], Comment.prototype, "body", 2);
|
|
68
|
+
__decorateClass$2([field({
|
|
64
69
|
type: "text",
|
|
65
70
|
nullable: true,
|
|
66
71
|
readonly: true
|
|
67
72
|
})], Comment.prototype, "idempotencyKey", 2);
|
|
68
|
-
__decorateClass([field({
|
|
73
|
+
__decorateClass$2([field({
|
|
69
74
|
type: "text",
|
|
70
75
|
nullable: true,
|
|
71
76
|
readonly: true
|
|
72
77
|
})], Comment.prototype, "retryTenantId", 2);
|
|
73
|
-
__decorateClass([field({
|
|
78
|
+
__decorateClass$2([field({
|
|
74
79
|
type: "text",
|
|
75
80
|
nullable: true,
|
|
76
81
|
readonly: true
|
|
77
82
|
})], Comment.prototype, "requestDigest", 2);
|
|
78
|
-
|
|
83
|
+
__decorateClass$2([foreignKey("Comment", {
|
|
84
|
+
nullable: true,
|
|
85
|
+
constraint: false
|
|
86
|
+
})], Comment.prototype, "parentCommentId", 2);
|
|
87
|
+
__decorateClass$2([field({ required: true })], Comment.prototype, "status", 2);
|
|
88
|
+
__decorateClass$2([field({
|
|
89
|
+
type: "text",
|
|
90
|
+
nullable: true,
|
|
91
|
+
readonly: true
|
|
92
|
+
})], Comment.prototype, "participationSnapshot", 2);
|
|
93
|
+
__decorateClass$2([field({
|
|
94
|
+
type: "datetime",
|
|
95
|
+
nullable: true,
|
|
96
|
+
readonly: true
|
|
97
|
+
})], Comment.prototype, "editedAt", 2);
|
|
98
|
+
Comment = __decorateClass$2([TenantScoped({ mode: "required" }), smrt({
|
|
79
99
|
tableName: "record_comments",
|
|
80
100
|
api: false,
|
|
81
101
|
mcp: false,
|
|
82
102
|
cli: false,
|
|
83
|
-
indexes: [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
indexes: [
|
|
104
|
+
{
|
|
105
|
+
name: "record_comments_tenant_request_key",
|
|
106
|
+
columns: ["retryTenantId", "idempotencyKey"],
|
|
107
|
+
unique: true
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "record_comments_record_created_idx",
|
|
111
|
+
columns: [
|
|
112
|
+
"tenantId",
|
|
113
|
+
"metaType",
|
|
114
|
+
"metaId",
|
|
115
|
+
"createdAt"
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "record_comments_parent_created_idx",
|
|
120
|
+
columns: [
|
|
121
|
+
"tenantId",
|
|
122
|
+
"parentCommentId",
|
|
123
|
+
"createdAt"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "record_comments_moderation_idx",
|
|
128
|
+
columns: [
|
|
129
|
+
"tenantId",
|
|
130
|
+
"status",
|
|
131
|
+
"createdAt"
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
]
|
|
96
135
|
})], Comment);
|
|
97
136
|
//#endregion
|
|
98
137
|
//#region src/collections/CommentCollection.ts
|
|
@@ -112,6 +151,108 @@ var CommentCollection = class extends SmrtCollection {
|
|
|
112
151
|
}
|
|
113
152
|
};
|
|
114
153
|
//#endregion
|
|
154
|
+
//#region src/models/CommentReport.ts
|
|
155
|
+
var __defProp$1 = Object.defineProperty;
|
|
156
|
+
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
157
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
configurable: true,
|
|
160
|
+
writable: true,
|
|
161
|
+
value
|
|
162
|
+
}) : obj[key] = value;
|
|
163
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
164
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
165
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
166
|
+
if (kind && result) __defProp$1(target, key, result);
|
|
167
|
+
return result;
|
|
168
|
+
};
|
|
169
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
170
|
+
var CommentReport = class extends SmrtObject {
|
|
171
|
+
tenantId = "";
|
|
172
|
+
commentId = "";
|
|
173
|
+
reporterUserId = "";
|
|
174
|
+
reason = "";
|
|
175
|
+
status = "open";
|
|
176
|
+
};
|
|
177
|
+
__publicField$1(CommentReport, "__smrtPackage__", "@happyvertical/smrt-comments");
|
|
178
|
+
__decorateClass$1([tenantId()], CommentReport.prototype, "tenantId", 2);
|
|
179
|
+
__decorateClass$1([foreignKey("Comment", {
|
|
180
|
+
required: true,
|
|
181
|
+
constraint: false
|
|
182
|
+
})], CommentReport.prototype, "commentId", 2);
|
|
183
|
+
__decorateClass$1([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], CommentReport.prototype, "reporterUserId", 2);
|
|
184
|
+
__decorateClass$1([field({ required: true })], CommentReport.prototype, "reason", 2);
|
|
185
|
+
__decorateClass$1([field({ required: true })], CommentReport.prototype, "status", 2);
|
|
186
|
+
CommentReport = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
|
|
187
|
+
tableName: "comment_reports",
|
|
188
|
+
api: false,
|
|
189
|
+
mcp: false,
|
|
190
|
+
cli: false,
|
|
191
|
+
indexes: [{
|
|
192
|
+
name: "comment_reports_actor_target_unique",
|
|
193
|
+
columns: [
|
|
194
|
+
"tenantId",
|
|
195
|
+
"reporterUserId",
|
|
196
|
+
"commentId"
|
|
197
|
+
],
|
|
198
|
+
unique: true
|
|
199
|
+
}, {
|
|
200
|
+
name: "comment_reports_queue_idx",
|
|
201
|
+
columns: [
|
|
202
|
+
"tenantId",
|
|
203
|
+
"status",
|
|
204
|
+
"createdAt"
|
|
205
|
+
]
|
|
206
|
+
}]
|
|
207
|
+
})], CommentReport);
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/collections/CommentReportCollection.ts
|
|
210
|
+
var CommentReportCollection = class extends SmrtCollection {
|
|
211
|
+
static _itemClass = CommentReport;
|
|
212
|
+
};
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/models/CommentRevision.ts
|
|
215
|
+
var __defProp = Object.defineProperty;
|
|
216
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
217
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
|
|
218
|
+
enumerable: true,
|
|
219
|
+
configurable: true,
|
|
220
|
+
writable: true,
|
|
221
|
+
value
|
|
222
|
+
}) : obj[key] = value;
|
|
223
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
224
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
225
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
226
|
+
if (kind && result) __defProp(target, key, result);
|
|
227
|
+
return result;
|
|
228
|
+
};
|
|
229
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
230
|
+
var CommentRevision = class extends SmrtObject {
|
|
231
|
+
tenantId = "";
|
|
232
|
+
commentId = "";
|
|
233
|
+
editorUserId = "";
|
|
234
|
+
body = "";
|
|
235
|
+
};
|
|
236
|
+
__publicField(CommentRevision, "__smrtPackage__", "@happyvertical/smrt-comments");
|
|
237
|
+
__decorateClass([tenantId()], CommentRevision.prototype, "tenantId", 2);
|
|
238
|
+
__decorateClass([foreignKey("Comment", {
|
|
239
|
+
required: true,
|
|
240
|
+
constraint: false
|
|
241
|
+
})], CommentRevision.prototype, "commentId", 2);
|
|
242
|
+
__decorateClass([crossPackageRef("@happyvertical/smrt-users:User", { required: true })], CommentRevision.prototype, "editorUserId", 2);
|
|
243
|
+
__decorateClass([field({ required: true })], CommentRevision.prototype, "body", 2);
|
|
244
|
+
CommentRevision = __decorateClass([TenantScoped({ mode: "required" }), smrt({
|
|
245
|
+
tableName: "comment_revisions",
|
|
246
|
+
api: false,
|
|
247
|
+
mcp: false,
|
|
248
|
+
cli: false
|
|
249
|
+
})], CommentRevision);
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/collections/CommentRevisionCollection.ts
|
|
252
|
+
var CommentRevisionCollection = class extends SmrtCollection {
|
|
253
|
+
static _itemClass = CommentRevision;
|
|
254
|
+
};
|
|
255
|
+
//#endregion
|
|
115
256
|
//#region src/recipes.ts
|
|
116
257
|
var RecordCommentsRecipe = class extends SmrtRecipe {
|
|
117
258
|
static id = "comments.records";
|
|
@@ -127,7 +268,14 @@ var RecordCommentsRecipe = class extends SmrtRecipe {
|
|
|
127
268
|
label: "Comments",
|
|
128
269
|
summary: "Keep discussions alongside the records your team works on."
|
|
129
270
|
};
|
|
130
|
-
static models = [
|
|
271
|
+
static models = [
|
|
272
|
+
Comment,
|
|
273
|
+
CommentRevision,
|
|
274
|
+
CommentReport,
|
|
275
|
+
ParticipationPolicy,
|
|
276
|
+
ParticipationBan,
|
|
277
|
+
ParticipationRateBucket
|
|
278
|
+
];
|
|
131
279
|
static nav = [];
|
|
132
280
|
static runtime = "both";
|
|
133
281
|
static surfaces = [{
|
|
@@ -143,7 +291,7 @@ var RecordCommentsRecipe = class extends SmrtRecipe {
|
|
|
143
291
|
var canonicalUuid = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value) ? value.toLowerCase() : value;
|
|
144
292
|
var CommentIdempotencyError = class extends Error {
|
|
145
293
|
constructor(code) {
|
|
146
|
-
super(code === "COMMENT_REQUEST_CONFLICT" ? "Comment request key already used with different content." : "Comment request no longer has
|
|
294
|
+
super(code === "COMMENT_REQUEST_CONFLICT" ? "Comment request key already used with different content." : "Comment request no longer has a valid retained creation binding.");
|
|
147
295
|
this.code = code;
|
|
148
296
|
this.name = "CommentIdempotencyError";
|
|
149
297
|
}
|
|
@@ -163,6 +311,130 @@ var CommentService = class {
|
|
|
163
311
|
action
|
|
164
312
|
})) throw new Error("Comment record access denied.");
|
|
165
313
|
}
|
|
314
|
+
async getAuthorizedComment(commentId, action) {
|
|
315
|
+
const tenantId = this.options.actor.tenantId;
|
|
316
|
+
const comment = await withTenant({ tenantId }, async () => (await CommentCollection.create({ db: this.options.db })).get(commentId));
|
|
317
|
+
if (!comment || canonicalUuid(comment.tenantId) !== canonicalUuid(tenantId)) throw new Error("Comment not found.");
|
|
318
|
+
await this.authorize(comment.metaType, comment.metaId, action);
|
|
319
|
+
return comment;
|
|
320
|
+
}
|
|
321
|
+
/** Edits retain the exact former body before changing the visible comment. */
|
|
322
|
+
async edit(commentId, body) {
|
|
323
|
+
if (!body.trim()) throw new TypeError("Comment body is required.");
|
|
324
|
+
const comment = await this.getAuthorizedComment(commentId, "read");
|
|
325
|
+
if (canonicalUuid(comment.authorUserId) !== canonicalUuid(this.options.actor.userId)) throw new Error("Comment edit denied.");
|
|
326
|
+
await this.authorize(comment.metaType, comment.metaId, "comment");
|
|
327
|
+
const tenantId = this.options.actor.tenantId;
|
|
328
|
+
return withTenant({ tenantId }, async () => {
|
|
329
|
+
const collection = await CommentCollection.create({ db: this.options.db });
|
|
330
|
+
if (!collection.db.transaction) throw new Error("Comment edits require transactions.");
|
|
331
|
+
return collection.db.transaction(async (tx) => {
|
|
332
|
+
const scoped = await CommentCollection.create({ db: tx });
|
|
333
|
+
const table = `"${scoped.tableName.replace(/"/g, "\"\"")}"`;
|
|
334
|
+
await tx.query(`UPDATE ${table} SET body = body WHERE id = ? AND tenant_id = ?`, commentId, tenantId);
|
|
335
|
+
const current = await scoped.get(commentId);
|
|
336
|
+
if (!current || canonicalUuid(current.authorUserId) !== canonicalUuid(this.options.actor.userId)) throw new Error("Comment edit denied.");
|
|
337
|
+
return new ParticipationService({
|
|
338
|
+
db: tx,
|
|
339
|
+
entitlement: this.options.participation
|
|
340
|
+
}).executeInTransaction(tx, {
|
|
341
|
+
tenantId,
|
|
342
|
+
actorUserId: this.options.actor.userId,
|
|
343
|
+
action: "comment",
|
|
344
|
+
recordType: current.metaType,
|
|
345
|
+
recordId: current.metaId
|
|
346
|
+
}, async (guardedTx, decision) => withTenant({ tenantId: current.tenantId }, async () => {
|
|
347
|
+
await (await CommentRevisionCollection.create({ db: guardedTx })).create({
|
|
348
|
+
tenantId: current.tenantId,
|
|
349
|
+
commentId,
|
|
350
|
+
editorUserId: this.options.actor.userId,
|
|
351
|
+
body: current.body
|
|
352
|
+
});
|
|
353
|
+
if (current.status === "visible" && decision.initialCommentStatus === "pending") current.status = "pending";
|
|
354
|
+
current.body = body;
|
|
355
|
+
current.editedAt = /* @__PURE__ */ new Date();
|
|
356
|
+
await current.save();
|
|
357
|
+
return current;
|
|
358
|
+
}));
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
/** A moderator may make a row visible, hidden, pending, or deleted. */
|
|
363
|
+
async moderate(commentId, status) {
|
|
364
|
+
const comment = await this.getAuthorizedComment(commentId, "moderate");
|
|
365
|
+
if (![
|
|
366
|
+
"visible",
|
|
367
|
+
"hidden",
|
|
368
|
+
"pending",
|
|
369
|
+
"deleted"
|
|
370
|
+
].includes(status)) throw new TypeError("Invalid comment moderation status.");
|
|
371
|
+
return withTenant({ tenantId: comment.tenantId }, async () => {
|
|
372
|
+
const collection = await CommentCollection.create({ db: this.options.db });
|
|
373
|
+
if (!collection.db.transaction) throw new Error("Comment moderation requires transactions.");
|
|
374
|
+
return collection.db.transaction(async (tx) => {
|
|
375
|
+
const scoped = await CommentCollection.create({ db: tx });
|
|
376
|
+
const table = `"${scoped.tableName.replace(/"/g, "\"\"")}"`;
|
|
377
|
+
await tx.query(`UPDATE ${table} SET body = body WHERE id = ? AND tenant_id = ?`, commentId, comment.tenantId);
|
|
378
|
+
const current = await scoped.get(commentId);
|
|
379
|
+
if (!current) throw new Error("Comment not found.");
|
|
380
|
+
current.status = status;
|
|
381
|
+
await current.save();
|
|
382
|
+
return current;
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
/** One retained report per actor/comment; new reports consume shared report quota. */
|
|
387
|
+
async report(commentId, reason) {
|
|
388
|
+
if (!reason.trim()) throw new TypeError("Comment report reason is required.");
|
|
389
|
+
const comment = await this.getAuthorizedComment(commentId, "read");
|
|
390
|
+
if (comment.status !== "visible") throw new Error("Comment is not reportable.");
|
|
391
|
+
commentId = canonicalUuid(comment.id ?? commentId);
|
|
392
|
+
const tenantId = canonicalUuid(this.options.actor.tenantId);
|
|
393
|
+
const reporterUserId = canonicalUuid(this.options.actor.userId);
|
|
394
|
+
const request = {
|
|
395
|
+
tenantId,
|
|
396
|
+
actorUserId: reporterUserId,
|
|
397
|
+
action: "report",
|
|
398
|
+
recordType: comment.metaType,
|
|
399
|
+
recordId: comment.metaId
|
|
400
|
+
};
|
|
401
|
+
const guard = new ParticipationService({
|
|
402
|
+
db: this.options.db,
|
|
403
|
+
entitlement: this.options.participation
|
|
404
|
+
});
|
|
405
|
+
await guard.authorize(request);
|
|
406
|
+
return withTenant({ tenantId }, async () => {
|
|
407
|
+
const reports = await CommentReportCollection.create({ db: this.options.db });
|
|
408
|
+
const id = await runOnce({
|
|
409
|
+
db: reports.db,
|
|
410
|
+
tenantId,
|
|
411
|
+
actor: "smrt-comments.report:v1",
|
|
412
|
+
token: `${reporterUserId}:${canonicalUuid(commentId)}`,
|
|
413
|
+
content: "retained-report:v1"
|
|
414
|
+
}, async (tx) => {
|
|
415
|
+
const existing = await (await CommentReportCollection.create({ db: tx })).list({ where: {
|
|
416
|
+
tenantId,
|
|
417
|
+
reporterUserId,
|
|
418
|
+
commentId
|
|
419
|
+
} });
|
|
420
|
+
if (existing[0]) return existing[0].id;
|
|
421
|
+
return guard.executeInTransaction(tx, request, async (guardedTx) => {
|
|
422
|
+
const current = await withTenant({ tenantId: comment.tenantId }, async () => (await CommentCollection.create({ db: guardedTx })).get(commentId));
|
|
423
|
+
if (!current || current.status !== "visible") throw new Error("Comment is not reportable.");
|
|
424
|
+
return (await (await CommentReportCollection.create({ db: guardedTx })).create({
|
|
425
|
+
tenantId,
|
|
426
|
+
commentId,
|
|
427
|
+
reporterUserId,
|
|
428
|
+
reason: reason.trim(),
|
|
429
|
+
status: "open"
|
|
430
|
+
})).id;
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
const report = id ? await reports.get(id) : null;
|
|
434
|
+
if (!report || report.commentId !== canonicalUuid(commentId) || report.reporterUserId !== reporterUserId) throw new Error("Retained report unavailable.");
|
|
435
|
+
return report;
|
|
436
|
+
});
|
|
437
|
+
}
|
|
166
438
|
async listForRecord(recordType, recordId) {
|
|
167
439
|
await this.authorize(recordType, recordId, "read");
|
|
168
440
|
const tenantId = this.options.actor.tenantId;
|
|
@@ -187,12 +459,24 @@ var CommentService = class {
|
|
|
187
459
|
return row;
|
|
188
460
|
}
|
|
189
461
|
async create(commentOptions) {
|
|
190
|
-
const { tenantId: inputTenantId, authorUserId: inputAuthorUserId, metaType, metaId, body, mentions, idempotencyKey } = commentOptions;
|
|
462
|
+
const { tenantId: inputTenantId, authorUserId: inputAuthorUserId, metaType, metaId, body, mentions, idempotencyKey, parentCommentId: inputParentCommentId } = commentOptions;
|
|
463
|
+
const parentCommentId = inputParentCommentId ? canonicalUuid(inputParentCommentId) : inputParentCommentId;
|
|
191
464
|
if (!inputTenantId || !inputAuthorUserId) throw new TypeError("Comments require a tenant and author.");
|
|
192
465
|
if (canonicalUuid(inputTenantId) !== canonicalUuid(this.options.actor.tenantId) || canonicalUuid(inputAuthorUserId) !== canonicalUuid(this.options.actor.userId)) throw new Error("Comment actor context mismatch.");
|
|
193
466
|
const tenantId = this.options.actor.tenantId;
|
|
194
467
|
const authorUserId = this.options.actor.userId;
|
|
195
468
|
await this.authorize(metaType ?? "", metaId ?? "", "comment");
|
|
469
|
+
const participationRequest = {
|
|
470
|
+
tenantId,
|
|
471
|
+
actorUserId: authorUserId,
|
|
472
|
+
action: "comment",
|
|
473
|
+
recordType: metaType ?? "",
|
|
474
|
+
recordId: metaId ?? ""
|
|
475
|
+
};
|
|
476
|
+
await new ParticipationService({
|
|
477
|
+
db: this.options.db,
|
|
478
|
+
entitlement: this.options.participation
|
|
479
|
+
}).authorize(participationRequest);
|
|
196
480
|
if (!body?.trim()) throw new TypeError("Comment body is required.");
|
|
197
481
|
const prepared = new Comment();
|
|
198
482
|
if (mentions !== void 0) prepared.mentionUserIds = mentions;
|
|
@@ -204,27 +488,43 @@ var CommentService = class {
|
|
|
204
488
|
metaType,
|
|
205
489
|
metaId,
|
|
206
490
|
body,
|
|
207
|
-
mentions: normalizedMentions
|
|
491
|
+
mentions: normalizedMentions,
|
|
492
|
+
...parentCommentId ? { parentCommentId } : {}
|
|
208
493
|
});
|
|
209
494
|
const comment = await withTenant({ tenantId }, async () => {
|
|
210
495
|
const collection = await CommentCollection.create({ db: this.options.db });
|
|
211
|
-
const insert = async (target) => {
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
496
|
+
const insert = async (target, inTransaction = false) => {
|
|
497
|
+
const guard = new ParticipationService({
|
|
498
|
+
db: target.db,
|
|
499
|
+
entitlement: this.options.participation
|
|
500
|
+
});
|
|
501
|
+
const work = async (tx, participation) => withTenant({ tenantId }, async () => {
|
|
502
|
+
target = await CommentCollection.create({ db: tx });
|
|
503
|
+
if (parentCommentId) {
|
|
504
|
+
const parent = await target.get(parentCommentId);
|
|
505
|
+
if (!parent || canonicalUuid(parent.tenantId) !== canonicalUuid(tenantId) || parent.metaType !== metaType || parent.metaId !== metaId) throw new Error("Comment parent does not belong to this record.");
|
|
506
|
+
}
|
|
507
|
+
const id = crypto.randomUUID();
|
|
508
|
+
return target.create({
|
|
509
|
+
tenantId,
|
|
510
|
+
authorUserId,
|
|
511
|
+
metaType,
|
|
512
|
+
metaId,
|
|
513
|
+
body,
|
|
514
|
+
id,
|
|
515
|
+
slug: id,
|
|
516
|
+
context: "",
|
|
517
|
+
_insertOnly: true,
|
|
518
|
+
mentions: prepared.mentions,
|
|
519
|
+
idempotencyKey: idempotencyKey ?? null,
|
|
520
|
+
requestDigest: idempotencyKey === void 0 ? null : requestDigest,
|
|
521
|
+
retryTenantId: idempotencyKey === void 0 ? null : canonicalUuid(tenantId),
|
|
522
|
+
parentCommentId: parentCommentId ?? null,
|
|
523
|
+
status: participation.initialCommentStatus ?? "visible",
|
|
524
|
+
participationSnapshot: participation.snapshot ? JSON.stringify(participation.snapshot) : null
|
|
525
|
+
});
|
|
227
526
|
});
|
|
527
|
+
return inTransaction ? guard.executeInTransaction(target.db, participationRequest, work) : guard.execute(participationRequest, work);
|
|
228
528
|
};
|
|
229
529
|
if (idempotencyKey === void 0) return insert(collection);
|
|
230
530
|
const receipt = await runOnce({
|
|
@@ -237,7 +537,7 @@ var CommentService = class {
|
|
|
237
537
|
const scoped = await CommentCollection.create({ db: tx });
|
|
238
538
|
const matches = await tx.query(`SELECT CAST(id AS TEXT) AS id, CAST(tenant_id AS TEXT) AS tenant_id FROM "${scoped.tableName.replace(/"/g, "\"\"")}" WHERE retry_tenant_id = ? AND idempotency_key = ?`, canonicalUuid(tenantId), idempotencyKey);
|
|
239
539
|
if (matches.rows.length > 1) throw new CommentIdempotencyError("COMMENT_REQUEST_UNAVAILABLE");
|
|
240
|
-
const row2 = matches.rows[0] ? await this.loadBoundComment(tx, matches.rows[0], canonicalUuid(tenantId)) : await insert(scoped);
|
|
540
|
+
const row2 = matches.rows[0] ? await this.loadBoundComment(tx, matches.rows[0], canonicalUuid(tenantId)) : await insert(scoped, true);
|
|
241
541
|
return {
|
|
242
542
|
id: row2.id,
|
|
243
543
|
digest: row2.requestDigest,
|
|
@@ -246,17 +546,22 @@ var CommentService = class {
|
|
|
246
546
|
});
|
|
247
547
|
if (receipt.digest !== requestDigest) throw new CommentIdempotencyError("COMMENT_REQUEST_CONFLICT");
|
|
248
548
|
const row = await this.loadBoundComment(collection.db, receipt, canonicalUuid(tenantId));
|
|
249
|
-
|
|
549
|
+
const retainedBodies = row.editedAt ? await withTenant({ tenantId: row.tenantId }, async () => (await (await CommentRevisionCollection.create({ db: collection.db })).list({ where: {
|
|
550
|
+
commentId: row.id,
|
|
551
|
+
tenantId: row.tenantId
|
|
552
|
+
} })).map((revision) => revision.body)) : [row.body];
|
|
553
|
+
if (canonicalUuid(row.tenantId) !== canonicalUuid(tenantId) || row.idempotencyKey !== idempotencyKey || row.requestDigest !== requestDigest || !retainedBodies.some((retainedBody) => digestRunOnceContent({
|
|
250
554
|
tenantId: canonicalUuid(row.tenantId),
|
|
251
555
|
authorUserId: canonicalUuid(row.authorUserId),
|
|
252
556
|
metaType: row.metaType,
|
|
253
557
|
metaId: row.metaId,
|
|
254
|
-
body:
|
|
255
|
-
mentions: [...row.mentionUserIds].sort()
|
|
256
|
-
|
|
558
|
+
body: retainedBody,
|
|
559
|
+
mentions: [...row.mentionUserIds].sort(),
|
|
560
|
+
...row.parentCommentId ? { parentCommentId: canonicalUuid(row.parentCommentId) } : {}
|
|
561
|
+
}) === requestDigest)) throw new CommentIdempotencyError("COMMENT_REQUEST_UNAVAILABLE");
|
|
257
562
|
return row;
|
|
258
563
|
});
|
|
259
|
-
if (!this.options.mentionNotifications || !comment.id) return comment;
|
|
564
|
+
if (!this.options.mentionNotifications || !comment.id || comment.status !== "visible") return comment;
|
|
260
565
|
for (const recipientUserId of comment.mentionUserIds) {
|
|
261
566
|
if (canonicalUuid(recipientUserId) === canonicalUuid(comment.authorUserId)) continue;
|
|
262
567
|
await this.options.mentionNotifications.notifyMention({
|
|
@@ -288,6 +593,6 @@ function createCommentMentionNotifications(options) {
|
|
|
288
593
|
} };
|
|
289
594
|
}
|
|
290
595
|
//#endregion
|
|
291
|
-
export { Comment, CommentCollection, CommentIdempotencyError, CommentService, RecordCommentsRecipe, createCommentMentionNotifications };
|
|
596
|
+
export { Comment, CommentCollection, CommentIdempotencyError, CommentReport, CommentReportCollection, CommentRevision, CommentRevisionCollection, CommentService, ParticipationBan, ParticipationBanCollection, ParticipationDeniedError, ParticipationPolicy, ParticipationPolicyCollection, ParticipationRateBucket, ParticipationRateBucketCollection, ParticipationService, RecordCommentsRecipe, createCommentMentionNotifications };
|
|
292
597
|
|
|
293
598
|
//# sourceMappingURL=index.js.map
|