@atproto/bsky 0.0.37 → 0.0.39
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/CHANGELOG.md +21 -0
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts +2 -3
- package/dist/api/app/bsky/feed/getListFeed.d.ts +2 -2
- package/dist/api/app/bsky/feed/getTimeline.d.ts +4 -2
- package/dist/api/app/bsky/labeler/getServices.d.ts +3 -0
- package/dist/api/util.d.ts +9 -2
- package/dist/auth-verifier.d.ts +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/data-plane/server/db/database-schema.d.ts +2 -2
- package/dist/data-plane/server/db/migrations/20240226T225725627Z-labelers.d.ts +3 -0
- package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
- package/dist/data-plane/server/db/tables/labeler.d.ts +13 -0
- package/dist/data-plane/server/indexing/index.d.ts +2 -0
- package/dist/data-plane/server/indexing/plugins/labeler.d.ts +10 -0
- package/dist/data-plane/server/util.d.ts +6 -6
- package/dist/hydration/actor.d.ts +3 -0
- package/dist/hydration/hydrator.d.ts +27 -22
- package/dist/hydration/label.d.ts +23 -9
- package/dist/index.js +4100 -4645
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +7 -27
- package/dist/lexicon/lexicons.d.ts +516 -1463
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +23 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +2 -1
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +3 -0
- package/dist/lexicon/types/app/bsky/labeler/defs.d.ts +41 -0
- package/dist/lexicon/types/{com/atproto/admin/searchRepos.d.ts → app/bsky/labeler/getServices.d.ts} +7 -7
- package/dist/lexicon/types/app/bsky/labeler/service.d.ts +14 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +0 -304
- package/dist/lexicon/types/com/atproto/label/defs.d.ts +23 -0
- package/dist/lexicon/types/com/atproto/server/describeServer.d.ts +7 -0
- package/dist/proto/bsky_connect.d.ts +7 -1
- package/dist/proto/bsky_pb.d.ts +25 -0
- package/dist/util.d.ts +7 -0
- package/dist/views/index.d.ts +3 -0
- package/dist/views/types.d.ts +2 -1
- package/package.json +14 -13
- package/proto/bsky.proto +12 -0
- package/src/api/app/bsky/actor/getProfile.ts +21 -17
- package/src/api/app/bsky/actor/getProfiles.ts +16 -7
- package/src/api/app/bsky/actor/getSuggestions.ts +18 -13
- package/src/api/app/bsky/actor/searchActors.ts +9 -5
- package/src/api/app/bsky/actor/searchActorsTypeahead.ts +12 -5
- package/src/api/app/bsky/feed/getActorFeeds.ts +16 -6
- package/src/api/app/bsky/feed/getActorLikes.ts +18 -8
- package/src/api/app/bsky/feed/getAuthorFeed.ts +18 -19
- package/src/api/app/bsky/feed/getFeed.ts +14 -7
- package/src/api/app/bsky/feed/getFeedGenerator.ts +8 -2
- package/src/api/app/bsky/feed/getFeedGenerators.ts +16 -5
- package/src/api/app/bsky/feed/getLikes.ts +13 -6
- package/src/api/app/bsky/feed/getListFeed.ts +13 -7
- package/src/api/app/bsky/feed/getPostThread.ts +15 -8
- package/src/api/app/bsky/feed/getPosts.ts +14 -5
- package/src/api/app/bsky/feed/getRepostedBy.ts +13 -6
- package/src/api/app/bsky/feed/getSuggestedFeeds.ts +8 -2
- package/src/api/app/bsky/feed/getTimeline.ts +14 -8
- package/src/api/app/bsky/feed/searchPosts.ts +9 -5
- package/src/api/app/bsky/graph/getBlocks.ts +10 -9
- package/src/api/app/bsky/graph/getFollowers.ts +23 -15
- package/src/api/app/bsky/graph/getFollows.ts +23 -15
- package/src/api/app/bsky/graph/getList.ts +14 -8
- package/src/api/app/bsky/graph/getListBlocks.ts +10 -7
- package/src/api/app/bsky/graph/getListMutes.ts +10 -7
- package/src/api/app/bsky/graph/getLists.ts +9 -7
- package/src/api/app/bsky/graph/getMutes.ts +10 -8
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +10 -7
- package/src/api/app/bsky/graph/muteActor.ts +1 -1
- package/src/api/app/bsky/labeler/getServices.ts +46 -0
- package/src/api/app/bsky/notification/listNotifications.ts +12 -8
- package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +6 -3
- package/src/api/com/atproto/admin/getAccountInfos.ts +10 -3
- package/src/api/index.ts +2 -0
- package/src/api/util.ts +19 -4
- package/src/auth-verifier.ts +2 -2
- package/src/context.ts +20 -0
- package/src/data-plane/server/db/database-schema.ts +4 -4
- package/src/data-plane/server/db/migrations/20240226T225725627Z-labelers.ts +27 -0
- package/src/data-plane/server/db/migrations/index.ts +1 -0
- package/src/data-plane/server/db/tables/labeler.ts +16 -0
- package/src/data-plane/server/indexing/index.ts +4 -0
- package/src/data-plane/server/indexing/plugins/labeler.ts +77 -0
- package/src/data-plane/server/routes/interactions.ts +17 -1
- package/src/data-plane/server/routes/labels.ts +4 -2
- package/src/data-plane/server/routes/profile.ts +15 -1
- package/src/data-plane/server/routes/records.ts +1 -0
- package/src/hydration/actor.ts +6 -0
- package/src/hydration/hydrator.ts +171 -97
- package/src/hydration/label.ts +106 -20
- package/src/index.ts +1 -3
- package/src/lexicon/index.ts +22 -137
- package/src/lexicon/lexicons.ts +552 -1635
- package/src/lexicon/types/app/bsky/actor/defs.ts +57 -1
- package/src/lexicon/types/app/bsky/embed/record.ts +2 -0
- package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +3 -0
- package/src/lexicon/types/app/bsky/labeler/defs.ts +93 -0
- package/src/lexicon/types/{com/atproto/admin/searchRepos.ts → app/bsky/labeler/getServices.ts} +8 -8
- package/src/lexicon/types/app/bsky/labeler/service.ts +31 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +0 -694
- package/src/lexicon/types/com/atproto/label/defs.ts +78 -0
- package/src/lexicon/types/com/atproto/server/describeServer.ts +18 -0
- package/src/proto/bsky_connect.ts +11 -0
- package/src/proto/bsky_pb.ts +146 -0
- package/src/util.ts +44 -0
- package/src/views/index.ts +77 -8
- package/src/views/types.ts +6 -3
- package/tests/__snapshots__/feed-generation.test.ts.snap +12 -45
- package/tests/_util.ts +21 -0
- package/tests/data-plane/__snapshots__/indexing.test.ts.snap +20 -8
- package/tests/label-hydration.test.ts +162 -0
- package/tests/views/__snapshots__/author-feed.test.ts.snap +0 -46
- package/tests/views/__snapshots__/block-lists.test.ts.snap +7 -17
- package/tests/views/__snapshots__/blocks.test.ts.snap +0 -9
- package/tests/views/__snapshots__/labeler-service.test.ts.snap +156 -0
- package/tests/views/__snapshots__/list-feed.test.ts.snap +0 -20
- package/tests/views/__snapshots__/mute-lists.test.ts.snap +10 -18
- package/tests/views/__snapshots__/mutes.test.ts.snap +0 -4
- package/tests/views/__snapshots__/notifications.test.ts.snap +0 -9
- package/tests/views/__snapshots__/posts.test.ts.snap +0 -7
- package/tests/views/__snapshots__/profile.test.ts.snap +40 -6
- package/tests/views/__snapshots__/thread.test.ts.snap +0 -38
- package/tests/views/__snapshots__/threadgating.test.ts.snap +2 -0
- package/tests/views/__snapshots__/timeline.test.ts.snap +0 -145
- package/tests/views/labeler-service.test.ts +156 -0
- package/tests/views/takedown-labels.test.ts +133 -0
- package/tests/views/timeline.test.ts +7 -2
- package/dist/data-plane/server/db/tables/moderation.d.ts +0 -42
- package/dist/lexicon/types/com/atproto/admin/createCommunicationTemplate.d.ts +0 -37
- package/dist/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.d.ts +0 -25
- package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +0 -45
- package/dist/lexicon/types/com/atproto/admin/getModerationEvent.d.ts +0 -29
- package/dist/lexicon/types/com/atproto/admin/getRecord.d.ts +0 -31
- package/dist/lexicon/types/com/atproto/admin/getRepo.d.ts +0 -30
- package/dist/lexicon/types/com/atproto/admin/listCommunicationTemplates.d.ts +0 -31
- package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +0 -48
- package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +0 -50
- package/dist/lexicon/types/com/atproto/admin/updateCommunicationTemplate.d.ts +0 -39
- package/src/data-plane/server/db/tables/moderation.ts +0 -59
- package/src/lexicon/types/com/atproto/admin/createCommunicationTemplate.ts +0 -54
- package/src/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.ts +0 -38
- package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +0 -67
- package/src/lexicon/types/com/atproto/admin/getModerationEvent.ts +0 -41
- package/src/lexicon/types/com/atproto/admin/getRecord.ts +0 -43
- package/src/lexicon/types/com/atproto/admin/getRepo.ts +0 -42
- package/src/lexicon/types/com/atproto/admin/listCommunicationTemplates.ts +0 -44
- package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +0 -73
- package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +0 -74
- package/src/lexicon/types/com/atproto/admin/updateCommunicationTemplate.ts +0 -57
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import AtpAgent from '@atproto/api'
|
|
2
|
+
import { TestNetwork, SeedClient, basicSeed, RecordRef } from '@atproto/dev-env'
|
|
3
|
+
import { forSnapshot, stripViewerFromLabeler } from '../_util'
|
|
4
|
+
import { ids } from '../../src/lexicon/lexicons'
|
|
5
|
+
|
|
6
|
+
describe('labeler service views', () => {
|
|
7
|
+
let network: TestNetwork
|
|
8
|
+
let agent: AtpAgent
|
|
9
|
+
let pdsAgent: AtpAgent
|
|
10
|
+
let sc: SeedClient
|
|
11
|
+
|
|
12
|
+
// account dids, for convenience
|
|
13
|
+
let alice: string
|
|
14
|
+
let bob: string
|
|
15
|
+
|
|
16
|
+
let aliceService: RecordRef
|
|
17
|
+
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
network = await TestNetwork.create({
|
|
20
|
+
dbPostgresSchema: 'bsky_views_labeler_service',
|
|
21
|
+
})
|
|
22
|
+
agent = network.bsky.getClient()
|
|
23
|
+
pdsAgent = network.pds.getClient()
|
|
24
|
+
sc = network.getSeedClient()
|
|
25
|
+
await basicSeed(sc)
|
|
26
|
+
alice = sc.dids.alice
|
|
27
|
+
bob = sc.dids.bob
|
|
28
|
+
|
|
29
|
+
const aliceRes = await pdsAgent.api.com.atproto.repo.createRecord(
|
|
30
|
+
{
|
|
31
|
+
repo: alice,
|
|
32
|
+
collection: ids.AppBskyLabelerService,
|
|
33
|
+
rkey: 'self',
|
|
34
|
+
record: {
|
|
35
|
+
policies: {
|
|
36
|
+
labelValues: ['spam', '!hide', 'scam', 'impersonation'],
|
|
37
|
+
},
|
|
38
|
+
createdAt: new Date().toISOString(),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{ headers: sc.getHeaders(alice), encoding: 'application/json' },
|
|
42
|
+
)
|
|
43
|
+
await pdsAgent.api.com.atproto.repo.createRecord(
|
|
44
|
+
{
|
|
45
|
+
repo: bob,
|
|
46
|
+
collection: ids.AppBskyLabelerService,
|
|
47
|
+
rkey: 'self',
|
|
48
|
+
record: {
|
|
49
|
+
policies: {
|
|
50
|
+
labelValues: ['nudity', 'sexual', 'porn'],
|
|
51
|
+
},
|
|
52
|
+
createdAt: new Date().toISOString(),
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{ headers: sc.getHeaders(bob), encoding: 'application/json' },
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
aliceService = new RecordRef(aliceRes.data.uri, aliceRes.data.cid)
|
|
59
|
+
|
|
60
|
+
await sc.like(bob, aliceService)
|
|
61
|
+
await network.processAll()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
afterAll(async () => {
|
|
65
|
+
await network.close()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('fetches labelers', async () => {
|
|
69
|
+
const view = await agent.api.app.bsky.labeler.getServices(
|
|
70
|
+
{ dids: [alice, bob, 'did:example:missing'] },
|
|
71
|
+
{ headers: await network.serviceHeaders(bob) },
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
expect(forSnapshot(view.data)).toMatchSnapshot()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('fetches labelers detailed', async () => {
|
|
78
|
+
const view = await agent.api.app.bsky.labeler.getServices(
|
|
79
|
+
{ dids: [alice, bob, 'did:example:missing'], detailed: true },
|
|
80
|
+
{ headers: await network.serviceHeaders(bob) },
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
expect(forSnapshot(view.data)).toMatchSnapshot()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('fetches labelers unauthed', async () => {
|
|
87
|
+
const { data: authed } = await agent.api.app.bsky.labeler.getServices(
|
|
88
|
+
{ dids: [alice] },
|
|
89
|
+
{ headers: await network.serviceHeaders(bob) },
|
|
90
|
+
)
|
|
91
|
+
const { data: unauthed } = await agent.api.app.bsky.labeler.getServices({
|
|
92
|
+
dids: [alice],
|
|
93
|
+
})
|
|
94
|
+
expect(unauthed.views).toEqual(authed.views.map(stripViewerFromLabeler))
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('fetches multiple labelers unauthed', async () => {
|
|
98
|
+
const { data: authed } = await agent.api.app.bsky.labeler.getServices(
|
|
99
|
+
{
|
|
100
|
+
dids: [alice, bob, 'did:example:missing'],
|
|
101
|
+
},
|
|
102
|
+
{ headers: await network.serviceHeaders(bob) },
|
|
103
|
+
)
|
|
104
|
+
const { data: unauthed } = await agent.api.app.bsky.labeler.getServices({
|
|
105
|
+
dids: [alice, bob, 'did:example:missing'],
|
|
106
|
+
})
|
|
107
|
+
expect(unauthed.views.length).toBeGreaterThan(0)
|
|
108
|
+
expect(unauthed.views).toEqual(authed.views.map(stripViewerFromLabeler))
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('renders a post embed of a labeler', async () => {
|
|
112
|
+
const postRes = await pdsAgent.api.app.bsky.feed.post.create(
|
|
113
|
+
{ repo: sc.dids.bob },
|
|
114
|
+
{
|
|
115
|
+
text: 'check out this labeler',
|
|
116
|
+
embed: {
|
|
117
|
+
$type: 'app.bsky.embed.record',
|
|
118
|
+
record: aliceService.raw,
|
|
119
|
+
},
|
|
120
|
+
createdAt: new Date().toISOString(),
|
|
121
|
+
},
|
|
122
|
+
sc.getHeaders(sc.dids.bob),
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
await network.processAll()
|
|
126
|
+
|
|
127
|
+
const postViews = await agent.api.app.bsky.feed.getPosts({
|
|
128
|
+
uris: [postRes.uri],
|
|
129
|
+
})
|
|
130
|
+
const serviceViews = await agent.api.app.bsky.labeler.getServices({
|
|
131
|
+
dids: [alice],
|
|
132
|
+
})
|
|
133
|
+
expect(postViews.data.posts[0].embed?.record).toMatchObject(
|
|
134
|
+
serviceViews.data.views[0],
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('blocked by labeler takedown', async () => {
|
|
139
|
+
await network.bsky.ctx.dataplane.takedownRecord({
|
|
140
|
+
recordUri: aliceService.uriStr,
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const res = await agent.api.app.bsky.labeler.getServices(
|
|
144
|
+
{ dids: [alice, bob] },
|
|
145
|
+
{ headers: await network.serviceHeaders(bob) },
|
|
146
|
+
)
|
|
147
|
+
expect(res.data.views.length).toBe(1)
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
expect(res.data.views[0].creator.did).toEqual(bob)
|
|
150
|
+
|
|
151
|
+
// Cleanup
|
|
152
|
+
await network.bsky.ctx.dataplane.untakedownRecord({
|
|
153
|
+
recordUri: aliceService.uriStr,
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
})
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import AtpAgent from '@atproto/api'
|
|
2
|
+
import { TestNetwork, SeedClient, basicSeed, RecordRef } from '@atproto/dev-env'
|
|
3
|
+
|
|
4
|
+
describe('bsky takedown labels', () => {
|
|
5
|
+
let network: TestNetwork
|
|
6
|
+
let agent: AtpAgent
|
|
7
|
+
let sc: SeedClient
|
|
8
|
+
|
|
9
|
+
let takendownSubjects: string[]
|
|
10
|
+
|
|
11
|
+
let aliceListRef: RecordRef
|
|
12
|
+
let carolListRef: RecordRef
|
|
13
|
+
let aliceGenRef: RecordRef
|
|
14
|
+
let bobGenRef: RecordRef
|
|
15
|
+
let carolGenRef: RecordRef
|
|
16
|
+
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
network = await TestNetwork.create({
|
|
19
|
+
dbPostgresSchema: 'bsky_views_takedown_labels',
|
|
20
|
+
})
|
|
21
|
+
agent = network.bsky.getClient()
|
|
22
|
+
sc = network.getSeedClient()
|
|
23
|
+
await basicSeed(sc)
|
|
24
|
+
|
|
25
|
+
aliceListRef = await sc.createList(sc.dids.alice, 'alice list', 'mod')
|
|
26
|
+
carolListRef = await sc.createList(sc.dids.carol, 'carol list', 'mod')
|
|
27
|
+
aliceGenRef = await sc.createFeedGen(
|
|
28
|
+
sc.dids.alice,
|
|
29
|
+
'did:web:example.com',
|
|
30
|
+
'alice generator',
|
|
31
|
+
)
|
|
32
|
+
bobGenRef = await sc.createFeedGen(
|
|
33
|
+
sc.dids.bob,
|
|
34
|
+
'did:web:example.com',
|
|
35
|
+
'bob generator',
|
|
36
|
+
)
|
|
37
|
+
carolGenRef = await sc.createFeedGen(
|
|
38
|
+
sc.dids.carol,
|
|
39
|
+
'did:web:example.com',
|
|
40
|
+
'carol generator',
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
await network.processAll()
|
|
44
|
+
|
|
45
|
+
takendownSubjects = [
|
|
46
|
+
sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
47
|
+
sc.dids.carol,
|
|
48
|
+
aliceListRef.uriStr,
|
|
49
|
+
aliceGenRef.uriStr,
|
|
50
|
+
]
|
|
51
|
+
const src = network.ozone.ctx.cfg.service.did
|
|
52
|
+
const cts = new Date().toISOString()
|
|
53
|
+
const labels = takendownSubjects.map((uri) => ({
|
|
54
|
+
src,
|
|
55
|
+
uri,
|
|
56
|
+
cid: '',
|
|
57
|
+
val: '!takedown',
|
|
58
|
+
neg: false,
|
|
59
|
+
cts,
|
|
60
|
+
}))
|
|
61
|
+
AtpAgent.configure({ appLabelers: [src] })
|
|
62
|
+
|
|
63
|
+
await network.bsky.db.db.insertInto('label').values(labels).execute()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
afterAll(async () => {
|
|
67
|
+
await network.close()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('takesdown profiles', async () => {
|
|
71
|
+
const attempt = agent.api.app.bsky.actor.getProfile({
|
|
72
|
+
actor: sc.dids.carol,
|
|
73
|
+
})
|
|
74
|
+
await expect(attempt).rejects.toThrow('Account has been suspended')
|
|
75
|
+
const res = await agent.api.app.bsky.actor.getProfiles({
|
|
76
|
+
actors: [sc.dids.alice, sc.dids.bob, sc.dids.carol],
|
|
77
|
+
})
|
|
78
|
+
expect(res.data.profiles.length).toBe(2)
|
|
79
|
+
expect(res.data.profiles.some((p) => p.did === sc.dids.carol)).toBe(false)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('takesdown posts', async () => {
|
|
83
|
+
const uris = [
|
|
84
|
+
sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
85
|
+
sc.posts[sc.dids.alice][1].ref.uriStr,
|
|
86
|
+
sc.posts[sc.dids.bob][0].ref.uriStr,
|
|
87
|
+
sc.posts[sc.dids.carol][0].ref.uriStr,
|
|
88
|
+
sc.posts[sc.dids.dan][1].ref.uriStr,
|
|
89
|
+
sc.replies[sc.dids.alice][0].ref.uriStr,
|
|
90
|
+
]
|
|
91
|
+
const res = await agent.api.app.bsky.feed.getPosts({ uris })
|
|
92
|
+
|
|
93
|
+
expect(res.data.posts.length).toBe(4)
|
|
94
|
+
expect(res.data.posts.some((p) => p.author.did === sc.dids.carol)).toBe(
|
|
95
|
+
false,
|
|
96
|
+
)
|
|
97
|
+
expect(
|
|
98
|
+
res.data.posts.some(
|
|
99
|
+
(p) => p.uri === sc.posts[sc.dids.alice][0].ref.uriStr,
|
|
100
|
+
),
|
|
101
|
+
).toBe(false)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('takesdown lists', async () => {
|
|
105
|
+
// record takedown
|
|
106
|
+
const attempt1 = agent.api.app.bsky.graph.getList({
|
|
107
|
+
list: aliceListRef.uriStr,
|
|
108
|
+
})
|
|
109
|
+
await expect(attempt1).rejects.toThrow('List not found')
|
|
110
|
+
|
|
111
|
+
// actor takedown
|
|
112
|
+
const attempt2 = agent.api.app.bsky.graph.getList({
|
|
113
|
+
list: carolListRef.uriStr,
|
|
114
|
+
})
|
|
115
|
+
await expect(attempt2).rejects.toThrow('List not found')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('takesdown feed generators', async () => {
|
|
119
|
+
const res = await agent.api.app.bsky.feed.getFeedGenerators({
|
|
120
|
+
feeds: [aliceGenRef.uriStr, bobGenRef.uriStr, carolGenRef.uriStr],
|
|
121
|
+
})
|
|
122
|
+
expect(res.data.feeds.length).toBe(1)
|
|
123
|
+
expect(res.data.feeds.at(0)?.uri).toEqual(bobGenRef.uriStr)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('only applies if the relevant labeler is configured', async () => {
|
|
127
|
+
AtpAgent.configure({ appLabelers: ['did:web:example.com'] })
|
|
128
|
+
const res = await agent.api.app.bsky.actor.getProfile({
|
|
129
|
+
actor: sc.dids.carol,
|
|
130
|
+
})
|
|
131
|
+
expect(res.data.did).toEqual(sc.dids.carol)
|
|
132
|
+
})
|
|
133
|
+
})
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import assert from 'assert'
|
|
2
2
|
import AtpAgent from '@atproto/api'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
TestNetwork,
|
|
5
|
+
SeedClient,
|
|
6
|
+
basicSeed,
|
|
7
|
+
EXAMPLE_LABELER,
|
|
8
|
+
} from '@atproto/dev-env'
|
|
4
9
|
import { forSnapshot, getOriginator, paginateAll } from '../_util'
|
|
5
10
|
import { FeedViewPost } from '../../src/lexicon/types/app/bsky/feed/defs'
|
|
6
11
|
import { Database } from '../../src'
|
|
@@ -258,7 +263,7 @@ const createLabel = async (
|
|
|
258
263
|
val: opts.val,
|
|
259
264
|
cts: new Date().toISOString(),
|
|
260
265
|
neg: false,
|
|
261
|
-
src:
|
|
266
|
+
src: EXAMPLE_LABELER,
|
|
262
267
|
})
|
|
263
268
|
.execute()
|
|
264
269
|
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Generated } from 'kysely';
|
|
2
|
-
import { REVIEWCLOSED, REVIEWOPEN, REVIEWESCALATED } from '../../../../lexicon/types/com/atproto/admin/defs';
|
|
3
|
-
export declare const eventTableName = "moderation_event";
|
|
4
|
-
export declare const subjectStatusTableName = "moderation_subject_status";
|
|
5
|
-
export interface ModerationEvent {
|
|
6
|
-
id: Generated<number>;
|
|
7
|
-
action: 'com.atproto.admin.defs#modEventTakedown' | 'com.atproto.admin.defs#modEventAcknowledge' | 'com.atproto.admin.defs#modEventEscalate' | 'com.atproto.admin.defs#modEventComment' | 'com.atproto.admin.defs#modEventLabel' | 'com.atproto.admin.defs#modEventReport' | 'com.atproto.admin.defs#modEventMute' | 'com.atproto.admin.defs#modEventReverseTakedown' | 'com.atproto.admin.defs#modEventEmail';
|
|
8
|
-
subjectType: 'com.atproto.admin.defs#repoRef' | 'com.atproto.repo.strongRef';
|
|
9
|
-
subjectDid: string;
|
|
10
|
-
subjectUri: string | null;
|
|
11
|
-
subjectCid: string | null;
|
|
12
|
-
createLabelVals: string | null;
|
|
13
|
-
negateLabelVals: string | null;
|
|
14
|
-
comment: string | null;
|
|
15
|
-
createdAt: string;
|
|
16
|
-
createdBy: string;
|
|
17
|
-
durationInHours: number | null;
|
|
18
|
-
expiresAt: string | null;
|
|
19
|
-
meta: Record<string, string | boolean> | null;
|
|
20
|
-
legacyRefId: number | null;
|
|
21
|
-
}
|
|
22
|
-
export interface ModerationSubjectStatus {
|
|
23
|
-
id: Generated<number>;
|
|
24
|
-
did: string;
|
|
25
|
-
recordPath: string;
|
|
26
|
-
recordCid: string | null;
|
|
27
|
-
blobCids: string[] | null;
|
|
28
|
-
reviewState: typeof REVIEWCLOSED | typeof REVIEWOPEN | typeof REVIEWESCALATED;
|
|
29
|
-
createdAt: string;
|
|
30
|
-
updatedAt: string;
|
|
31
|
-
lastReviewedBy: string | null;
|
|
32
|
-
lastReviewedAt: string | null;
|
|
33
|
-
lastReportedAt: string | null;
|
|
34
|
-
muteUntil: string | null;
|
|
35
|
-
suspendUntil: string | null;
|
|
36
|
-
takendown: boolean;
|
|
37
|
-
comment: string | null;
|
|
38
|
-
}
|
|
39
|
-
export type PartialDB = {
|
|
40
|
-
[eventTableName]: ModerationEvent;
|
|
41
|
-
[subjectStatusTableName]: ModerationSubjectStatus;
|
|
42
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
}
|
|
6
|
-
export interface InputSchema {
|
|
7
|
-
name: string;
|
|
8
|
-
contentMarkdown: string;
|
|
9
|
-
subject: string;
|
|
10
|
-
createdBy?: string;
|
|
11
|
-
[k: string]: unknown;
|
|
12
|
-
}
|
|
13
|
-
export type OutputSchema = ComAtprotoAdminDefs.CommunicationTemplateView;
|
|
14
|
-
export interface HandlerInput {
|
|
15
|
-
encoding: 'application/json';
|
|
16
|
-
body: InputSchema;
|
|
17
|
-
}
|
|
18
|
-
export interface HandlerSuccess {
|
|
19
|
-
encoding: 'application/json';
|
|
20
|
-
body: OutputSchema;
|
|
21
|
-
headers?: {
|
|
22
|
-
[key: string]: string;
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
export interface HandlerError {
|
|
26
|
-
status: number;
|
|
27
|
-
message?: string;
|
|
28
|
-
}
|
|
29
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
30
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
31
|
-
auth: HA;
|
|
32
|
-
params: QueryParams;
|
|
33
|
-
input: HandlerInput;
|
|
34
|
-
req: express.Request;
|
|
35
|
-
res: express.Response;
|
|
36
|
-
};
|
|
37
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
-
export interface QueryParams {
|
|
4
|
-
}
|
|
5
|
-
export interface InputSchema {
|
|
6
|
-
id: string;
|
|
7
|
-
[k: string]: unknown;
|
|
8
|
-
}
|
|
9
|
-
export interface HandlerInput {
|
|
10
|
-
encoding: 'application/json';
|
|
11
|
-
body: InputSchema;
|
|
12
|
-
}
|
|
13
|
-
export interface HandlerError {
|
|
14
|
-
status: number;
|
|
15
|
-
message?: string;
|
|
16
|
-
}
|
|
17
|
-
export type HandlerOutput = HandlerError | void;
|
|
18
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
19
|
-
auth: HA;
|
|
20
|
-
params: QueryParams;
|
|
21
|
-
input: HandlerInput;
|
|
22
|
-
req: express.Request;
|
|
23
|
-
res: express.Response;
|
|
24
|
-
};
|
|
25
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
import * as ComAtprotoRepoStrongRef from '../repo/strongRef';
|
|
5
|
-
export interface QueryParams {
|
|
6
|
-
}
|
|
7
|
-
export interface InputSchema {
|
|
8
|
-
event: ComAtprotoAdminDefs.ModEventTakedown | ComAtprotoAdminDefs.ModEventAcknowledge | ComAtprotoAdminDefs.ModEventEscalate | ComAtprotoAdminDefs.ModEventComment | ComAtprotoAdminDefs.ModEventLabel | ComAtprotoAdminDefs.ModEventReport | ComAtprotoAdminDefs.ModEventMute | ComAtprotoAdminDefs.ModEventReverseTakedown | ComAtprotoAdminDefs.ModEventUnmute | ComAtprotoAdminDefs.ModEventEmail | ComAtprotoAdminDefs.ModEventTag | {
|
|
9
|
-
$type: string;
|
|
10
|
-
[k: string]: unknown;
|
|
11
|
-
};
|
|
12
|
-
subject: ComAtprotoAdminDefs.RepoRef | ComAtprotoRepoStrongRef.Main | {
|
|
13
|
-
$type: string;
|
|
14
|
-
[k: string]: unknown;
|
|
15
|
-
};
|
|
16
|
-
subjectBlobCids?: string[];
|
|
17
|
-
createdBy: string;
|
|
18
|
-
[k: string]: unknown;
|
|
19
|
-
}
|
|
20
|
-
export type OutputSchema = ComAtprotoAdminDefs.ModEventView;
|
|
21
|
-
export interface HandlerInput {
|
|
22
|
-
encoding: 'application/json';
|
|
23
|
-
body: InputSchema;
|
|
24
|
-
}
|
|
25
|
-
export interface HandlerSuccess {
|
|
26
|
-
encoding: 'application/json';
|
|
27
|
-
body: OutputSchema;
|
|
28
|
-
headers?: {
|
|
29
|
-
[key: string]: string;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export interface HandlerError {
|
|
33
|
-
status: number;
|
|
34
|
-
message?: string;
|
|
35
|
-
error?: 'SubjectHasAction';
|
|
36
|
-
}
|
|
37
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
38
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
39
|
-
auth: HA;
|
|
40
|
-
params: QueryParams;
|
|
41
|
-
input: HandlerInput;
|
|
42
|
-
req: express.Request;
|
|
43
|
-
res: express.Response;
|
|
44
|
-
};
|
|
45
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
id: number;
|
|
6
|
-
}
|
|
7
|
-
export type InputSchema = undefined;
|
|
8
|
-
export type OutputSchema = ComAtprotoAdminDefs.ModEventViewDetail;
|
|
9
|
-
export type HandlerInput = undefined;
|
|
10
|
-
export interface HandlerSuccess {
|
|
11
|
-
encoding: 'application/json';
|
|
12
|
-
body: OutputSchema;
|
|
13
|
-
headers?: {
|
|
14
|
-
[key: string]: string;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export interface HandlerError {
|
|
18
|
-
status: number;
|
|
19
|
-
message?: string;
|
|
20
|
-
}
|
|
21
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
22
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
23
|
-
auth: HA;
|
|
24
|
-
params: QueryParams;
|
|
25
|
-
input: HandlerInput;
|
|
26
|
-
req: express.Request;
|
|
27
|
-
res: express.Response;
|
|
28
|
-
};
|
|
29
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
uri: string;
|
|
6
|
-
cid?: string;
|
|
7
|
-
}
|
|
8
|
-
export type InputSchema = undefined;
|
|
9
|
-
export type OutputSchema = ComAtprotoAdminDefs.RecordViewDetail;
|
|
10
|
-
export type HandlerInput = undefined;
|
|
11
|
-
export interface HandlerSuccess {
|
|
12
|
-
encoding: 'application/json';
|
|
13
|
-
body: OutputSchema;
|
|
14
|
-
headers?: {
|
|
15
|
-
[key: string]: string;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export interface HandlerError {
|
|
19
|
-
status: number;
|
|
20
|
-
message?: string;
|
|
21
|
-
error?: 'RecordNotFound';
|
|
22
|
-
}
|
|
23
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
24
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
25
|
-
auth: HA;
|
|
26
|
-
params: QueryParams;
|
|
27
|
-
input: HandlerInput;
|
|
28
|
-
req: express.Request;
|
|
29
|
-
res: express.Response;
|
|
30
|
-
};
|
|
31
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
did: string;
|
|
6
|
-
}
|
|
7
|
-
export type InputSchema = undefined;
|
|
8
|
-
export type OutputSchema = ComAtprotoAdminDefs.RepoViewDetail;
|
|
9
|
-
export type HandlerInput = undefined;
|
|
10
|
-
export interface HandlerSuccess {
|
|
11
|
-
encoding: 'application/json';
|
|
12
|
-
body: OutputSchema;
|
|
13
|
-
headers?: {
|
|
14
|
-
[key: string]: string;
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export interface HandlerError {
|
|
18
|
-
status: number;
|
|
19
|
-
message?: string;
|
|
20
|
-
error?: 'RepoNotFound';
|
|
21
|
-
}
|
|
22
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
23
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
24
|
-
auth: HA;
|
|
25
|
-
params: QueryParams;
|
|
26
|
-
input: HandlerInput;
|
|
27
|
-
req: express.Request;
|
|
28
|
-
res: express.Response;
|
|
29
|
-
};
|
|
30
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
}
|
|
6
|
-
export type InputSchema = undefined;
|
|
7
|
-
export interface OutputSchema {
|
|
8
|
-
communicationTemplates: ComAtprotoAdminDefs.CommunicationTemplateView[];
|
|
9
|
-
[k: string]: unknown;
|
|
10
|
-
}
|
|
11
|
-
export type HandlerInput = undefined;
|
|
12
|
-
export interface HandlerSuccess {
|
|
13
|
-
encoding: 'application/json';
|
|
14
|
-
body: OutputSchema;
|
|
15
|
-
headers?: {
|
|
16
|
-
[key: string]: string;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
export interface HandlerError {
|
|
20
|
-
status: number;
|
|
21
|
-
message?: string;
|
|
22
|
-
}
|
|
23
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
24
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
25
|
-
auth: HA;
|
|
26
|
-
params: QueryParams;
|
|
27
|
-
input: HandlerInput;
|
|
28
|
-
req: express.Request;
|
|
29
|
-
res: express.Response;
|
|
30
|
-
};
|
|
31
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
types?: string[];
|
|
6
|
-
createdBy?: string;
|
|
7
|
-
sortDirection: 'asc' | 'desc';
|
|
8
|
-
createdAfter?: string;
|
|
9
|
-
createdBefore?: string;
|
|
10
|
-
subject?: string;
|
|
11
|
-
includeAllUserRecords: boolean;
|
|
12
|
-
limit: number;
|
|
13
|
-
hasComment?: boolean;
|
|
14
|
-
comment?: string;
|
|
15
|
-
addedLabels?: string[];
|
|
16
|
-
removedLabels?: string[];
|
|
17
|
-
addedTags?: string[];
|
|
18
|
-
removedTags?: string[];
|
|
19
|
-
reportTypes?: string[];
|
|
20
|
-
cursor?: string;
|
|
21
|
-
}
|
|
22
|
-
export type InputSchema = undefined;
|
|
23
|
-
export interface OutputSchema {
|
|
24
|
-
cursor?: string;
|
|
25
|
-
events: ComAtprotoAdminDefs.ModEventView[];
|
|
26
|
-
[k: string]: unknown;
|
|
27
|
-
}
|
|
28
|
-
export type HandlerInput = undefined;
|
|
29
|
-
export interface HandlerSuccess {
|
|
30
|
-
encoding: 'application/json';
|
|
31
|
-
body: OutputSchema;
|
|
32
|
-
headers?: {
|
|
33
|
-
[key: string]: string;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
export interface HandlerError {
|
|
37
|
-
status: number;
|
|
38
|
-
message?: string;
|
|
39
|
-
}
|
|
40
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
41
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
42
|
-
auth: HA;
|
|
43
|
-
params: QueryParams;
|
|
44
|
-
input: HandlerInput;
|
|
45
|
-
req: express.Request;
|
|
46
|
-
res: express.Response;
|
|
47
|
-
};
|
|
48
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoAdminDefs from './defs';
|
|
4
|
-
export interface QueryParams {
|
|
5
|
-
subject?: string;
|
|
6
|
-
comment?: string;
|
|
7
|
-
reportedAfter?: string;
|
|
8
|
-
reportedBefore?: string;
|
|
9
|
-
reviewedAfter?: string;
|
|
10
|
-
reviewedBefore?: string;
|
|
11
|
-
includeMuted?: boolean;
|
|
12
|
-
reviewState?: string;
|
|
13
|
-
ignoreSubjects?: string[];
|
|
14
|
-
lastReviewedBy?: string;
|
|
15
|
-
sortField: 'lastReviewedAt' | 'lastReportedAt';
|
|
16
|
-
sortDirection: 'asc' | 'desc';
|
|
17
|
-
takendown?: boolean;
|
|
18
|
-
appealed?: boolean;
|
|
19
|
-
limit: number;
|
|
20
|
-
tags?: string[];
|
|
21
|
-
excludeTags?: string[];
|
|
22
|
-
cursor?: string;
|
|
23
|
-
}
|
|
24
|
-
export type InputSchema = undefined;
|
|
25
|
-
export interface OutputSchema {
|
|
26
|
-
cursor?: string;
|
|
27
|
-
subjectStatuses: ComAtprotoAdminDefs.SubjectStatusView[];
|
|
28
|
-
[k: string]: unknown;
|
|
29
|
-
}
|
|
30
|
-
export type HandlerInput = undefined;
|
|
31
|
-
export interface HandlerSuccess {
|
|
32
|
-
encoding: 'application/json';
|
|
33
|
-
body: OutputSchema;
|
|
34
|
-
headers?: {
|
|
35
|
-
[key: string]: string;
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
export interface HandlerError {
|
|
39
|
-
status: number;
|
|
40
|
-
message?: string;
|
|
41
|
-
}
|
|
42
|
-
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough;
|
|
43
|
-
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
44
|
-
auth: HA;
|
|
45
|
-
params: QueryParams;
|
|
46
|
-
input: HandlerInput;
|
|
47
|
-
req: express.Request;
|
|
48
|
-
res: express.Response;
|
|
49
|
-
};
|
|
50
|
-
export type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|