Skip to content

Commit

Permalink
[APP-1072] Support labeler declaration fields on app view responses (#…
Browse files Browse the repository at this point in the history
…3579)

* Mirror new fields on labelerViewDetailed

(cherry picked from commit 33fdceec26c189995936129355135fdb1480a738)
(cherry picked from commit fe56266)

* Mirror new labeler service record properties on labelerViewDetailed lexicons

(cherry picked from commit 6a490f8)

* Include new labeler service record properties on the labelerViewDetailed reponse from the app view.

(cherry picked from commit 279ed64)

* Format

(cherry picked from commit 620346d)

* Fix up bad conflict resolution in test suite

(cherry picked from commit efa04cf)

* Import order

(cherry picked from commit 82567ca)
  • Loading branch information
estrattonbailey authored Feb 26, 2025
1 parent 27b0a7b commit 11d8d21
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-files-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@atproto/bsky": patch
---

Include new labeler service record properties on the `labelerViewDetailed` reponse from the app view.
5 changes: 5 additions & 0 deletions .changeset/six-fireants-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@atproto/api": patch
---

Mirror new labeler service record properties on `labelerViewDetailed`.
21 changes: 21 additions & 0 deletions lexicons/app/bsky/labeler/defs.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@
"labels": {
"type": "array",
"items": { "type": "ref", "ref": "com.atproto.label.defs#label" }
},
"reasonTypes": {
"description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.",
"type": "array",
"items": {
"type": "ref",
"ref": "com.atproto.moderation.defs#reasonType"
}
},
"subjectTypes": {
"description": "The set of subject types (account, record, etc) this service accepts reports on.",
"type": "array",
"items": {
"type": "ref",
"ref": "com.atproto.moderation.defs#subjectType"
}
},
"subjectCollections": {
"type": "array",
"description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.",
"items": { "type": "string", "format": "nsid" }
}
}
},
Expand Down
27 changes: 27 additions & 0 deletions packages/api/src/client/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9044,6 +9044,33 @@ export const schemaDict = {
ref: 'lex:com.atproto.label.defs#label',
},
},
reasonTypes: {
description:
"The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.",
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#reasonType',
},
},
subjectTypes: {
description:
'The set of subject types (account, record, etc) this service accepts reports on.',
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#subjectType',
},
},
subjectCollections: {
type: 'array',
description:
'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.',
items: {
type: 'string',
format: 'nsid',
},
},
},
},
labelerViewerState: {
Expand Down
7 changes: 7 additions & 0 deletions packages/api/src/client/types/app/bsky/labeler/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { validate as _validate } from '../../../../lexicons'
import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
import type * as AppBskyActorDefs from '../actor/defs.js'
import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js'
import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.js'

const is$typed = _is$typed,
validate = _validate
Expand Down Expand Up @@ -43,6 +44,12 @@ export interface LabelerViewDetailed {
viewer?: LabelerViewerState
indexedAt: string
labels?: ComAtprotoLabelDefs.Label[]
/** The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. */
reasonTypes?: ComAtprotoModerationDefs.ReasonType[]
/** The set of subject types (account, record, etc) this service accepts reports on. */
subjectTypes?: ComAtprotoModerationDefs.SubjectType[]
/** Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. */
subjectCollections?: string[]
}

const hashLabelerViewDetailed = 'labelerViewDetailed'
Expand Down
27 changes: 27 additions & 0 deletions packages/bsky/src/lexicon/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9060,6 +9060,33 @@ export const schemaDict = {
ref: 'lex:com.atproto.label.defs#label',
},
},
reasonTypes: {
description:
"The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.",
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#reasonType',
},
},
subjectTypes: {
description:
'The set of subject types (account, record, etc) this service accepts reports on.',
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#subjectType',
},
},
subjectCollections: {
type: 'array',
description:
'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.',
items: {
type: 'string',
format: 'nsid',
},
},
},
},
labelerViewerState: {
Expand Down
7 changes: 7 additions & 0 deletions packages/bsky/src/lexicon/types/app/bsky/labeler/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { validate as _validate } from '../../../../lexicons'
import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
import type * as AppBskyActorDefs from '../actor/defs.js'
import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js'
import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.js'

const is$typed = _is$typed,
validate = _validate
Expand Down Expand Up @@ -43,6 +44,12 @@ export interface LabelerViewDetailed {
viewer?: LabelerViewerState
indexedAt: string
labels?: ComAtprotoLabelDefs.Label[]
/** The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. */
reasonTypes?: ComAtprotoModerationDefs.ReasonType[]
/** The set of subject types (account, record, etc) this service accepts reports on. */
subjectTypes?: ComAtprotoModerationDefs.SubjectType[]
/** Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. */
subjectCollections?: string[]
}

const hashLabelerViewDetailed = 'labelerViewDetailed'
Expand Down
9 changes: 6 additions & 3 deletions packages/bsky/src/views/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,12 +592,15 @@ export class Views {
): Un$Typed<LabelerViewDetailed> | undefined {
const baseView = this.labeler(did, state)
if (!baseView) return
const record = state.labelers?.get(did)
if (!record) return
const labeler = state.labelers?.get(did)
if (!labeler) return

return {
...baseView,
policies: record.record.policies,
policies: labeler.record.policies,
reasonTypes: labeler.record.reasonTypes,
subjectTypes: labeler.record.subjectTypes,
subjectCollections: labeler.record.subjectCollections,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,49 @@ Object {
],
}
`;

exports[`labeler service views returns additional labeler data 1`] = `
Object {
"views": Array [
Object {
"$type": "app.bsky.labeler.defs#labelerViewDetailed",
"cid": "cids(0)",
"creator": Object {
"associated": Object {
"labeler": true,
},
"did": "user(0)",
"handle": "carol.test",
"labels": Array [],
"viewer": Object {
"blockedBy": false,
"following": "record(1)",
"muted": false,
},
},
"indexedAt": "1970-01-01T00:00:00.000Z",
"labels": Array [],
"likeCount": 0,
"policies": Object {
"labelValues": Array [
"spam",
"!hide",
"scam",
"impersonation",
],
},
"reasonTypes": Array [
"com.atproto.moderation.defs#reasonOther",
],
"subjectCollections": Array [
"app.bsky.feed.post",
],
"subjectTypes": Array [
"record",
],
"uri": "record(0)",
"viewer": Object {},
},
],
}
`;
51 changes: 50 additions & 1 deletion packages/bsky/tests/views/labeler-service.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import assert from 'node:assert'
import { AtpAgent } from '@atproto/api'
import {
AppBskyLabelerDefs,
AtpAgent,
ComAtprotoModerationDefs,
} from '@atproto/api'
import { RecordRef, SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
import { ids } from '../../src/lexicon/lexicons'
import { isView as isRecordEmbedView } from '../../src/lexicon/types/app/bsky/embed/record'
Expand All @@ -14,6 +18,7 @@ describe('labeler service views', () => {
// account dids, for convenience
let alice: string
let bob: string
let carol: string

let aliceService: RecordRef

Expand All @@ -27,6 +32,7 @@ describe('labeler service views', () => {
await basicSeed(sc)
alice = sc.dids.alice
bob = sc.dids.bob
carol = sc.dids.carol

const aliceRes = await pdsAgent.api.com.atproto.repo.createRecord(
{
Expand Down Expand Up @@ -190,4 +196,47 @@ describe('labeler service views', () => {
// Cleanup
await network.bsky.ctx.dataplane.untakedownActor({ did: alice })
})

it(`returns additional labeler data`, async () => {
await pdsAgent.api.com.atproto.repo.createRecord(
{
repo: carol,
collection: ids.AppBskyLabelerService,
rkey: 'self',
record: {
policies: {
labelValues: ['spam', '!hide', 'scam', 'impersonation'],
},
createdAt: new Date().toISOString(),
reasonTypes: [ComAtprotoModerationDefs.REASONOTHER],
subjectTypes: ['record'],
subjectCollections: ['app.bsky.feed.post'],
},
},
{ headers: sc.getHeaders(carol), encoding: 'application/json' },
)
await network.processAll()

const view = await agent.api.app.bsky.labeler.getServices(
{ dids: [carol], detailed: true },
{
headers: await network.serviceHeaders(
bob,
ids.AppBskyLabelerGetServices,
),
},
)

const labelerView = view.data.views[0]
expect(AppBskyLabelerDefs.isLabelerViewDetailed(labelerView)).toBe(true)
// for TS only
if (!AppBskyLabelerDefs.isLabelerViewDetailed(labelerView)) return
expect(labelerView).toBeTruthy()
expect(labelerView.reasonTypes).toEqual([
ComAtprotoModerationDefs.REASONOTHER,
])
expect(labelerView.subjectTypes).toEqual(['record'])
expect(labelerView.subjectCollections).toEqual(['app.bsky.feed.post'])
expect(forSnapshot(view.data)).toMatchSnapshot()
})
})
27 changes: 27 additions & 0 deletions packages/ozone/src/lexicon/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9044,6 +9044,33 @@ export const schemaDict = {
ref: 'lex:com.atproto.label.defs#label',
},
},
reasonTypes: {
description:
"The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.",
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#reasonType',
},
},
subjectTypes: {
description:
'The set of subject types (account, record, etc) this service accepts reports on.',
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#subjectType',
},
},
subjectCollections: {
type: 'array',
description:
'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.',
items: {
type: 'string',
format: 'nsid',
},
},
},
},
labelerViewerState: {
Expand Down
7 changes: 7 additions & 0 deletions packages/ozone/src/lexicon/types/app/bsky/labeler/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { validate as _validate } from '../../../../lexicons'
import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
import type * as AppBskyActorDefs from '../actor/defs.js'
import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.js'
import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.js'

const is$typed = _is$typed,
validate = _validate
Expand Down Expand Up @@ -43,6 +44,12 @@ export interface LabelerViewDetailed {
viewer?: LabelerViewerState
indexedAt: string
labels?: ComAtprotoLabelDefs.Label[]
/** The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. */
reasonTypes?: ComAtprotoModerationDefs.ReasonType[]
/** The set of subject types (account, record, etc) this service accepts reports on. */
subjectTypes?: ComAtprotoModerationDefs.SubjectType[]
/** Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. */
subjectCollections?: string[]
}

const hashLabelerViewDetailed = 'labelerViewDetailed'
Expand Down
27 changes: 27 additions & 0 deletions packages/pds/src/lexicon/lexicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9044,6 +9044,33 @@ export const schemaDict = {
ref: 'lex:com.atproto.label.defs#label',
},
},
reasonTypes: {
description:
"The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.",
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#reasonType',
},
},
subjectTypes: {
description:
'The set of subject types (account, record, etc) this service accepts reports on.',
type: 'array',
items: {
type: 'ref',
ref: 'lex:com.atproto.moderation.defs#subjectType',
},
},
subjectCollections: {
type: 'array',
description:
'Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.',
items: {
type: 'string',
format: 'nsid',
},
},
},
},
labelerViewerState: {
Expand Down
Loading

0 comments on commit 11d8d21

Please sign in to comment.