@atproto/ozone 0.1.24 → 0.1.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.
- package/CHANGELOG.md +16 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +8 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/proxied.d.ts.map +1 -1
- package/dist/api/proxied.js +13 -0
- package/dist/api/proxied.js.map +1 -1
- package/dist/api/server/getConfig.d.ts.map +1 -1
- package/dist/api/server/getConfig.js +4 -3
- package/dist/api/server/getConfig.js.map +1 -1
- package/dist/api/team/addMember.d.ts +4 -0
- package/dist/api/team/addMember.d.ts.map +1 -0
- package/dist/api/team/addMember.js +38 -0
- package/dist/api/team/addMember.js.map +1 -0
- package/dist/api/team/deleteMember.d.ts +4 -0
- package/dist/api/team/deleteMember.d.ts.map +1 -0
- package/dist/api/team/deleteMember.js +26 -0
- package/dist/api/team/deleteMember.js.map +1 -0
- package/dist/api/team/listMembers.d.ts +4 -0
- package/dist/api/team/listMembers.d.ts.map +1 -0
- package/dist/api/team/listMembers.js +20 -0
- package/dist/api/team/listMembers.js.map +1 -0
- package/dist/api/team/updateMember.d.ts +4 -0
- package/dist/api/team/updateMember.d.ts.map +1 -0
- package/dist/api/team/updateMember.js +40 -0
- package/dist/api/team/updateMember.js.map +1 -0
- package/dist/api/util.d.ts +1 -0
- package/dist/api/util.d.ts.map +1 -1
- package/dist/api/util.js +10 -1
- package/dist/api/util.js.map +1 -1
- package/dist/auth-verifier.d.ts +3 -6
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +7 -19
- package/dist/auth-verifier.js.map +1 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +10 -7
- package/dist/config/config.js.map +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +7 -3
- package/dist/context.js.map +1 -1
- package/dist/db/migrations/20240521T211332580Z-member.d.ts +4 -0
- package/dist/db/migrations/20240521T211332580Z-member.d.ts.map +1 -0
- package/dist/db/migrations/20240521T211332580Z-member.js +20 -0
- package/dist/db/migrations/20240521T211332580Z-member.js.map +1 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +2 -1
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/schema/index.d.ts +2 -1
- package/dist/db/schema/index.d.ts.map +1 -1
- package/dist/db/schema/member.d.ts +14 -0
- package/dist/db/schema/member.d.ts.map +1 -0
- package/dist/db/schema/member.js +5 -0
- package/dist/db/schema/member.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +18 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +41 -1
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +204 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +222 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/team/addMember.d.ts +40 -0
- package/dist/lexicon/types/tools/ozone/team/addMember.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/addMember.js +3 -0
- package/dist/lexicon/types/tools/ozone/team/addMember.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/defs.d.ts +24 -0
- package/dist/lexicon/types/tools/ozone/team/defs.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/defs.js +22 -0
- package/dist/lexicon/types/tools/ozone/team/defs.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/deleteMember.d.ts +30 -0
- package/dist/lexicon/types/tools/ozone/team/deleteMember.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/deleteMember.js +3 -0
- package/dist/lexicon/types/tools/ozone/team/deleteMember.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/listMembers.d.ts +38 -0
- package/dist/lexicon/types/tools/ozone/team/listMembers.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/listMembers.js +3 -0
- package/dist/lexicon/types/tools/ozone/team/listMembers.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/updateMember.d.ts +41 -0
- package/dist/lexicon/types/tools/ozone/team/updateMember.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/team/updateMember.js +3 -0
- package/dist/lexicon/types/tools/ozone/team/updateMember.js.map +1 -0
- package/dist/logger.d.ts +2 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/team/index.d.ts +37 -0
- package/dist/team/index.d.ts.map +1 -0
- package/dist/team/index.js +144 -0
- package/dist/team/index.js.map +1 -0
- package/package.json +3 -3
- package/src/api/index.ts +8 -0
- package/src/api/proxied.ts +17 -0
- package/src/api/server/getConfig.ts +4 -4
- package/src/api/team/addMember.ts +46 -0
- package/src/api/team/deleteMember.ts +29 -0
- package/src/api/team/listMembers.ts +20 -0
- package/src/api/team/updateMember.ts +47 -0
- package/src/api/util.ts +15 -0
- package/src/auth-verifier.ts +14 -12
- package/src/config/config.ts +10 -7
- package/src/context.ts +9 -3
- package/src/db/migrations/20240521T211332580Z-member.ts +17 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/db/schema/index.ts +3 -1
- package/src/db/schema/member.ts +19 -0
- package/src/index.ts +36 -0
- package/src/lexicon/index.ts +63 -0
- package/src/lexicon/lexicons.ts +225 -0
- package/src/lexicon/types/tools/ozone/team/addMember.ts +53 -0
- package/src/lexicon/types/tools/ozone/team/defs.ts +42 -0
- package/src/lexicon/types/tools/ozone/team/deleteMember.ts +39 -0
- package/src/lexicon/types/tools/ozone/team/listMembers.ts +48 -0
- package/src/lexicon/types/tools/ozone/team/updateMember.ts +54 -0
- package/src/team/index.ts +213 -0
- package/tests/__snapshots__/team.test.ts.snap +664 -0
- package/tests/get-config.test.ts +3 -4
- package/tests/team.test.ts +163 -0
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -11006,6 +11006,226 @@ export const schemaDict = {
|
|
|
11006
11006
|
},
|
|
11007
11007
|
},
|
|
11008
11008
|
},
|
|
11009
|
+
ToolsOzoneTeamAddMember: {
|
|
11010
|
+
lexicon: 1,
|
|
11011
|
+
id: 'tools.ozone.team.addMember',
|
|
11012
|
+
defs: {
|
|
11013
|
+
main: {
|
|
11014
|
+
type: 'procedure',
|
|
11015
|
+
description: 'Add a member to the ozone team. Requires admin role.',
|
|
11016
|
+
input: {
|
|
11017
|
+
encoding: 'application/json',
|
|
11018
|
+
schema: {
|
|
11019
|
+
type: 'object',
|
|
11020
|
+
required: ['did', 'role'],
|
|
11021
|
+
properties: {
|
|
11022
|
+
did: {
|
|
11023
|
+
type: 'string',
|
|
11024
|
+
format: 'did',
|
|
11025
|
+
},
|
|
11026
|
+
role: {
|
|
11027
|
+
type: 'string',
|
|
11028
|
+
knownValues: [
|
|
11029
|
+
'tools.ozone.team.defs#roleAdmin',
|
|
11030
|
+
'tools.ozone.team.defs#roleModerator',
|
|
11031
|
+
'tools.ozone.team.defs#roleTriage',
|
|
11032
|
+
],
|
|
11033
|
+
},
|
|
11034
|
+
},
|
|
11035
|
+
},
|
|
11036
|
+
},
|
|
11037
|
+
output: {
|
|
11038
|
+
encoding: 'application/json',
|
|
11039
|
+
schema: {
|
|
11040
|
+
type: 'ref',
|
|
11041
|
+
ref: 'lex:tools.ozone.team.defs#member',
|
|
11042
|
+
},
|
|
11043
|
+
},
|
|
11044
|
+
errors: [
|
|
11045
|
+
{
|
|
11046
|
+
name: 'MemberAlreadyExists',
|
|
11047
|
+
description: 'Member already exists in the team.',
|
|
11048
|
+
},
|
|
11049
|
+
],
|
|
11050
|
+
},
|
|
11051
|
+
},
|
|
11052
|
+
},
|
|
11053
|
+
ToolsOzoneTeamDefs: {
|
|
11054
|
+
lexicon: 1,
|
|
11055
|
+
id: 'tools.ozone.team.defs',
|
|
11056
|
+
defs: {
|
|
11057
|
+
member: {
|
|
11058
|
+
type: 'object',
|
|
11059
|
+
required: ['did', 'role'],
|
|
11060
|
+
properties: {
|
|
11061
|
+
did: {
|
|
11062
|
+
type: 'string',
|
|
11063
|
+
format: 'did',
|
|
11064
|
+
},
|
|
11065
|
+
disabled: {
|
|
11066
|
+
type: 'boolean',
|
|
11067
|
+
},
|
|
11068
|
+
profile: {
|
|
11069
|
+
type: 'ref',
|
|
11070
|
+
ref: 'lex:app.bsky.actor.defs#profileViewDetailed',
|
|
11071
|
+
},
|
|
11072
|
+
createdAt: {
|
|
11073
|
+
type: 'string',
|
|
11074
|
+
format: 'datetime',
|
|
11075
|
+
},
|
|
11076
|
+
updatedAt: {
|
|
11077
|
+
type: 'string',
|
|
11078
|
+
format: 'datetime',
|
|
11079
|
+
},
|
|
11080
|
+
lastUpdatedBy: {
|
|
11081
|
+
type: 'string',
|
|
11082
|
+
},
|
|
11083
|
+
role: {
|
|
11084
|
+
type: 'string',
|
|
11085
|
+
knownValues: [
|
|
11086
|
+
'lex:tools.ozone.team.defs#roleAdmin',
|
|
11087
|
+
'lex:tools.ozone.team.defs#roleModerator',
|
|
11088
|
+
'lex:tools.ozone.team.defs#roleTriage',
|
|
11089
|
+
],
|
|
11090
|
+
},
|
|
11091
|
+
},
|
|
11092
|
+
},
|
|
11093
|
+
roleAdmin: {
|
|
11094
|
+
type: 'token',
|
|
11095
|
+
description:
|
|
11096
|
+
'Admin role. Highest level of access, can perform all actions.',
|
|
11097
|
+
},
|
|
11098
|
+
roleModerator: {
|
|
11099
|
+
type: 'token',
|
|
11100
|
+
description: 'Moderator role. Can perform most actions.',
|
|
11101
|
+
},
|
|
11102
|
+
roleTriage: {
|
|
11103
|
+
type: 'token',
|
|
11104
|
+
description:
|
|
11105
|
+
'Triage role. Mostly intended for monitoring and escalating issues.',
|
|
11106
|
+
},
|
|
11107
|
+
},
|
|
11108
|
+
},
|
|
11109
|
+
ToolsOzoneTeamDeleteMember: {
|
|
11110
|
+
lexicon: 1,
|
|
11111
|
+
id: 'tools.ozone.team.deleteMember',
|
|
11112
|
+
defs: {
|
|
11113
|
+
main: {
|
|
11114
|
+
type: 'procedure',
|
|
11115
|
+
description: 'Delete a member from ozone team. Requires admin role.',
|
|
11116
|
+
input: {
|
|
11117
|
+
encoding: 'application/json',
|
|
11118
|
+
schema: {
|
|
11119
|
+
type: 'object',
|
|
11120
|
+
required: ['did'],
|
|
11121
|
+
properties: {
|
|
11122
|
+
did: {
|
|
11123
|
+
type: 'string',
|
|
11124
|
+
format: 'did',
|
|
11125
|
+
},
|
|
11126
|
+
},
|
|
11127
|
+
},
|
|
11128
|
+
},
|
|
11129
|
+
errors: [
|
|
11130
|
+
{
|
|
11131
|
+
name: 'MemberNotFound',
|
|
11132
|
+
description: 'The member being deleted does not exist',
|
|
11133
|
+
},
|
|
11134
|
+
],
|
|
11135
|
+
},
|
|
11136
|
+
},
|
|
11137
|
+
},
|
|
11138
|
+
ToolsOzoneTeamListMembers: {
|
|
11139
|
+
lexicon: 1,
|
|
11140
|
+
id: 'tools.ozone.team.listMembers',
|
|
11141
|
+
defs: {
|
|
11142
|
+
main: {
|
|
11143
|
+
type: 'query',
|
|
11144
|
+
description: 'List all members with access to the ozone service.',
|
|
11145
|
+
parameters: {
|
|
11146
|
+
type: 'params',
|
|
11147
|
+
properties: {
|
|
11148
|
+
limit: {
|
|
11149
|
+
type: 'integer',
|
|
11150
|
+
minimum: 1,
|
|
11151
|
+
maximum: 100,
|
|
11152
|
+
default: 50,
|
|
11153
|
+
},
|
|
11154
|
+
cursor: {
|
|
11155
|
+
type: 'string',
|
|
11156
|
+
},
|
|
11157
|
+
},
|
|
11158
|
+
},
|
|
11159
|
+
output: {
|
|
11160
|
+
encoding: 'application/json',
|
|
11161
|
+
schema: {
|
|
11162
|
+
type: 'object',
|
|
11163
|
+
required: ['members'],
|
|
11164
|
+
properties: {
|
|
11165
|
+
cursor: {
|
|
11166
|
+
type: 'string',
|
|
11167
|
+
},
|
|
11168
|
+
members: {
|
|
11169
|
+
type: 'array',
|
|
11170
|
+
items: {
|
|
11171
|
+
type: 'ref',
|
|
11172
|
+
ref: 'lex:tools.ozone.team.defs#member',
|
|
11173
|
+
},
|
|
11174
|
+
},
|
|
11175
|
+
},
|
|
11176
|
+
},
|
|
11177
|
+
},
|
|
11178
|
+
},
|
|
11179
|
+
},
|
|
11180
|
+
},
|
|
11181
|
+
ToolsOzoneTeamUpdateMember: {
|
|
11182
|
+
lexicon: 1,
|
|
11183
|
+
id: 'tools.ozone.team.updateMember',
|
|
11184
|
+
defs: {
|
|
11185
|
+
main: {
|
|
11186
|
+
type: 'procedure',
|
|
11187
|
+
description:
|
|
11188
|
+
'Update a member in the ozone service. Requires admin role.',
|
|
11189
|
+
input: {
|
|
11190
|
+
encoding: 'application/json',
|
|
11191
|
+
schema: {
|
|
11192
|
+
type: 'object',
|
|
11193
|
+
required: ['did'],
|
|
11194
|
+
properties: {
|
|
11195
|
+
did: {
|
|
11196
|
+
type: 'string',
|
|
11197
|
+
format: 'did',
|
|
11198
|
+
},
|
|
11199
|
+
disabled: {
|
|
11200
|
+
type: 'boolean',
|
|
11201
|
+
},
|
|
11202
|
+
role: {
|
|
11203
|
+
type: 'string',
|
|
11204
|
+
knownValues: [
|
|
11205
|
+
'tools.ozone.team.defs#roleAdmin',
|
|
11206
|
+
'tools.ozone.team.defs#roleModerator',
|
|
11207
|
+
'tools.ozone.team.defs#roleTriage',
|
|
11208
|
+
],
|
|
11209
|
+
},
|
|
11210
|
+
},
|
|
11211
|
+
},
|
|
11212
|
+
},
|
|
11213
|
+
output: {
|
|
11214
|
+
encoding: 'application/json',
|
|
11215
|
+
schema: {
|
|
11216
|
+
type: 'ref',
|
|
11217
|
+
ref: 'lex:tools.ozone.team.defs#member',
|
|
11218
|
+
},
|
|
11219
|
+
},
|
|
11220
|
+
errors: [
|
|
11221
|
+
{
|
|
11222
|
+
name: 'MemberNotFound',
|
|
11223
|
+
description: 'The member being updated does not exist in the team',
|
|
11224
|
+
},
|
|
11225
|
+
],
|
|
11226
|
+
},
|
|
11227
|
+
},
|
|
11228
|
+
},
|
|
11009
11229
|
}
|
|
11010
11230
|
export const schemas: LexiconDoc[] = Object.values(schemaDict) as LexiconDoc[]
|
|
11011
11231
|
export const lexicons: Lexicons = new Lexicons(schemas)
|
|
@@ -11216,4 +11436,9 @@ export const ids = {
|
|
|
11216
11436
|
ToolsOzoneModerationQueryStatuses: 'tools.ozone.moderation.queryStatuses',
|
|
11217
11437
|
ToolsOzoneModerationSearchRepos: 'tools.ozone.moderation.searchRepos',
|
|
11218
11438
|
ToolsOzoneServerGetConfig: 'tools.ozone.server.getConfig',
|
|
11439
|
+
ToolsOzoneTeamAddMember: 'tools.ozone.team.addMember',
|
|
11440
|
+
ToolsOzoneTeamDefs: 'tools.ozone.team.defs',
|
|
11441
|
+
ToolsOzoneTeamDeleteMember: 'tools.ozone.team.deleteMember',
|
|
11442
|
+
ToolsOzoneTeamListMembers: 'tools.ozone.team.listMembers',
|
|
11443
|
+
ToolsOzoneTeamUpdateMember: 'tools.ozone.team.updateMember',
|
|
11219
11444
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
10
|
+
import * as ToolsOzoneTeamDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {}
|
|
13
|
+
|
|
14
|
+
export interface InputSchema {
|
|
15
|
+
did: string
|
|
16
|
+
role:
|
|
17
|
+
| 'tools.ozone.team.defs#roleAdmin'
|
|
18
|
+
| 'tools.ozone.team.defs#roleModerator'
|
|
19
|
+
| 'tools.ozone.team.defs#roleTriage'
|
|
20
|
+
| (string & {})
|
|
21
|
+
[k: string]: unknown
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type OutputSchema = ToolsOzoneTeamDefs.Member
|
|
25
|
+
|
|
26
|
+
export interface HandlerInput {
|
|
27
|
+
encoding: 'application/json'
|
|
28
|
+
body: InputSchema
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface HandlerSuccess {
|
|
32
|
+
encoding: 'application/json'
|
|
33
|
+
body: OutputSchema
|
|
34
|
+
headers?: { [key: string]: string }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HandlerError {
|
|
38
|
+
status: number
|
|
39
|
+
message?: string
|
|
40
|
+
error?: 'MemberAlreadyExists'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
44
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
45
|
+
auth: HA
|
|
46
|
+
params: QueryParams
|
|
47
|
+
input: HandlerInput
|
|
48
|
+
req: express.Request
|
|
49
|
+
res: express.Response
|
|
50
|
+
}
|
|
51
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
52
|
+
ctx: HandlerReqCtx<HA>,
|
|
53
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
5
|
+
import { lexicons } from '../../../../lexicons'
|
|
6
|
+
import { isObj, hasProp } from '../../../../util'
|
|
7
|
+
import { CID } from 'multiformats/cid'
|
|
8
|
+
import * as AppBskyActorDefs from '../../../app/bsky/actor/defs'
|
|
9
|
+
|
|
10
|
+
export interface Member {
|
|
11
|
+
did: string
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
profile?: AppBskyActorDefs.ProfileViewDetailed
|
|
14
|
+
createdAt?: string
|
|
15
|
+
updatedAt?: string
|
|
16
|
+
lastUpdatedBy?: string
|
|
17
|
+
role:
|
|
18
|
+
| 'lex:tools.ozone.team.defs#roleAdmin'
|
|
19
|
+
| 'lex:tools.ozone.team.defs#roleModerator'
|
|
20
|
+
| 'lex:tools.ozone.team.defs#roleTriage'
|
|
21
|
+
| (string & {})
|
|
22
|
+
[k: string]: unknown
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isMember(v: unknown): v is Member {
|
|
26
|
+
return (
|
|
27
|
+
isObj(v) &&
|
|
28
|
+
hasProp(v, '$type') &&
|
|
29
|
+
v.$type === 'tools.ozone.team.defs#member'
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function validateMember(v: unknown): ValidationResult {
|
|
34
|
+
return lexicons.validate('tools.ozone.team.defs#member', v)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Admin role. Highest level of access, can perform all actions. */
|
|
38
|
+
export const ROLEADMIN = 'tools.ozone.team.defs#roleAdmin'
|
|
39
|
+
/** Moderator role. Can perform most actions. */
|
|
40
|
+
export const ROLEMODERATOR = 'tools.ozone.team.defs#roleModerator'
|
|
41
|
+
/** Triage role. Mostly intended for monitoring and escalating issues. */
|
|
42
|
+
export const ROLETRIAGE = 'tools.ozone.team.defs#roleTriage'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
10
|
+
|
|
11
|
+
export interface QueryParams {}
|
|
12
|
+
|
|
13
|
+
export interface InputSchema {
|
|
14
|
+
did: string
|
|
15
|
+
[k: string]: unknown
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface HandlerInput {
|
|
19
|
+
encoding: 'application/json'
|
|
20
|
+
body: InputSchema
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface HandlerError {
|
|
24
|
+
status: number
|
|
25
|
+
message?: string
|
|
26
|
+
error?: 'MemberNotFound'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type HandlerOutput = HandlerError | void
|
|
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> = (
|
|
38
|
+
ctx: HandlerReqCtx<HA>,
|
|
39
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
10
|
+
import * as ToolsOzoneTeamDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {
|
|
13
|
+
limit: number
|
|
14
|
+
cursor?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type InputSchema = undefined
|
|
18
|
+
|
|
19
|
+
export interface OutputSchema {
|
|
20
|
+
cursor?: string
|
|
21
|
+
members: ToolsOzoneTeamDefs.Member[]
|
|
22
|
+
[k: string]: unknown
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type HandlerInput = undefined
|
|
26
|
+
|
|
27
|
+
export interface HandlerSuccess {
|
|
28
|
+
encoding: 'application/json'
|
|
29
|
+
body: OutputSchema
|
|
30
|
+
headers?: { [key: string]: string }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface HandlerError {
|
|
34
|
+
status: number
|
|
35
|
+
message?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
39
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
40
|
+
auth: HA
|
|
41
|
+
params: QueryParams
|
|
42
|
+
input: HandlerInput
|
|
43
|
+
req: express.Request
|
|
44
|
+
res: express.Response
|
|
45
|
+
}
|
|
46
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
47
|
+
ctx: HandlerReqCtx<HA>,
|
|
48
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
|
|
10
|
+
import * as ToolsOzoneTeamDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {}
|
|
13
|
+
|
|
14
|
+
export interface InputSchema {
|
|
15
|
+
did: string
|
|
16
|
+
disabled?: boolean
|
|
17
|
+
role?:
|
|
18
|
+
| 'tools.ozone.team.defs#roleAdmin'
|
|
19
|
+
| 'tools.ozone.team.defs#roleModerator'
|
|
20
|
+
| 'tools.ozone.team.defs#roleTriage'
|
|
21
|
+
| (string & {})
|
|
22
|
+
[k: string]: unknown
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type OutputSchema = ToolsOzoneTeamDefs.Member
|
|
26
|
+
|
|
27
|
+
export interface HandlerInput {
|
|
28
|
+
encoding: 'application/json'
|
|
29
|
+
body: InputSchema
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface HandlerSuccess {
|
|
33
|
+
encoding: 'application/json'
|
|
34
|
+
body: OutputSchema
|
|
35
|
+
headers?: { [key: string]: string }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface HandlerError {
|
|
39
|
+
status: number
|
|
40
|
+
message?: string
|
|
41
|
+
error?: 'MemberNotFound'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
45
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
46
|
+
auth: HA
|
|
47
|
+
params: QueryParams
|
|
48
|
+
input: HandlerInput
|
|
49
|
+
req: express.Request
|
|
50
|
+
res: express.Response
|
|
51
|
+
}
|
|
52
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
53
|
+
ctx: HandlerReqCtx<HA>,
|
|
54
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import Database from '../db'
|
|
2
|
+
import { Selectable } from 'kysely'
|
|
3
|
+
import { Member } from '../db/schema/member'
|
|
4
|
+
import { Member as TeamMember } from '../lexicon/types/tools/ozone/team/defs'
|
|
5
|
+
import { ProfileViewDetailed } from '../lexicon/types/app/bsky/actor/defs'
|
|
6
|
+
import { InvalidRequestError } from '@atproto/xrpc-server'
|
|
7
|
+
import { chunkArray } from '@atproto/common'
|
|
8
|
+
import AppContext from '../context'
|
|
9
|
+
import { httpLogger } from '../logger'
|
|
10
|
+
|
|
11
|
+
export type TeamServiceCreator = (db: Database) => TeamService
|
|
12
|
+
|
|
13
|
+
export class TeamService {
|
|
14
|
+
constructor(public db: Database) {}
|
|
15
|
+
|
|
16
|
+
static creator() {
|
|
17
|
+
return (db: Database) => new TeamService(db)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async list({
|
|
21
|
+
cursor,
|
|
22
|
+
limit = 25,
|
|
23
|
+
}: {
|
|
24
|
+
cursor?: string
|
|
25
|
+
limit?: number
|
|
26
|
+
}): Promise<{ members: Selectable<Member>[]; cursor?: string }> {
|
|
27
|
+
let builder = this.db.db.selectFrom('member').selectAll()
|
|
28
|
+
if (cursor) {
|
|
29
|
+
builder = builder.where('createdAt', '>', new Date(cursor))
|
|
30
|
+
}
|
|
31
|
+
const members = await builder
|
|
32
|
+
.limit(limit)
|
|
33
|
+
.orderBy('createdAt', 'asc')
|
|
34
|
+
.execute()
|
|
35
|
+
|
|
36
|
+
return { members, cursor: members.at(-1)?.createdAt.toISOString() }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async create({
|
|
40
|
+
role,
|
|
41
|
+
did,
|
|
42
|
+
disabled,
|
|
43
|
+
updatedAt,
|
|
44
|
+
createdAt,
|
|
45
|
+
lastUpdatedBy,
|
|
46
|
+
}: Omit<Selectable<Member>, 'createdAt' | 'updatedAt'> & {
|
|
47
|
+
createdAt?: Date
|
|
48
|
+
updatedAt?: Date
|
|
49
|
+
}): Promise<Selectable<Member>> {
|
|
50
|
+
const now = new Date()
|
|
51
|
+
const newMember = await this.db.db
|
|
52
|
+
.insertInto('member')
|
|
53
|
+
.values({
|
|
54
|
+
role,
|
|
55
|
+
did,
|
|
56
|
+
disabled,
|
|
57
|
+
lastUpdatedBy,
|
|
58
|
+
updatedAt: updatedAt || now,
|
|
59
|
+
createdAt: createdAt || now,
|
|
60
|
+
})
|
|
61
|
+
.returningAll()
|
|
62
|
+
.executeTakeFirstOrThrow()
|
|
63
|
+
|
|
64
|
+
return newMember
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async upsert({
|
|
68
|
+
role,
|
|
69
|
+
did,
|
|
70
|
+
lastUpdatedBy,
|
|
71
|
+
}: Pick<
|
|
72
|
+
Selectable<Member>,
|
|
73
|
+
'role' | 'did' | 'lastUpdatedBy'
|
|
74
|
+
>): Promise<void> {
|
|
75
|
+
const now = new Date()
|
|
76
|
+
await this.db.db
|
|
77
|
+
.insertInto('member')
|
|
78
|
+
.values({
|
|
79
|
+
role,
|
|
80
|
+
did,
|
|
81
|
+
lastUpdatedBy,
|
|
82
|
+
disabled: false,
|
|
83
|
+
updatedAt: now,
|
|
84
|
+
createdAt: now,
|
|
85
|
+
})
|
|
86
|
+
.onConflict((oc) =>
|
|
87
|
+
oc.column('did').doUpdateSet({ role, updatedAt: now, lastUpdatedBy }),
|
|
88
|
+
)
|
|
89
|
+
.execute()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async update(
|
|
93
|
+
did: string,
|
|
94
|
+
updates: Partial<
|
|
95
|
+
Pick<
|
|
96
|
+
Selectable<Member>,
|
|
97
|
+
'role' | 'disabled' | 'lastUpdatedBy' | 'updatedAt'
|
|
98
|
+
>
|
|
99
|
+
>,
|
|
100
|
+
): Promise<Selectable<Member>> {
|
|
101
|
+
const { role, disabled, lastUpdatedBy, updatedAt = new Date() } = updates
|
|
102
|
+
const updatedMember = await this.db.db
|
|
103
|
+
.updateTable('member')
|
|
104
|
+
.where('did', '=', did)
|
|
105
|
+
.set({
|
|
106
|
+
role,
|
|
107
|
+
disabled,
|
|
108
|
+
lastUpdatedBy,
|
|
109
|
+
updatedAt,
|
|
110
|
+
})
|
|
111
|
+
.returningAll()
|
|
112
|
+
.executeTakeFirstOrThrow()
|
|
113
|
+
|
|
114
|
+
return updatedMember
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async delete(did: string): Promise<void> {
|
|
118
|
+
await this.db.db.deleteFrom('member').where('did', '=', did).execute()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async assertCanDelete(did: string): Promise<void> {
|
|
122
|
+
const memberExists = await this.doesMemberExist(did)
|
|
123
|
+
|
|
124
|
+
if (!memberExists) {
|
|
125
|
+
throw new InvalidRequestError('member not found', 'MemberNotFound')
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async doesMemberExist(did: string): Promise<boolean> {
|
|
130
|
+
const member = await this.db.db
|
|
131
|
+
.selectFrom('member')
|
|
132
|
+
.select('did')
|
|
133
|
+
.where('did', '=', did)
|
|
134
|
+
.executeTakeFirst()
|
|
135
|
+
|
|
136
|
+
return !!member
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async getMember(did: string): Promise<Selectable<Member> | undefined> {
|
|
140
|
+
const member = await this.db.db
|
|
141
|
+
.selectFrom('member')
|
|
142
|
+
.selectAll()
|
|
143
|
+
.where('did', '=', did)
|
|
144
|
+
.executeTakeFirst()
|
|
145
|
+
|
|
146
|
+
return member
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getMemberRole(member?: Selectable<Member>) {
|
|
150
|
+
const isAdmin = member?.role === 'tools.ozone.team.defs#roleAdmin'
|
|
151
|
+
const isModerator =
|
|
152
|
+
isAdmin || member?.role === 'tools.ozone.team.defs#roleModerator'
|
|
153
|
+
const isTriage =
|
|
154
|
+
isModerator || member?.role === 'tools.ozone.team.defs#roleTriage'
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
isModerator,
|
|
158
|
+
isAdmin,
|
|
159
|
+
isTriage,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// getProfiles() only allows 25 DIDs at a time so we need to query in chunks
|
|
164
|
+
async getProfiles(
|
|
165
|
+
dids: string[],
|
|
166
|
+
ctx: AppContext,
|
|
167
|
+
): Promise<Map<string, ProfileViewDetailed>> {
|
|
168
|
+
const profiles = new Map<string, ProfileViewDetailed>()
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
const headers = await ctx.appviewAuth()
|
|
172
|
+
|
|
173
|
+
for (const actors of chunkArray(dids, 25)) {
|
|
174
|
+
const { data } = await ctx.appviewAgent.api.app.bsky.actor.getProfiles(
|
|
175
|
+
{ actors },
|
|
176
|
+
headers,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
data.profiles.forEach((profile) => {
|
|
180
|
+
profiles.set(profile.did, profile)
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
} catch (error) {
|
|
184
|
+
httpLogger.error(
|
|
185
|
+
{ error, dids },
|
|
186
|
+
'Failed to get profiles for team members',
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return profiles
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async view(
|
|
194
|
+
members: Selectable<Member>[],
|
|
195
|
+
ctx: AppContext,
|
|
196
|
+
): Promise<TeamMember[]> {
|
|
197
|
+
const profiles = await this.getProfiles(
|
|
198
|
+
members.map(({ did }) => did),
|
|
199
|
+
ctx,
|
|
200
|
+
)
|
|
201
|
+
return members.map((member) => {
|
|
202
|
+
return {
|
|
203
|
+
did: member.did,
|
|
204
|
+
role: member.role,
|
|
205
|
+
disabled: member.disabled,
|
|
206
|
+
profile: profiles.get(member.did),
|
|
207
|
+
createdAt: member.createdAt.toISOString(),
|
|
208
|
+
updatedAt: member.updatedAt.toISOString(),
|
|
209
|
+
lastUpdatedBy: member.lastUpdatedBy,
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
}
|