@atproto/api 0.5.4 → 0.6.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.
@@ -37,7 +37,7 @@ interface Labeler {
37
37
  }
38
38
  export interface LabelerSettings {
39
39
  labeler: Labeler;
40
- settings: Record<string, LabelPreference>;
40
+ labels: Record<string, LabelPreference>;
41
41
  }
42
42
  export declare type ModerationSubjectProfile = AppBskyActorDefs.ProfileViewBasic | AppBskyActorDefs.ProfileView | AppBskyActorDefs.ProfileViewDetailed;
43
43
  export declare type ModerationSubjectPost = AppBskyFeedDefs.PostView;
@@ -49,6 +49,9 @@ export declare type ModerationCauseSource = {
49
49
  } | {
50
50
  type: 'list';
51
51
  list: AppBskyGraphDefs.ListViewBasic;
52
+ } | {
53
+ type: 'labeler';
54
+ labeler: Labeler;
52
55
  };
53
56
  export declare type ModerationCause = {
54
57
  type: 'blocking';
@@ -60,7 +63,7 @@ export declare type ModerationCause = {
60
63
  priority: 4;
61
64
  } | {
62
65
  type: 'label';
63
- labeler: Labeler;
66
+ source: ModerationCauseSource;
64
67
  label: Label;
65
68
  labelDef: LabelDefinition;
66
69
  setting: LabelPreference;
@@ -73,7 +76,8 @@ export declare type ModerationCause = {
73
76
  export interface ModerationOpts {
74
77
  userDid: string;
75
78
  adultContentEnabled: boolean;
76
- labelerSettings: LabelerSettings[];
79
+ labels: Record<string, LabelPreference>;
80
+ labelers: LabelerSettings[];
77
81
  }
78
82
  export declare class ModerationDecision {
79
83
  cause: ModerationCause | undefined;
@@ -26,14 +26,22 @@ Every moderation function takes a set of options which look like this:
26
26
  // is adult content allowed?
27
27
  adultContentEnabled: true,
28
28
 
29
- // the user's labeler settings
30
- labelerSettings: [
29
+ // the global label settings (used on self-labels)
30
+ labels: {
31
+ porn: 'hide',
32
+ sexual: 'warn',
33
+ nudity: 'ignore',
34
+ // ...
35
+ },
36
+
37
+ // the per-labeler settings
38
+ labelers: [
31
39
  {
32
40
  labeler: {
33
41
  did: '...',
34
42
  displayName: 'My mod service'
35
43
  },
36
- settings: {
44
+ labels: {
37
45
  porn: 'hide',
38
46
  sexual: 'warn',
39
47
  nudity: 'ignore',
@@ -50,7 +58,8 @@ This should match the following interfaces:
50
58
  interface ModerationOpts {
51
59
  userDid: string
52
60
  adultContentEnabled: boolean
53
- labelerSettings: LabelerSettings[]
61
+ labels: Record<string, LabelPreference>
62
+ labelers: LabelerSettings[]
54
63
  }
55
64
 
56
65
  interface Labeler {
@@ -62,7 +71,7 @@ type LabelPreference = 'ignore' | 'warn' | 'hide'
62
71
 
63
72
  interface LabelerSettings {
64
73
  labeler: Labeler
65
- settings: Record<string, LabelPreference>
74
+ labels: Record<string, LabelPreference>
66
75
  }
67
76
  ```
68
77
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/api",
3
- "version": "0.5.4",
3
+ "version": "0.6.0",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
6
  "codegen": "yarn docgen && node ./scripts/generate-code.mjs && lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
@@ -1441,6 +1441,36 @@ export const schemaDict = {
1441
1441
  },
1442
1442
  },
1443
1443
  },
1444
+ selfLabels: {
1445
+ type: 'object',
1446
+ description:
1447
+ 'Metadata tags on an atproto record, published by the author within the record.',
1448
+ required: ['values'],
1449
+ properties: {
1450
+ values: {
1451
+ type: 'array',
1452
+ items: {
1453
+ type: 'ref',
1454
+ ref: 'lex:com.atproto.label.defs#selfLabel',
1455
+ },
1456
+ maxLength: 10,
1457
+ },
1458
+ },
1459
+ },
1460
+ selfLabel: {
1461
+ type: 'object',
1462
+ description:
1463
+ 'Metadata tag on an atproto record, published by the author within the record. Note -- schemas should use #selfLabels, not #selfLabel.',
1464
+ required: ['val'],
1465
+ properties: {
1466
+ val: {
1467
+ type: 'string',
1468
+ maxLength: 128,
1469
+ description:
1470
+ 'the short string name of the value or type of this label',
1471
+ },
1472
+ },
1473
+ },
1444
1474
  },
1445
1475
  },
1446
1476
  ComAtprotoLabelQueryLabels: {
@@ -3925,6 +3955,10 @@ export const schemaDict = {
3925
3955
  accept: ['image/png', 'image/jpeg'],
3926
3956
  maxSize: 1000000,
3927
3957
  },
3958
+ labels: {
3959
+ type: 'union',
3960
+ refs: ['lex:com.atproto.label.defs#selfLabels'],
3961
+ },
3928
3962
  },
3929
3963
  },
3930
3964
  },
@@ -4671,6 +4705,10 @@ export const schemaDict = {
4671
4705
  accept: ['image/png', 'image/jpeg'],
4672
4706
  maxSize: 1000000,
4673
4707
  },
4708
+ labels: {
4709
+ type: 'union',
4710
+ refs: ['lex:com.atproto.label.defs#selfLabels'],
4711
+ },
4674
4712
  createdAt: {
4675
4713
  type: 'string',
4676
4714
  format: 'datetime',
@@ -4752,6 +4790,15 @@ export const schemaDict = {
4752
4790
  cursor: {
4753
4791
  type: 'string',
4754
4792
  },
4793
+ filter: {
4794
+ type: 'string',
4795
+ knownValues: [
4796
+ 'posts_with_replies',
4797
+ 'posts_no_replies',
4798
+ 'posts_with_media',
4799
+ ],
4800
+ default: 'posts_with_replies',
4801
+ },
4755
4802
  },
4756
4803
  },
4757
4804
  output: {
@@ -5321,6 +5368,10 @@ export const schemaDict = {
5321
5368
  format: 'language',
5322
5369
  },
5323
5370
  },
5371
+ labels: {
5372
+ type: 'union',
5373
+ refs: ['lex:com.atproto.label.defs#selfLabels'],
5374
+ },
5324
5375
  createdAt: {
5325
5376
  type: 'string',
5326
5377
  format: 'datetime',
@@ -5940,6 +5991,10 @@ export const schemaDict = {
5940
5991
  accept: ['image/png', 'image/jpeg'],
5941
5992
  maxSize: 1000000,
5942
5993
  },
5994
+ labels: {
5995
+ type: 'union',
5996
+ refs: ['lex:com.atproto.label.defs#selfLabels'],
5997
+ },
5943
5998
  createdAt: {
5944
5999
  type: 'string',
5945
6000
  format: 'datetime',
@@ -5,12 +5,16 @@ import { ValidationResult, BlobRef } from '@atproto/lexicon'
5
5
  import { isObj, hasProp } from '../../../../util'
6
6
  import { lexicons } from '../../../../lexicons'
7
7
  import { CID } from 'multiformats/cid'
8
+ import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
8
9
 
9
10
  export interface Record {
10
11
  displayName?: string
11
12
  description?: string
12
13
  avatar?: BlobRef
13
14
  banner?: BlobRef
15
+ labels?:
16
+ | ComAtprotoLabelDefs.SelfLabels
17
+ | { $type: string; [k: string]: unknown }
14
18
  [k: string]: unknown
15
19
  }
16
20
 
@@ -6,6 +6,7 @@ import { isObj, hasProp } from '../../../../util'
6
6
  import { lexicons } from '../../../../lexicons'
7
7
  import { CID } from 'multiformats/cid'
8
8
  import * as AppBskyRichtextFacet from '../richtext/facet'
9
+ import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
9
10
 
10
11
  export interface Record {
11
12
  did: string
@@ -13,6 +14,9 @@ export interface Record {
13
14
  description?: string
14
15
  descriptionFacets?: AppBskyRichtextFacet.Main[]
15
16
  avatar?: BlobRef
17
+ labels?:
18
+ | ComAtprotoLabelDefs.SelfLabels
19
+ | { $type: string; [k: string]: unknown }
16
20
  createdAt: string
17
21
  [k: string]: unknown
18
22
  }
@@ -12,6 +12,11 @@ export interface QueryParams {
12
12
  actor: string
13
13
  limit?: number
14
14
  cursor?: string
15
+ filter?:
16
+ | 'posts_with_replies'
17
+ | 'posts_no_replies'
18
+ | 'posts_with_media'
19
+ | (string & {})
15
20
  }
16
21
 
17
22
  export type InputSchema = undefined
@@ -10,6 +10,7 @@ import * as AppBskyEmbedImages from '../embed/images'
10
10
  import * as AppBskyEmbedExternal from '../embed/external'
11
11
  import * as AppBskyEmbedRecord from '../embed/record'
12
12
  import * as AppBskyEmbedRecordWithMedia from '../embed/recordWithMedia'
13
+ import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
13
14
  import * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef'
14
15
 
15
16
  export interface Record {
@@ -25,6 +26,9 @@ export interface Record {
25
26
  | AppBskyEmbedRecordWithMedia.Main
26
27
  | { $type: string; [k: string]: unknown }
27
28
  langs?: string[]
29
+ labels?:
30
+ | ComAtprotoLabelDefs.SelfLabels
31
+ | { $type: string; [k: string]: unknown }
28
32
  createdAt: string
29
33
  [k: string]: unknown
30
34
  }
@@ -7,6 +7,7 @@ import { lexicons } from '../../../../lexicons'
7
7
  import { CID } from 'multiformats/cid'
8
8
  import * as AppBskyGraphDefs from './defs'
9
9
  import * as AppBskyRichtextFacet from '../richtext/facet'
10
+ import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs'
10
11
 
11
12
  export interface Record {
12
13
  purpose: AppBskyGraphDefs.ListPurpose
@@ -14,6 +15,9 @@ export interface Record {
14
15
  description?: string
15
16
  descriptionFacets?: AppBskyRichtextFacet.Main[]
16
17
  avatar?: BlobRef
18
+ labels?:
19
+ | ComAtprotoLabelDefs.SelfLabels
20
+ | { $type: string; [k: string]: unknown }
17
21
  createdAt: string
18
22
  [k: string]: unknown
19
23
  }
@@ -34,3 +34,40 @@ export function isLabel(v: unknown): v is Label {
34
34
  export function validateLabel(v: unknown): ValidationResult {
35
35
  return lexicons.validate('com.atproto.label.defs#label', v)
36
36
  }
37
+
38
+ /** Metadata tags on an atproto record, published by the author within the record. */
39
+ export interface SelfLabels {
40
+ values: SelfLabel[]
41
+ [k: string]: unknown
42
+ }
43
+
44
+ export function isSelfLabels(v: unknown): v is SelfLabels {
45
+ return (
46
+ isObj(v) &&
47
+ hasProp(v, '$type') &&
48
+ v.$type === 'com.atproto.label.defs#selfLabels'
49
+ )
50
+ }
51
+
52
+ export function validateSelfLabels(v: unknown): ValidationResult {
53
+ return lexicons.validate('com.atproto.label.defs#selfLabels', v)
54
+ }
55
+
56
+ /** Metadata tag on an atproto record, published by the author within the record. Note -- schemas should use #selfLabels, not #selfLabel. */
57
+ export interface SelfLabel {
58
+ /** the short string name of the value or type of this label */
59
+ val: string
60
+ [k: string]: unknown
61
+ }
62
+
63
+ export function isSelfLabel(v: unknown): v is SelfLabel {
64
+ return (
65
+ isObj(v) &&
66
+ hasProp(v, '$type') &&
67
+ v.$type === 'com.atproto.label.defs#selfLabel'
68
+ )
69
+ }
70
+
71
+ export function validateSelfLabel(v: unknown): ValidationResult {
72
+ return lexicons.validate('com.atproto.label.defs#selfLabel', v)
73
+ }
@@ -47,15 +47,15 @@ export class ModerationCauseAccumulator {
47
47
  }
48
48
 
49
49
  // look up the label preference
50
- // TODO use the find() when 3P labelers support lands
51
- // const labelerSettings = opts.labelerSettings.find(
52
- // (s) => s.labeler.did === label.src,
53
- // )
54
- const labelerSettings = opts.labelerSettings[0]
55
- if (!labelerSettings) {
56
- // ignore labels from labelers we don't use
57
- return
58
- }
50
+ const isSelf = label.src === this.did
51
+ const labeler = isSelf
52
+ ? undefined
53
+ : opts.labelers.find((s) => s.labeler.did === label.src)
54
+
55
+ /* TODO when 3P labelers are supported
56
+ if (!isSelf && !labeler) {
57
+ return // skip labelers not configured by the user
58
+ }*/
59
59
 
60
60
  // establish the label preference for interpretation
61
61
  let labelPref: LabelPreference = 'ignore'
@@ -63,8 +63,10 @@ export class ModerationCauseAccumulator {
63
63
  labelPref = labelDef.preferences[0]
64
64
  } else if (labelDef.flags.includes('adult') && !opts.adultContentEnabled) {
65
65
  labelPref = 'hide'
66
- } else if (labelerSettings.settings[label.val]) {
67
- labelPref = labelerSettings.settings[label.val]
66
+ } else if (labeler?.labels[label.val]) {
67
+ labelPref = labeler.labels[label.val]
68
+ } else if (opts.labels[label.val]) {
69
+ labelPref = opts.labels[label.val]
68
70
  }
69
71
 
70
72
  // ignore labels the user has asked to ignore
@@ -88,9 +90,12 @@ export class ModerationCauseAccumulator {
88
90
 
89
91
  this.causes.push({
90
92
  type: 'label',
93
+ source:
94
+ isSelf || !labeler
95
+ ? { type: 'user' }
96
+ : { type: 'labeler', labeler: labeler.labeler },
91
97
  label,
92
98
  labelDef,
93
- labeler: labelerSettings.labeler,
94
99
  setting: labelPref,
95
100
  priority,
96
101
  })
@@ -64,7 +64,7 @@ interface Labeler {
64
64
 
65
65
  export interface LabelerSettings {
66
66
  labeler: Labeler
67
- settings: Record<string, LabelPreference>
67
+ labels: Record<string, LabelPreference>
68
68
  }
69
69
 
70
70
  // subjects
@@ -95,13 +95,14 @@ export type ModerationSubject =
95
95
  export type ModerationCauseSource =
96
96
  | { type: 'user' }
97
97
  | { type: 'list'; list: AppBskyGraphDefs.ListViewBasic }
98
+ | { type: 'labeler'; labeler: Labeler }
98
99
 
99
100
  export type ModerationCause =
100
101
  | { type: 'blocking'; source: ModerationCauseSource; priority: 3 }
101
102
  | { type: 'blocked-by'; source: ModerationCauseSource; priority: 4 }
102
103
  | {
103
104
  type: 'label'
104
- labeler: Labeler
105
+ source: ModerationCauseSource
105
106
  label: Label
106
107
  labelDef: LabelDefinition
107
108
  setting: LabelPreference
@@ -112,7 +113,8 @@ export type ModerationCause =
112
113
  export interface ModerationOpts {
113
114
  userDid: string
114
115
  adultContentEnabled: boolean
115
- labelerSettings: LabelerSettings[]
116
+ labels: Record<string, LabelPreference>
117
+ labelers: LabelerSettings[]
116
118
  }
117
119
 
118
120
  export class ModerationDecision {