@atproto/api 0.20.23 → 0.20.26

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 (74) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/agent.d.ts +4 -0
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +17 -0
  5. package/dist/agent.js.map +1 -1
  6. package/dist/client/lexicons.d.ts +8 -0
  7. package/dist/client/lexicons.d.ts.map +1 -1
  8. package/dist/client/lexicons.js +4 -0
  9. package/dist/client/lexicons.js.map +1 -1
  10. package/dist/client/types/app/bsky/actor/defs.d.ts +2 -0
  11. package/dist/client/types/app/bsky/actor/defs.d.ts.map +1 -1
  12. package/dist/client/types/app/bsky/actor/defs.js.map +1 -1
  13. package/dist/rich-text/detection.d.ts.map +1 -1
  14. package/dist/rich-text/detection.js +4 -1
  15. package/dist/rich-text/detection.js.map +1 -1
  16. package/dist/types.d.ts +1 -0
  17. package/dist/types.d.ts.map +1 -1
  18. package/dist/types.js.map +1 -1
  19. package/package.json +22 -16
  20. package/definitions/labels.json +0 -170
  21. package/docs/moderation.md +0 -260
  22. package/jest.config.cjs +0 -23
  23. package/jest.d.ts +0 -20
  24. package/jest.setup.ts +0 -97
  25. package/scripts/code/labels.mjs +0 -77
  26. package/scripts/generate-code.mjs +0 -4
  27. package/src/age-assurance.test.ts +0 -218
  28. package/src/age-assurance.ts +0 -137
  29. package/src/agent.ts +0 -1645
  30. package/src/atp-agent.ts +0 -570
  31. package/src/bsky-agent.ts +0 -14
  32. package/src/const.ts +0 -1
  33. package/src/index.ts +0 -44
  34. package/src/mocker.ts +0 -220
  35. package/src/moderation/decision.ts +0 -389
  36. package/src/moderation/index.ts +0 -69
  37. package/src/moderation/mutewords.ts +0 -170
  38. package/src/moderation/subjects/account.ts +0 -44
  39. package/src/moderation/subjects/feed-generator.ts +0 -24
  40. package/src/moderation/subjects/notification.ts +0 -25
  41. package/src/moderation/subjects/post.ts +0 -433
  42. package/src/moderation/subjects/profile.ts +0 -26
  43. package/src/moderation/subjects/status.ts +0 -27
  44. package/src/moderation/subjects/user-list.ts +0 -48
  45. package/src/moderation/types.ts +0 -191
  46. package/src/moderation/ui.ts +0 -21
  47. package/src/moderation/util.ts +0 -111
  48. package/src/predicate.ts +0 -52
  49. package/src/rich-text/detection.ts +0 -146
  50. package/src/rich-text/rich-text.ts +0 -418
  51. package/src/rich-text/sanitization.ts +0 -42
  52. package/src/rich-text/unicode.ts +0 -47
  53. package/src/rich-text/util.ts +0 -15
  54. package/src/session-manager.ts +0 -5
  55. package/src/types.ts +0 -165
  56. package/src/util.ts +0 -96
  57. package/tests/atp-agent.test.ts +0 -3863
  58. package/tests/dispatcher.test.ts +0 -527
  59. package/tests/errors.test.ts +0 -29
  60. package/tests/moderation-behaviors.test.ts +0 -951
  61. package/tests/moderation-custom-labels.test.ts +0 -334
  62. package/tests/moderation-mutewords.test.ts +0 -1299
  63. package/tests/moderation-prefs.test.ts +0 -402
  64. package/tests/moderation-quoteposts.test.ts +0 -277
  65. package/tests/moderation.test.ts +0 -739
  66. package/tests/rich-text-detection.test.ts +0 -456
  67. package/tests/rich-text-sanitization.test.ts +0 -216
  68. package/tests/rich-text.test.ts +0 -705
  69. package/tests/util/echo-server.ts +0 -37
  70. package/tests/util/moderation-behavior.ts +0 -268
  71. package/tsconfig.build.json +0 -9
  72. package/tsconfig.build.tsbuildinfo +0 -1
  73. package/tsconfig.json +0 -7
  74. package/tsconfig.tests.json +0 -10
@@ -1,402 +0,0 @@
1
- import { TestNetworkNoAppView } from '@atproto/dev-env'
2
- import { isContentLabelPref } from '../src/client/types/app/bsky/actor/defs.js'
3
- import { DEFAULT_LABEL_SETTINGS } from '../src/index.js'
4
- import './util/moderation-behavior.js'
5
-
6
- describe('agent', () => {
7
- let network: TestNetworkNoAppView
8
-
9
- beforeAll(async () => {
10
- network = await TestNetworkNoAppView.create({
11
- dbPostgresSchema: 'api_moderation_prefs',
12
- })
13
- })
14
-
15
- afterAll(async () => {
16
- await network?.close()
17
- })
18
-
19
- it('migrates legacy content-label prefs (no mutations)', async () => {
20
- const agent = network.pds.getAgent()
21
-
22
- await agent.createAccount({
23
- handle: 'user1.test',
24
- email: 'user1@test.com',
25
- password: 'password',
26
- })
27
-
28
- await agent.app.bsky.actor.putPreferences({
29
- preferences: [
30
- {
31
- $type: 'app.bsky.actor.defs#contentLabelPref',
32
- label: 'porn',
33
- visibility: 'show',
34
- },
35
- {
36
- $type: 'app.bsky.actor.defs#contentLabelPref',
37
- label: 'nudity',
38
- visibility: 'show',
39
- },
40
- {
41
- $type: 'app.bsky.actor.defs#contentLabelPref',
42
- label: 'sexual',
43
- visibility: 'show',
44
- },
45
- {
46
- $type: 'app.bsky.actor.defs#contentLabelPref',
47
- label: 'graphic-media',
48
- visibility: 'show',
49
- },
50
- ],
51
- })
52
- await expect(agent.getPreferences()).resolves.toStrictEqual({
53
- feeds: {
54
- pinned: undefined,
55
- saved: undefined,
56
- },
57
- savedFeeds: expect.any(Array),
58
- interests: { tags: [] },
59
- moderationPrefs: {
60
- adultContentEnabled: false,
61
- labels: {
62
- porn: 'ignore',
63
- nudity: 'ignore',
64
- sexual: 'ignore',
65
- 'graphic-media': 'ignore',
66
- },
67
- labelers: [...agent.appLabelers.map((did) => ({ did, labels: {} }))],
68
- hiddenPosts: [],
69
- mutedWords: [],
70
- },
71
- birthDate: undefined,
72
- feedViewPrefs: {
73
- home: {
74
- hideQuotePosts: false,
75
- hideReplies: false,
76
- hideRepliesByLikeCount: 0,
77
- hideRepliesByUnfollowed: true,
78
- hideReposts: false,
79
- },
80
- },
81
- threadViewPrefs: {
82
- sort: 'hotness',
83
- },
84
- bskyAppState: {
85
- activeProgressGuide: undefined,
86
- queuedNudges: [],
87
- nuxs: [],
88
- },
89
- postInteractionSettings: {
90
- threadgateAllowRules: undefined,
91
- postgateEmbeddingRules: undefined,
92
- },
93
- verificationPrefs: {
94
- hideBadges: false,
95
- },
96
- liveEventPreferences: {
97
- hiddenFeedIds: [],
98
- hideAllFeeds: false,
99
- },
100
- })
101
- })
102
-
103
- it('adds/removes moderation services', async () => {
104
- const agent = network.pds.getAgent()
105
-
106
- await agent.createAccount({
107
- handle: 'user5.test',
108
- email: 'user5@test.com',
109
- password: 'password',
110
- })
111
-
112
- await agent.addLabeler('did:plc:other')
113
- expect(agent.labelers).toStrictEqual(['did:plc:other'])
114
- await expect(agent.getPreferences()).resolves.toStrictEqual({
115
- feeds: { pinned: undefined, saved: undefined },
116
- savedFeeds: expect.any(Array),
117
- interests: { tags: [] },
118
- moderationPrefs: {
119
- adultContentEnabled: false,
120
- labels: DEFAULT_LABEL_SETTINGS,
121
- labelers: [
122
- ...agent.appLabelers.map((did) => ({ did, labels: {} })),
123
- {
124
- did: 'did:plc:other',
125
- labels: {},
126
- },
127
- ],
128
- hiddenPosts: [],
129
- mutedWords: [],
130
- },
131
- birthDate: undefined,
132
- feedViewPrefs: {
133
- home: {
134
- hideReplies: false,
135
- hideRepliesByUnfollowed: true,
136
- hideRepliesByLikeCount: 0,
137
- hideReposts: false,
138
- hideQuotePosts: false,
139
- },
140
- },
141
- threadViewPrefs: {
142
- sort: 'hotness',
143
- },
144
- bskyAppState: {
145
- activeProgressGuide: undefined,
146
- queuedNudges: [],
147
- nuxs: [],
148
- },
149
- postInteractionSettings: {
150
- threadgateAllowRules: undefined,
151
- postgateEmbeddingRules: undefined,
152
- },
153
- verificationPrefs: {
154
- hideBadges: false,
155
- },
156
- liveEventPreferences: {
157
- hiddenFeedIds: [],
158
- hideAllFeeds: false,
159
- },
160
- })
161
- expect(agent.labelers).toStrictEqual(['did:plc:other'])
162
-
163
- await agent.removeLabeler('did:plc:other')
164
- expect(agent.labelers).toStrictEqual([])
165
- await expect(agent.getPreferences()).resolves.toStrictEqual({
166
- feeds: { pinned: undefined, saved: undefined },
167
- savedFeeds: expect.any(Array),
168
- interests: { tags: [] },
169
- moderationPrefs: {
170
- adultContentEnabled: false,
171
- labels: DEFAULT_LABEL_SETTINGS,
172
- labelers: [...agent.appLabelers.map((did) => ({ did, labels: {} }))],
173
- hiddenPosts: [],
174
- mutedWords: [],
175
- },
176
- birthDate: undefined,
177
- feedViewPrefs: {
178
- home: {
179
- hideReplies: false,
180
- hideRepliesByUnfollowed: true,
181
- hideRepliesByLikeCount: 0,
182
- hideReposts: false,
183
- hideQuotePosts: false,
184
- },
185
- },
186
- threadViewPrefs: {
187
- sort: 'hotness',
188
- },
189
- bskyAppState: {
190
- activeProgressGuide: undefined,
191
- queuedNudges: [],
192
- nuxs: [],
193
- },
194
- postInteractionSettings: {
195
- threadgateAllowRules: undefined,
196
- postgateEmbeddingRules: undefined,
197
- },
198
- verificationPrefs: {
199
- hideBadges: false,
200
- },
201
- liveEventPreferences: {
202
- hiddenFeedIds: [],
203
- hideAllFeeds: false,
204
- },
205
- })
206
- expect(agent.labelers).toStrictEqual([])
207
- })
208
-
209
- it('sets label preferences globally and per-moderator', async () => {
210
- const agent = network.pds.getAgent()
211
-
212
- await agent.createAccount({
213
- handle: 'user7.test',
214
- email: 'user7@test.com',
215
- password: 'password',
216
- })
217
-
218
- await agent.addLabeler('did:plc:other')
219
- await agent.setContentLabelPref('porn', 'ignore')
220
- await agent.setContentLabelPref('porn', 'hide', 'did:plc:other')
221
- await agent.setContentLabelPref('x-custom', 'warn', 'did:plc:other')
222
-
223
- await expect(agent.getPreferences()).resolves.toStrictEqual({
224
- feeds: { pinned: undefined, saved: undefined },
225
- savedFeeds: expect.any(Array),
226
- interests: { tags: [] },
227
- moderationPrefs: {
228
- adultContentEnabled: false,
229
- labels: { ...DEFAULT_LABEL_SETTINGS, porn: 'ignore', nsfw: 'ignore' },
230
- labelers: [
231
- ...agent.appLabelers.map((did) => ({ did, labels: {} })),
232
- {
233
- did: 'did:plc:other',
234
- labels: {
235
- porn: 'hide',
236
- 'x-custom': 'warn',
237
- },
238
- },
239
- ],
240
- hiddenPosts: [],
241
- mutedWords: [],
242
- },
243
- birthDate: undefined,
244
- feedViewPrefs: {
245
- home: {
246
- hideReplies: false,
247
- hideRepliesByUnfollowed: true,
248
- hideRepliesByLikeCount: 0,
249
- hideReposts: false,
250
- hideQuotePosts: false,
251
- },
252
- },
253
- threadViewPrefs: {
254
- sort: 'hotness',
255
- },
256
- bskyAppState: {
257
- activeProgressGuide: undefined,
258
- queuedNudges: [],
259
- nuxs: [],
260
- },
261
- postInteractionSettings: {
262
- threadgateAllowRules: undefined,
263
- postgateEmbeddingRules: undefined,
264
- },
265
- verificationPrefs: {
266
- hideBadges: false,
267
- },
268
- liveEventPreferences: {
269
- hiddenFeedIds: [],
270
- hideAllFeeds: false,
271
- },
272
- })
273
- })
274
-
275
- it(`updates label pref`, async () => {
276
- const agent = network.pds.getAgent()
277
-
278
- await agent.createAccount({
279
- handle: 'user8.test',
280
- email: 'user8@test.com',
281
- password: 'password',
282
- })
283
-
284
- await agent.addLabeler('did:plc:other')
285
- await agent.setContentLabelPref('porn', 'ignore')
286
- await agent.setContentLabelPref('porn', 'ignore', 'did:plc:other')
287
- await agent.setContentLabelPref('porn', 'hide')
288
- await agent.setContentLabelPref('porn', 'hide', 'did:plc:other')
289
-
290
- const { moderationPrefs } = await agent.getPreferences()
291
- const labeler = moderationPrefs.labelers.find(
292
- (l) => l.did === 'did:plc:other',
293
- )
294
-
295
- expect(moderationPrefs.labels.porn).toEqual('hide')
296
- expect(labeler?.labels?.porn).toEqual('hide')
297
- })
298
-
299
- it(`double-write for legacy: 'graphic-media' in sync with 'gore'`, async () => {
300
- const agent = network.pds.getAgent()
301
-
302
- await agent.createAccount({
303
- handle: 'user9.test',
304
- email: 'user9@test.com',
305
- password: 'password',
306
- })
307
-
308
- await agent.setContentLabelPref('graphic-media', 'hide')
309
- const a = await agent.getPreferences()
310
-
311
- expect(a.moderationPrefs.labels.gore).toEqual('hide')
312
- expect(a.moderationPrefs.labels['graphic-media']).toEqual('hide')
313
-
314
- await agent.setContentLabelPref('graphic-media', 'warn')
315
- const b = await agent.getPreferences()
316
-
317
- expect(b.moderationPrefs.labels.gore).toEqual('warn')
318
- expect(b.moderationPrefs.labels['graphic-media']).toEqual('warn')
319
- })
320
-
321
- it(`double-write for legacy: 'porn' in sync with 'nsfw'`, async () => {
322
- const agent = network.pds.getAgent()
323
-
324
- await agent.createAccount({
325
- handle: 'user10.test',
326
- email: 'user10@test.com',
327
- password: 'password',
328
- })
329
-
330
- await agent.setContentLabelPref('porn', 'hide')
331
- const a = await agent.getPreferences()
332
-
333
- expect(a.moderationPrefs.labels.nsfw).toEqual('hide')
334
- expect(a.moderationPrefs.labels.porn).toEqual('hide')
335
-
336
- await agent.setContentLabelPref('porn', 'warn')
337
- const b = await agent.getPreferences()
338
-
339
- expect(b.moderationPrefs.labels.nsfw).toEqual('warn')
340
- expect(b.moderationPrefs.labels.porn).toEqual('warn')
341
- })
342
-
343
- it(`double-write for legacy: 'sexual' in sync with 'suggestive'`, async () => {
344
- const agent = network.pds.getAgent()
345
-
346
- await agent.createAccount({
347
- handle: 'user11.test',
348
- email: 'user11@test.com',
349
- password: 'password',
350
- })
351
-
352
- await agent.setContentLabelPref('sexual', 'hide')
353
- const a = await agent.getPreferences()
354
-
355
- expect(a.moderationPrefs.labels.sexual).toEqual('hide')
356
- expect(a.moderationPrefs.labels.suggestive).toEqual('hide')
357
-
358
- await agent.setContentLabelPref('sexual', 'warn')
359
- const b = await agent.getPreferences()
360
-
361
- expect(b.moderationPrefs.labels.sexual).toEqual('warn')
362
- expect(b.moderationPrefs.labels.suggestive).toEqual('warn')
363
- })
364
-
365
- it(`double-write for legacy: filters out existing old label pref if double-written`, async () => {
366
- const agent = network.pds.getAgent()
367
-
368
- await agent.createAccount({
369
- handle: 'user12.test',
370
- email: 'user12@test.com',
371
- password: 'password',
372
- })
373
-
374
- await agent.setContentLabelPref('nsfw', 'hide')
375
- await agent.setContentLabelPref('porn', 'hide')
376
- const a = await agent.app.bsky.actor.getPreferences({})
377
-
378
- const nsfwSettings = a.data.preferences.filter(
379
- (pref) => isContentLabelPref(pref) && pref.label === 'nsfw',
380
- )
381
- expect(nsfwSettings.length).toEqual(1)
382
- })
383
-
384
- it(`remaps old values to new on read`, async () => {
385
- const agent = network.pds.getAgent()
386
-
387
- await agent.createAccount({
388
- handle: 'user13.test',
389
- email: 'user13@test.com',
390
- password: 'password',
391
- })
392
-
393
- await agent.setContentLabelPref('nsfw', 'hide')
394
- await agent.setContentLabelPref('gore', 'hide')
395
- await agent.setContentLabelPref('suggestive', 'hide')
396
- const a = await agent.getPreferences()
397
-
398
- expect(a.moderationPrefs.labels.porn).toEqual('hide')
399
- expect(a.moderationPrefs.labels['graphic-media']).toEqual('hide')
400
- expect(a.moderationPrefs.labels['sexual']).toEqual('hide')
401
- })
402
- })
@@ -1,277 +0,0 @@
1
- import {
2
- InterpretedLabelValueDefinition,
3
- ModerationOpts,
4
- interpretLabelValueDefinition,
5
- mock,
6
- moderatePost,
7
- } from '../src/index.js'
8
- import './util/moderation-behavior.js'
9
-
10
- interface ScenarioResult {
11
- profileList?: string[]
12
- profileView?: string[]
13
- avatar?: string[]
14
- banner?: string[]
15
- displayName?: string[]
16
- contentList?: string[]
17
- contentView?: string[]
18
- contentMedia?: string[]
19
- }
20
-
21
- interface Scenario {
22
- blurs: 'content' | 'media' | 'none'
23
- severity: 'alert' | 'inform' | 'none'
24
- account: ScenarioResult
25
- profile: ScenarioResult
26
- post: ScenarioResult
27
- }
28
-
29
- const TESTS: Scenario[] = [
30
- {
31
- blurs: 'content',
32
- severity: 'alert',
33
- account: {
34
- profileList: ['filter'],
35
- contentList: ['filter'],
36
- },
37
- profile: {},
38
- post: {
39
- contentList: ['filter'],
40
- },
41
- },
42
- {
43
- blurs: 'content',
44
- severity: 'inform',
45
- account: {
46
- profileList: ['filter'],
47
- contentList: ['filter'],
48
- },
49
- profile: {},
50
- post: {
51
- contentList: ['filter'],
52
- },
53
- },
54
- {
55
- blurs: 'content',
56
- severity: 'none',
57
- account: {
58
- profileList: ['filter'],
59
- contentList: ['filter'],
60
- },
61
- profile: {},
62
- post: {
63
- contentList: ['filter'],
64
- },
65
- },
66
-
67
- {
68
- blurs: 'media',
69
- severity: 'alert',
70
- account: {
71
- profileList: ['filter'],
72
- contentList: ['filter'],
73
- },
74
- profile: {},
75
- post: {
76
- contentList: ['filter'],
77
- },
78
- },
79
- {
80
- blurs: 'media',
81
- severity: 'inform',
82
- account: {
83
- profileList: ['filter'],
84
- contentList: ['filter'],
85
- },
86
- profile: {},
87
- post: {
88
- contentList: ['filter'],
89
- },
90
- },
91
- {
92
- blurs: 'media',
93
- severity: 'none',
94
- account: {
95
- profileList: ['filter'],
96
- contentList: ['filter'],
97
- },
98
- profile: {},
99
- post: {
100
- contentList: ['filter'],
101
- },
102
- },
103
-
104
- {
105
- blurs: 'none',
106
- severity: 'alert',
107
- account: {
108
- profileList: ['filter'],
109
- contentList: ['filter'],
110
- },
111
- profile: {},
112
- post: {
113
- contentList: ['filter'],
114
- },
115
- },
116
- {
117
- blurs: 'none',
118
- severity: 'inform',
119
- account: {
120
- profileList: ['filter'],
121
- contentList: ['filter'],
122
- },
123
- profile: {},
124
- post: {
125
- contentList: ['filter'],
126
- },
127
- },
128
- {
129
- blurs: 'none',
130
- severity: 'none',
131
- account: {
132
- profileList: ['filter'],
133
- contentList: ['filter'],
134
- },
135
- profile: {},
136
- post: {
137
- contentList: ['filter'],
138
- },
139
- },
140
- ]
141
-
142
- describe('Moderation: custom labels', () => {
143
- const scenarios = TESTS.flatMap((test) => [
144
- {
145
- blurs: test.blurs,
146
- severity: test.severity,
147
- target: 'post',
148
- expected: test.post,
149
- },
150
- {
151
- blurs: test.blurs,
152
- severity: test.severity,
153
- target: 'profile',
154
- expected: test.profile,
155
- },
156
- {
157
- blurs: test.blurs,
158
- severity: test.severity,
159
- target: 'account',
160
- expected: test.account,
161
- },
162
- ])
163
- it.each(scenarios)(
164
- 'blurs=$blurs, severity=$severity, target=$target',
165
- ({ blurs, severity, target, expected }) => {
166
- let postLabels
167
- let profileLabels
168
- if (target === 'post') {
169
- postLabels = [
170
- mock.label({
171
- val: 'custom',
172
- uri: 'at://did:web:carla.test/app.bsky.feed.post/fake',
173
- src: 'did:web:labeler.test',
174
- }),
175
- ]
176
- } else if (target === 'profile') {
177
- profileLabels = [
178
- mock.label({
179
- val: 'custom',
180
- uri: 'at://did:web:carla.test/app.bsky.actor.profile/self',
181
- src: 'did:web:labeler.test',
182
- }),
183
- ]
184
- } else {
185
- profileLabels = [
186
- mock.label({
187
- val: 'custom',
188
- uri: 'did:web:carla.test',
189
- src: 'did:web:labeler.test',
190
- }),
191
- ]
192
- }
193
-
194
- const post = mock.postView({
195
- record: {
196
- $type: 'app.bsky.feed.post',
197
- text: 'Hello',
198
- createdAt: new Date().toISOString(),
199
- },
200
- embed: mock.embedRecordView({
201
- record: mock.post({
202
- text: 'Quoted post text',
203
- }),
204
- labels: postLabels,
205
- author: mock.profileViewBasic({
206
- handle: 'carla.test',
207
- displayName: 'Carla',
208
- labels: profileLabels,
209
- }),
210
- }),
211
- author: mock.profileViewBasic({
212
- handle: 'bob.test',
213
- displayName: 'Bob',
214
- }),
215
- })
216
- const res = moderatePost(post, modOpts(blurs, severity))
217
-
218
- expect(res.ui('profileList')).toBeModerationResult(
219
- expected.profileList || [],
220
- )
221
- expect(res.ui('profileView')).toBeModerationResult(
222
- expected.profileView || [],
223
- )
224
- expect(res.ui('avatar')).toBeModerationResult(expected.avatar || [])
225
- expect(res.ui('banner')).toBeModerationResult(expected.banner || [])
226
- expect(res.ui('displayName')).toBeModerationResult(
227
- expected.displayName || [],
228
- )
229
- expect(res.ui('contentList')).toBeModerationResult(
230
- expected.contentList || [],
231
- )
232
- expect(res.ui('contentView')).toBeModerationResult(
233
- expected.contentView || [],
234
- )
235
- expect(res.ui('contentMedia')).toBeModerationResult(
236
- expected.contentMedia || [],
237
- )
238
- },
239
- )
240
- })
241
-
242
- function modOpts(blurs: string, severity: string): ModerationOpts {
243
- return {
244
- userDid: 'did:web:alice.test',
245
- prefs: {
246
- adultContentEnabled: true,
247
- labels: {},
248
- labelers: [
249
- {
250
- did: 'did:web:labeler.test',
251
- labels: { custom: 'hide' },
252
- },
253
- ],
254
- mutedWords: [],
255
- hiddenPosts: [],
256
- },
257
- labelDefs: {
258
- 'did:web:labeler.test': [makeCustomLabel(blurs, severity)],
259
- },
260
- }
261
- }
262
-
263
- function makeCustomLabel(
264
- blurs: string,
265
- severity: string,
266
- ): InterpretedLabelValueDefinition {
267
- return interpretLabelValueDefinition(
268
- {
269
- identifier: 'custom',
270
- blurs,
271
- severity,
272
- defaultSetting: 'warn',
273
- locales: [],
274
- },
275
- 'did:web:labeler.test',
276
- )
277
- }