@atproto/pds 0.4.68 → 0.4.70
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 +26 -0
- package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getPostThread.js +11 -6
- package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
- package/dist/config/config.d.ts +1 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +3 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/env.d.ts +1 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +1 -0
- package/dist/config/env.js.map +1 -1
- package/dist/context.d.ts +2 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +8 -1
- package/dist/context.js.map +1 -1
- package/dist/lexicon/index.d.ts +13 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +36 -1
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +396 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +439 -3
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getConfig.d.ts +34 -0
- package/dist/lexicon/types/app/bsky/unspecced/getConfig.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getConfig.js +3 -0
- package/dist/lexicon/types/app/bsky/unspecced/getConfig.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts +60 -2
- package/dist/lexicon/types/tools/ozone/moderation/defs.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/defs.js +50 -0
- package/dist/lexicon/types/tools/ozone/moderation/defs.js.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/emitEvent.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/moderation/queryStatuses.d.ts +10 -0
- package/dist/lexicon/types/tools/ozone/moderation/queryStatuses.d.ts.map +1 -1
- package/dist/lexicon/types/tools/ozone/setting/defs.d.ts +20 -0
- package/dist/lexicon/types/tools/ozone/setting/defs.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/defs.js +15 -0
- package/dist/lexicon/types/tools/ozone/setting/defs.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/listOptions.d.ts +43 -0
- package/dist/lexicon/types/tools/ozone/setting/listOptions.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/listOptions.js +3 -0
- package/dist/lexicon/types/tools/ozone/setting/listOptions.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/removeOptions.d.ts +40 -0
- package/dist/lexicon/types/tools/ozone/setting/removeOptions.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/removeOptions.js +3 -0
- package/dist/lexicon/types/tools/ozone/setting/removeOptions.js.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/upsertOption.d.ts +45 -0
- package/dist/lexicon/types/tools/ozone/setting/upsertOption.d.ts.map +1 -0
- package/dist/lexicon/types/tools/ozone/setting/upsertOption.js +3 -0
- package/dist/lexicon/types/tools/ozone/setting/upsertOption.js.map +1 -0
- package/dist/pipethrough.d.ts +0 -1
- package/dist/pipethrough.d.ts.map +1 -1
- package/dist/pipethrough.js +11 -10
- package/dist/pipethrough.js.map +1 -1
- package/example.env +1 -1
- package/package.json +11 -11
- package/src/api/app/bsky/feed/getPostThread.ts +15 -4
- package/src/config/config.ts +5 -0
- package/src/config/env.ts +2 -0
- package/src/context.ts +11 -3
- package/src/lexicon/index.ts +58 -0
- package/src/lexicon/lexicons.ts +449 -3
- package/src/lexicon/types/app/bsky/unspecced/getConfig.ts +43 -0
- package/src/lexicon/types/tools/ozone/moderation/defs.ts +132 -0
- package/src/lexicon/types/tools/ozone/moderation/emitEvent.ts +3 -0
- package/src/lexicon/types/tools/ozone/moderation/queryStatuses.ts +10 -0
- package/src/lexicon/types/tools/ozone/setting/defs.ts +37 -0
- package/src/lexicon/types/tools/ozone/setting/listOptions.ts +53 -0
- package/src/lexicon/types/tools/ozone/setting/removeOptions.ts +49 -0
- package/src/lexicon/types/tools/ozone/setting/upsertOption.ts +58 -0
- package/src/pipethrough.ts +13 -12
- package/tests/proxied/__snapshots__/admin.test.ts.snap +12 -0
- package/tests/proxied/proxy-catchall.test.ts +1 -1
- package/tests/proxied/read-after-write.test.ts +20 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -30,6 +30,9 @@ export interface ModEventView {
|
|
|
30
30
|
| ModEventResolveAppeal
|
|
31
31
|
| ModEventDivert
|
|
32
32
|
| ModEventTag
|
|
33
|
+
| AccountEvent
|
|
34
|
+
| IdentityEvent
|
|
35
|
+
| RecordEvent
|
|
33
36
|
| { $type: string; [k: string]: unknown }
|
|
34
37
|
subject:
|
|
35
38
|
| ComAtprotoAdminDefs.RepoRef
|
|
@@ -74,6 +77,9 @@ export interface ModEventViewDetail {
|
|
|
74
77
|
| ModEventResolveAppeal
|
|
75
78
|
| ModEventDivert
|
|
76
79
|
| ModEventTag
|
|
80
|
+
| AccountEvent
|
|
81
|
+
| IdentityEvent
|
|
82
|
+
| RecordEvent
|
|
77
83
|
| { $type: string; [k: string]: unknown }
|
|
78
84
|
subject:
|
|
79
85
|
| RepoView
|
|
@@ -105,6 +111,10 @@ export interface SubjectStatusView {
|
|
|
105
111
|
| ComAtprotoAdminDefs.RepoRef
|
|
106
112
|
| ComAtprotoRepoStrongRef.Main
|
|
107
113
|
| { $type: string; [k: string]: unknown }
|
|
114
|
+
hosting?:
|
|
115
|
+
| AccountHosting
|
|
116
|
+
| RecordHosting
|
|
117
|
+
| { $type: string; [k: string]: unknown }
|
|
108
118
|
subjectBlobCids?: string[]
|
|
109
119
|
subjectRepoHandle?: string
|
|
110
120
|
/** Timestamp referencing when the last update was made to the moderation status of the subject */
|
|
@@ -472,6 +482,78 @@ export function validateModEventTag(v: unknown): ValidationResult {
|
|
|
472
482
|
return lexicons.validate('tools.ozone.moderation.defs#modEventTag', v)
|
|
473
483
|
}
|
|
474
484
|
|
|
485
|
+
/** Logs account status related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking. */
|
|
486
|
+
export interface AccountEvent {
|
|
487
|
+
comment?: string
|
|
488
|
+
/** Indicates that the account has a repository which can be fetched from the host that emitted this event. */
|
|
489
|
+
active: boolean
|
|
490
|
+
status?:
|
|
491
|
+
| 'unknown'
|
|
492
|
+
| 'deactivated'
|
|
493
|
+
| 'deleted'
|
|
494
|
+
| 'takendown'
|
|
495
|
+
| 'suspended'
|
|
496
|
+
| 'tombstoned'
|
|
497
|
+
| (string & {})
|
|
498
|
+
timestamp: string
|
|
499
|
+
[k: string]: unknown
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export function isAccountEvent(v: unknown): v is AccountEvent {
|
|
503
|
+
return (
|
|
504
|
+
isObj(v) &&
|
|
505
|
+
hasProp(v, '$type') &&
|
|
506
|
+
v.$type === 'tools.ozone.moderation.defs#accountEvent'
|
|
507
|
+
)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export function validateAccountEvent(v: unknown): ValidationResult {
|
|
511
|
+
return lexicons.validate('tools.ozone.moderation.defs#accountEvent', v)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/** Logs identity related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking. */
|
|
515
|
+
export interface IdentityEvent {
|
|
516
|
+
comment?: string
|
|
517
|
+
handle?: string
|
|
518
|
+
pdsHost?: string
|
|
519
|
+
tombstone?: boolean
|
|
520
|
+
timestamp: string
|
|
521
|
+
[k: string]: unknown
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export function isIdentityEvent(v: unknown): v is IdentityEvent {
|
|
525
|
+
return (
|
|
526
|
+
isObj(v) &&
|
|
527
|
+
hasProp(v, '$type') &&
|
|
528
|
+
v.$type === 'tools.ozone.moderation.defs#identityEvent'
|
|
529
|
+
)
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export function validateIdentityEvent(v: unknown): ValidationResult {
|
|
533
|
+
return lexicons.validate('tools.ozone.moderation.defs#identityEvent', v)
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/** Logs lifecycle event on a record subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking. */
|
|
537
|
+
export interface RecordEvent {
|
|
538
|
+
comment?: string
|
|
539
|
+
op: 'create' | 'update' | 'delete' | (string & {})
|
|
540
|
+
cid?: string
|
|
541
|
+
timestamp: string
|
|
542
|
+
[k: string]: unknown
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export function isRecordEvent(v: unknown): v is RecordEvent {
|
|
546
|
+
return (
|
|
547
|
+
isObj(v) &&
|
|
548
|
+
hasProp(v, '$type') &&
|
|
549
|
+
v.$type === 'tools.ozone.moderation.defs#recordEvent'
|
|
550
|
+
)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
export function validateRecordEvent(v: unknown): ValidationResult {
|
|
554
|
+
return lexicons.validate('tools.ozone.moderation.defs#recordEvent', v)
|
|
555
|
+
}
|
|
556
|
+
|
|
475
557
|
export interface RepoView {
|
|
476
558
|
did: string
|
|
477
559
|
handle: string
|
|
@@ -483,6 +565,7 @@ export interface RepoView {
|
|
|
483
565
|
invitesDisabled?: boolean
|
|
484
566
|
inviteNote?: string
|
|
485
567
|
deactivatedAt?: string
|
|
568
|
+
threatSignatures?: ComAtprotoAdminDefs.ThreatSignature[]
|
|
486
569
|
[k: string]: unknown
|
|
487
570
|
}
|
|
488
571
|
|
|
@@ -512,6 +595,7 @@ export interface RepoViewDetail {
|
|
|
512
595
|
inviteNote?: string
|
|
513
596
|
emailConfirmedAt?: string
|
|
514
597
|
deactivatedAt?: string
|
|
598
|
+
threatSignatures?: ComAtprotoAdminDefs.ThreatSignature[]
|
|
515
599
|
[k: string]: unknown
|
|
516
600
|
}
|
|
517
601
|
|
|
@@ -703,3 +787,51 @@ export function isVideoDetails(v: unknown): v is VideoDetails {
|
|
|
703
787
|
export function validateVideoDetails(v: unknown): ValidationResult {
|
|
704
788
|
return lexicons.validate('tools.ozone.moderation.defs#videoDetails', v)
|
|
705
789
|
}
|
|
790
|
+
|
|
791
|
+
export interface AccountHosting {
|
|
792
|
+
status:
|
|
793
|
+
| 'takendown'
|
|
794
|
+
| 'suspended'
|
|
795
|
+
| 'deleted'
|
|
796
|
+
| 'deactivated'
|
|
797
|
+
| 'unknown'
|
|
798
|
+
| (string & {})
|
|
799
|
+
updatedAt?: string
|
|
800
|
+
createdAt?: string
|
|
801
|
+
deletedAt?: string
|
|
802
|
+
deactivatedAt?: string
|
|
803
|
+
reactivatedAt?: string
|
|
804
|
+
[k: string]: unknown
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
export function isAccountHosting(v: unknown): v is AccountHosting {
|
|
808
|
+
return (
|
|
809
|
+
isObj(v) &&
|
|
810
|
+
hasProp(v, '$type') &&
|
|
811
|
+
v.$type === 'tools.ozone.moderation.defs#accountHosting'
|
|
812
|
+
)
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
export function validateAccountHosting(v: unknown): ValidationResult {
|
|
816
|
+
return lexicons.validate('tools.ozone.moderation.defs#accountHosting', v)
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
export interface RecordHosting {
|
|
820
|
+
status: 'deleted' | 'unknown' | (string & {})
|
|
821
|
+
updatedAt?: string
|
|
822
|
+
createdAt?: string
|
|
823
|
+
deletedAt?: string
|
|
824
|
+
[k: string]: unknown
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
export function isRecordHosting(v: unknown): v is RecordHosting {
|
|
828
|
+
return (
|
|
829
|
+
isObj(v) &&
|
|
830
|
+
hasProp(v, '$type') &&
|
|
831
|
+
v.$type === 'tools.ozone.moderation.defs#recordHosting'
|
|
832
|
+
)
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
export function validateRecordHosting(v: unknown): ValidationResult {
|
|
836
|
+
return lexicons.validate('tools.ozone.moderation.defs#recordHosting', v)
|
|
837
|
+
}
|
|
@@ -29,6 +29,9 @@ export interface InputSchema {
|
|
|
29
29
|
| ToolsOzoneModerationDefs.ModEventResolveAppeal
|
|
30
30
|
| ToolsOzoneModerationDefs.ModEventEmail
|
|
31
31
|
| ToolsOzoneModerationDefs.ModEventTag
|
|
32
|
+
| ToolsOzoneModerationDefs.AccountEvent
|
|
33
|
+
| ToolsOzoneModerationDefs.IdentityEvent
|
|
34
|
+
| ToolsOzoneModerationDefs.RecordEvent
|
|
32
35
|
| { $type: string; [k: string]: unknown }
|
|
33
36
|
subject:
|
|
34
37
|
| ComAtprotoAdminDefs.RepoRef
|
|
@@ -22,6 +22,16 @@ export interface QueryParams {
|
|
|
22
22
|
reportedBefore?: string
|
|
23
23
|
/** Search subjects reviewed after a given timestamp */
|
|
24
24
|
reviewedAfter?: string
|
|
25
|
+
/** Search subjects where the associated record/account was deleted after a given timestamp */
|
|
26
|
+
hostingDeletedAfter?: string
|
|
27
|
+
/** Search subjects where the associated record/account was deleted before a given timestamp */
|
|
28
|
+
hostingDeletedBefore?: string
|
|
29
|
+
/** Search subjects where the associated record/account was updated after a given timestamp */
|
|
30
|
+
hostingUpdatedAfter?: string
|
|
31
|
+
/** Search subjects where the associated record/account was updated before a given timestamp */
|
|
32
|
+
hostingUpdatedBefore?: string
|
|
33
|
+
/** Search subjects by the status of the associated record/account */
|
|
34
|
+
hostingStatuses?: string[]
|
|
25
35
|
/** Search subjects reviewed before a given timestamp */
|
|
26
36
|
reviewedBefore?: string
|
|
27
37
|
/** By default, we don't include muted subjects in the results. Set this to true to include them. */
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
|
|
9
|
+
export interface Option {
|
|
10
|
+
key: string
|
|
11
|
+
did: string
|
|
12
|
+
value: {}
|
|
13
|
+
description?: string
|
|
14
|
+
createdAt?: string
|
|
15
|
+
updatedAt?: string
|
|
16
|
+
managerRole?:
|
|
17
|
+
| 'tools.ozone.team.defs#roleModerator'
|
|
18
|
+
| 'tools.ozone.team.defs#roleTriage'
|
|
19
|
+
| 'tools.ozone.team.defs#roleAdmin'
|
|
20
|
+
| (string & {})
|
|
21
|
+
scope: 'instance' | 'personal' | (string & {})
|
|
22
|
+
createdBy: string
|
|
23
|
+
lastUpdatedBy: string
|
|
24
|
+
[k: string]: unknown
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isOption(v: unknown): v is Option {
|
|
28
|
+
return (
|
|
29
|
+
isObj(v) &&
|
|
30
|
+
hasProp(v, '$type') &&
|
|
31
|
+
v.$type === 'tools.ozone.setting.defs#option'
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function validateOption(v: unknown): ValidationResult {
|
|
36
|
+
return lexicons.validate('tools.ozone.setting.defs#option', v)
|
|
37
|
+
}
|
|
@@ -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 ToolsOzoneSettingDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {
|
|
13
|
+
limit: number
|
|
14
|
+
cursor?: string
|
|
15
|
+
scope: 'instance' | 'personal' | (string & {})
|
|
16
|
+
/** Filter keys by prefix */
|
|
17
|
+
prefix?: string
|
|
18
|
+
/** Filter for only the specified keys. Ignored if prefix is provided */
|
|
19
|
+
keys?: string[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type InputSchema = undefined
|
|
23
|
+
|
|
24
|
+
export interface OutputSchema {
|
|
25
|
+
cursor?: string
|
|
26
|
+
options: ToolsOzoneSettingDefs.Option[]
|
|
27
|
+
[k: string]: unknown
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type HandlerInput = undefined
|
|
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
|
+
}
|
|
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,49 @@
|
|
|
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
|
+
keys: string[]
|
|
15
|
+
scope: 'instance' | 'personal' | (string & {})
|
|
16
|
+
[k: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface OutputSchema {
|
|
20
|
+
[k: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface HandlerInput {
|
|
24
|
+
encoding: 'application/json'
|
|
25
|
+
body: InputSchema
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface HandlerSuccess {
|
|
29
|
+
encoding: 'application/json'
|
|
30
|
+
body: OutputSchema
|
|
31
|
+
headers?: { [key: string]: string }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface HandlerError {
|
|
35
|
+
status: number
|
|
36
|
+
message?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
40
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
41
|
+
auth: HA
|
|
42
|
+
params: QueryParams
|
|
43
|
+
input: HandlerInput
|
|
44
|
+
req: express.Request
|
|
45
|
+
res: express.Response
|
|
46
|
+
}
|
|
47
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
48
|
+
ctx: HandlerReqCtx<HA>,
|
|
49
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,58 @@
|
|
|
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 ToolsOzoneSettingDefs from './defs'
|
|
11
|
+
|
|
12
|
+
export interface QueryParams {}
|
|
13
|
+
|
|
14
|
+
export interface InputSchema {
|
|
15
|
+
key: string
|
|
16
|
+
scope: 'instance' | 'personal' | (string & {})
|
|
17
|
+
value: {}
|
|
18
|
+
description?: string
|
|
19
|
+
managerRole?:
|
|
20
|
+
| 'tools.ozone.team.defs#roleModerator'
|
|
21
|
+
| 'tools.ozone.team.defs#roleTriage'
|
|
22
|
+
| 'tools.ozone.team.defs#roleAdmin'
|
|
23
|
+
| (string & {})
|
|
24
|
+
[k: string]: unknown
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface OutputSchema {
|
|
28
|
+
option: ToolsOzoneSettingDefs.Option
|
|
29
|
+
[k: string]: unknown
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface HandlerInput {
|
|
33
|
+
encoding: 'application/json'
|
|
34
|
+
body: InputSchema
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface HandlerSuccess {
|
|
38
|
+
encoding: 'application/json'
|
|
39
|
+
body: OutputSchema
|
|
40
|
+
headers?: { [key: string]: string }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface HandlerError {
|
|
44
|
+
status: number
|
|
45
|
+
message?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough
|
|
49
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
50
|
+
auth: HA
|
|
51
|
+
params: QueryParams
|
|
52
|
+
input: HandlerInput
|
|
53
|
+
req: express.Request
|
|
54
|
+
res: express.Response
|
|
55
|
+
}
|
|
56
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
57
|
+
ctx: HandlerReqCtx<HA>,
|
|
58
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
package/src/pipethrough.ts
CHANGED
|
@@ -357,9 +357,9 @@ async function pipethroughRequest(
|
|
|
357
357
|
|
|
358
358
|
function handleUpstreamRequestError(
|
|
359
359
|
err: unknown,
|
|
360
|
-
message = '
|
|
360
|
+
message = 'Upstream service unreachable',
|
|
361
361
|
): never {
|
|
362
|
-
httpLogger.
|
|
362
|
+
httpLogger.error({ err }, message)
|
|
363
363
|
throw new XRPCServerError(ResponseType.UpstreamFailure, message, undefined, {
|
|
364
364
|
cause: err,
|
|
365
365
|
})
|
|
@@ -520,18 +520,11 @@ async function tryParsingError(
|
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
-
|
|
523
|
+
async function bufferUpstreamResponse(
|
|
524
524
|
readable: Readable,
|
|
525
525
|
contentEncoding?: string | string[],
|
|
526
526
|
): Promise<Buffer> {
|
|
527
527
|
try {
|
|
528
|
-
// Needed for type-safety (should never happen irl)
|
|
529
|
-
if (Array.isArray(contentEncoding)) {
|
|
530
|
-
throw new TypeError(
|
|
531
|
-
'upstream service returned multiple content-encoding headers',
|
|
532
|
-
)
|
|
533
|
-
}
|
|
534
|
-
|
|
535
528
|
return await streamToNodeBuffer(decodeStream(readable, contentEncoding))
|
|
536
529
|
} catch (err) {
|
|
537
530
|
if (!readable.destroyed) readable.destroy()
|
|
@@ -561,7 +554,11 @@ export async function asPipeThroughBuffer(
|
|
|
561
554
|
// Response parsing/forwarding
|
|
562
555
|
// -------------------
|
|
563
556
|
|
|
564
|
-
const RES_HEADERS_TO_FORWARD = [
|
|
557
|
+
const RES_HEADERS_TO_FORWARD = [
|
|
558
|
+
'atproto-repo-rev',
|
|
559
|
+
'atproto-content-labelers',
|
|
560
|
+
'retry-after',
|
|
561
|
+
]
|
|
565
562
|
|
|
566
563
|
function* responseHeaders(
|
|
567
564
|
headers: IncomingHttpHeaders,
|
|
@@ -584,7 +581,11 @@ function* responseHeaders(
|
|
|
584
581
|
for (let i = 0; i < RES_HEADERS_TO_FORWARD.length; i++) {
|
|
585
582
|
const name = RES_HEADERS_TO_FORWARD[i]
|
|
586
583
|
const val = headers[name]
|
|
587
|
-
|
|
584
|
+
|
|
585
|
+
if (val != null) {
|
|
586
|
+
const value: string = Array.isArray(val) ? val.join(',') : val
|
|
587
|
+
yield [name, value]
|
|
588
|
+
}
|
|
588
589
|
}
|
|
589
590
|
}
|
|
590
591
|
|
|
@@ -122,6 +122,10 @@ Object {
|
|
|
122
122
|
"moderation": Object {
|
|
123
123
|
"subjectStatus": Object {
|
|
124
124
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
125
|
+
"hosting": Object {
|
|
126
|
+
"$type": "tools.ozone.moderation.defs#accountHosting",
|
|
127
|
+
"status": "unknown",
|
|
128
|
+
},
|
|
125
129
|
"id": 1,
|
|
126
130
|
"lastReportedAt": "1970-01-01T00:00:00.000Z",
|
|
127
131
|
"lastReviewedAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -214,6 +218,10 @@ Object {
|
|
|
214
218
|
"moderation": Object {
|
|
215
219
|
"subjectStatus": Object {
|
|
216
220
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
221
|
+
"hosting": Object {
|
|
222
|
+
"$type": "tools.ozone.moderation.defs#recordHosting",
|
|
223
|
+
"status": "unknown",
|
|
224
|
+
},
|
|
217
225
|
"id": 4,
|
|
218
226
|
"lastReviewedAt": "1970-01-01T00:00:00.000Z",
|
|
219
227
|
"lastReviewedBy": "user(1)",
|
|
@@ -271,6 +279,10 @@ Object {
|
|
|
271
279
|
"moderation": Object {
|
|
272
280
|
"subjectStatus": Object {
|
|
273
281
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
282
|
+
"hosting": Object {
|
|
283
|
+
"$type": "tools.ozone.moderation.defs#accountHosting",
|
|
284
|
+
"status": "unknown",
|
|
285
|
+
},
|
|
274
286
|
"id": 1,
|
|
275
287
|
"lastReportedAt": "1970-01-01T00:00:00.000Z",
|
|
276
288
|
"lastReviewedAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -101,12 +101,22 @@ describe('proxy read after write', () => {
|
|
|
101
101
|
{ uri: sc.posts[alice][0].ref.uriStr },
|
|
102
102
|
{ headers: { ...sc.getHeaders(alice) } },
|
|
103
103
|
)
|
|
104
|
-
const
|
|
104
|
+
const thread = res.data.thread as ThreadViewPost
|
|
105
|
+
const layerOne = thread.replies as ThreadViewPost[]
|
|
105
106
|
expect(layerOne.length).toBe(1)
|
|
106
107
|
expect(layerOne[0].post.uri).toEqual(reply1.ref.uriStr)
|
|
107
108
|
const layerTwo = layerOne[0].replies as ThreadViewPost[]
|
|
108
109
|
expect(layerTwo.length).toBe(1)
|
|
109
110
|
expect(layerTwo[0].post.uri).toEqual(reply2.ref.uriStr)
|
|
111
|
+
|
|
112
|
+
const aliceHandle = sc.accounts[alice].handle
|
|
113
|
+
const handleUriStr = thread.post.uri.replace(alice, aliceHandle)
|
|
114
|
+
expect(handleUriStr).not.toEqual(thread.post.uri)
|
|
115
|
+
const handleRes = await agent.api.app.bsky.feed.getPostThread(
|
|
116
|
+
{ uri: handleUriStr },
|
|
117
|
+
{ headers: { ...sc.getHeaders(alice) } },
|
|
118
|
+
)
|
|
119
|
+
expect(handleRes.data.thread).toEqual(res.data.thread)
|
|
110
120
|
})
|
|
111
121
|
|
|
112
122
|
it('handles read after write on a thread that is not found on appview', async () => {
|
|
@@ -123,6 +133,15 @@ describe('proxy read after write', () => {
|
|
|
123
133
|
expect((thread.replies?.at(0) as ThreadViewPost).post.uri).toEqual(
|
|
124
134
|
replyRef2.uriStr,
|
|
125
135
|
)
|
|
136
|
+
|
|
137
|
+
const aliceHandle = sc.accounts[alice].handle
|
|
138
|
+
const handleUriStr = thread.post.uri.replace(alice, aliceHandle)
|
|
139
|
+
expect(handleUriStr).not.toEqual(thread.post.uri)
|
|
140
|
+
const handleRes = await agent.api.app.bsky.feed.getPostThread(
|
|
141
|
+
{ uri: handleUriStr },
|
|
142
|
+
{ headers: { ...sc.getHeaders(alice) } },
|
|
143
|
+
)
|
|
144
|
+
expect(handleRes.data.thread).toEqual(res.data.thread)
|
|
126
145
|
})
|
|
127
146
|
|
|
128
147
|
it('handles read after write on threads with record embeds', async () => {
|