@atproto/bsky 0.0.10 → 0.0.12
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/com/atproto/admin/util.d.ts +5 -0
- package/dist/config.d.ts +2 -0
- package/dist/context.d.ts +8 -0
- package/dist/db/index.js +51 -2
- package/dist/db/index.js.map +3 -3
- package/dist/db/migrations/20230929T192920807Z-record-cursor-indexes.d.ts +3 -0
- package/dist/db/migrations/index.d.ts +1 -0
- package/dist/did-cache.d.ts +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1818 -580
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +16 -0
- package/dist/lexicon/lexicons.d.ts +330 -3
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +28 -0
- package/dist/lexicon/types/com/atproto/admin/getAccountInfo.d.ts +29 -0
- package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts +39 -0
- package/dist/lexicon/types/com/atproto/admin/searchRepos.d.ts +0 -1
- package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts +46 -0
- package/dist/lexicon/types/com/atproto/server/confirmEmail.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/server/createAccount.d.ts +2 -0
- package/dist/lexicon/types/com/atproto/server/createSession.d.ts +2 -0
- package/dist/lexicon/types/com/atproto/server/getSession.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailConfirmation.d.ts +19 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailUpdate.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/server/reserveSigningKey.d.ts +30 -0
- package/dist/lexicon/types/com/atproto/server/updateEmail.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/sync/listRepos.d.ts +1 -0
- package/dist/services/actor/index.d.ts +2 -2
- package/dist/services/actor/types.d.ts +1 -0
- package/dist/services/graph/index.d.ts +2 -0
- package/dist/services/moderation/index.d.ts +13 -3
- package/dist/services/util/search.d.ts +3 -3
- package/package.json +13 -14
- package/src/api/app/bsky/actor/searchActors.ts +36 -22
- package/src/api/app/bsky/actor/searchActorsTypeahead.ts +24 -17
- package/src/api/app/bsky/feed/getAuthorFeed.ts +2 -2
- package/src/api/app/bsky/feed/getPostThread.ts +2 -2
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +1 -0
- package/src/api/app/bsky/notification/listNotifications.ts +33 -22
- package/src/api/com/atproto/admin/getModerationAction.ts +28 -2
- package/src/api/com/atproto/admin/getModerationReport.ts +27 -2
- package/src/api/com/atproto/admin/getRecord.ts +14 -2
- package/src/api/com/atproto/admin/getRepo.ts +13 -2
- package/src/api/com/atproto/admin/reverseModerationAction.ts +31 -5
- package/src/api/com/atproto/admin/searchRepos.ts +6 -12
- package/src/api/com/atproto/admin/takeModerationAction.ts +41 -7
- package/src/api/com/atproto/admin/util.ts +50 -0
- package/src/api/well-known.ts +8 -0
- package/src/auth.ts +12 -5
- package/src/auto-moderator/index.ts +1 -0
- package/src/config.ts +7 -0
- package/src/context.ts +30 -0
- package/src/db/migrations/20230929T192920807Z-record-cursor-indexes.ts +40 -0
- package/src/db/migrations/index.ts +1 -0
- package/src/did-cache.ts +29 -14
- package/src/feed-gen/with-friends.ts +2 -2
- package/src/index.ts +9 -1
- package/src/indexer/subscription.ts +1 -21
- package/src/lexicon/index.ts +96 -0
- package/src/lexicon/lexicons.ts +368 -4
- package/src/lexicon/types/app/bsky/actor/defs.ts +1 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +61 -0
- package/src/lexicon/types/com/atproto/admin/getAccountInfo.ts +41 -0
- package/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +54 -0
- package/src/lexicon/types/com/atproto/admin/searchRepos.ts +0 -1
- package/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts +61 -0
- package/src/lexicon/types/com/atproto/server/confirmEmail.ts +40 -0
- package/src/lexicon/types/com/atproto/server/createAccount.ts +2 -0
- package/src/lexicon/types/com/atproto/server/createSession.ts +2 -0
- package/src/lexicon/types/com/atproto/server/getSession.ts +1 -0
- package/src/lexicon/types/com/atproto/server/refreshSession.ts +1 -0
- package/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts +31 -0
- package/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts +43 -0
- package/src/lexicon/types/com/atproto/server/reserveSigningKey.ts +44 -0
- package/src/lexicon/types/com/atproto/server/updateEmail.ts +41 -0
- package/src/lexicon/types/com/atproto/sync/listRepos.ts +1 -0
- package/src/logger.ts +8 -0
- package/src/services/actor/index.ts +16 -10
- package/src/services/actor/types.ts +1 -0
- package/src/services/actor/views.ts +26 -8
- package/src/services/graph/index.ts +26 -7
- package/src/services/indexing/index.ts +15 -17
- package/src/services/moderation/index.ts +94 -14
- package/src/services/moderation/views.ts +1 -0
- package/src/services/util/search.ts +24 -23
- package/tests/__snapshots__/feed-generation.test.ts.snap +12 -12
- package/tests/__snapshots__/indexing.test.ts.snap +4 -4
- package/tests/admin/__snapshots__/get-moderation-action.test.ts.snap +172 -0
- package/tests/admin/__snapshots__/get-moderation-actions.test.ts.snap +178 -0
- package/tests/admin/__snapshots__/get-moderation-report.test.ts.snap +177 -0
- package/tests/admin/__snapshots__/get-moderation-reports.test.ts.snap +307 -0
- package/tests/admin/__snapshots__/get-record.test.ts.snap +275 -0
- package/tests/admin/__snapshots__/get-repo.test.ts.snap +103 -0
- package/tests/admin/get-moderation-action.test.ts +100 -0
- package/tests/admin/get-moderation-actions.test.ts +164 -0
- package/tests/admin/get-moderation-report.test.ts +100 -0
- package/tests/admin/get-moderation-reports.test.ts +332 -0
- package/tests/admin/get-record.test.ts +115 -0
- package/tests/admin/get-repo.test.ts +101 -0
- package/tests/{moderation.test.ts → admin/moderation.test.ts} +107 -9
- package/tests/admin/repo-search.test.ts +124 -0
- package/tests/algos/hot-classic.test.ts +3 -5
- package/tests/algos/whats-hot.test.ts +3 -5
- package/tests/algos/with-friends.test.ts +2 -4
- package/tests/auth.test.ts +64 -0
- package/tests/auto-moderator/fuzzy-matcher.test.ts +2 -3
- package/tests/auto-moderator/labeler.test.ts +5 -7
- package/tests/auto-moderator/takedowns.test.ts +11 -12
- package/tests/blob-resolver.test.ts +1 -3
- package/tests/did-cache.test.ts +2 -5
- package/tests/feed-generation.test.ts +8 -6
- package/tests/handle-invalidation.test.ts +2 -3
- package/tests/image/server.test.ts +1 -4
- package/tests/image/sharp.test.ts +1 -1
- package/tests/indexing.test.ts +4 -4
- package/tests/notification-server.test.ts +2 -3
- package/tests/pipeline/backpressure.test.ts +2 -3
- package/tests/pipeline/reingest.test.ts +7 -4
- package/tests/pipeline/repartition.test.ts +2 -3
- package/tests/reprocessing.test.ts +2 -6
- package/tests/seeds/basic.ts +4 -4
- package/tests/seeds/follows.ts +1 -1
- package/tests/seeds/likes.ts +1 -1
- package/tests/seeds/reposts.ts +1 -1
- package/tests/seeds/users-bulk.ts +1 -1
- package/tests/seeds/users.ts +1 -1
- package/tests/server.test.ts +1 -3
- package/tests/subscription/repo.test.ts +2 -4
- package/tests/views/__snapshots__/author-feed.test.ts.snap +24 -24
- package/tests/views/__snapshots__/block-lists.test.ts.snap +42 -7
- package/tests/views/__snapshots__/blocks.test.ts.snap +2 -2
- package/tests/views/__snapshots__/list-feed.test.ts.snap +6 -6
- package/tests/views/__snapshots__/mute-lists.test.ts.snap +15 -4
- package/tests/views/__snapshots__/mutes.test.ts.snap +2 -2
- package/tests/views/__snapshots__/notifications.test.ts.snap +2 -2
- package/tests/views/__snapshots__/posts.test.ts.snap +8 -8
- package/tests/views/__snapshots__/thread.test.ts.snap +10 -10
- package/tests/views/__snapshots__/timeline.test.ts.snap +58 -58
- package/tests/views/actor-likes.test.ts +2 -3
- package/tests/views/actor-search.test.ts +5 -5
- package/tests/views/admin/repo-search.test.ts +2 -4
- package/tests/views/author-feed.test.ts +2 -4
- package/tests/views/block-lists.test.ts +34 -7
- package/tests/views/blocks.test.ts +6 -3
- package/tests/views/follows.test.ts +2 -4
- package/tests/views/likes.test.ts +2 -5
- package/tests/views/list-feed.test.ts +2 -4
- package/tests/views/mute-lists.test.ts +23 -5
- package/tests/views/mutes.test.ts +2 -5
- package/tests/views/notifications.test.ts +2 -4
- package/tests/views/posts.test.ts +2 -5
- package/tests/views/profile.test.ts +4 -5
- package/tests/views/reposts.test.ts +2 -4
- package/tests/views/suggested-follows.test.ts +2 -3
- package/tests/views/suggestions.test.ts +2 -4
- package/tests/views/thread.test.ts +2 -4
- package/tests/views/threadgating.test.ts +2 -3
- package/tests/views/timeline.test.ts +2 -4
- package/dist/env.d.ts +0 -1
- package/example.dev.env +0 -5
- package/src/env.ts +0 -9
- package/tests/seeds/client.ts +0 -466
- /package/tests/{__snapshots__ → admin/__snapshots__}/moderation.test.ts.snap +0 -0
- /package/tests/{image/fixtures → sample-img}/at.png +0 -0
- /package/tests/{image/fixtures → sample-img}/hd-key.jpg +0 -0
- /package/tests/{image/fixtures → sample-img}/key-alt.jpg +0 -0
- /package/tests/{image/fixtures → sample-img}/key-landscape-large.jpg +0 -0
- /package/tests/{image/fixtures → sample-img}/key-landscape-small.jpg +0 -0
- /package/tests/{image/fixtures → sample-img}/key-portrait-large.jpg +0 -0
- /package/tests/{image/fixtures → sample-img}/key-portrait-small.jpg +0 -0
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
1
|
+
import { TestNetwork, ImageRef, RecordRef, SeedClient } from '@atproto/dev-env'
|
|
2
2
|
import { TID, cidForCbor } from '@atproto/common'
|
|
3
3
|
import AtpAgent, { ComAtprotoAdminTakeModerationAction } from '@atproto/api'
|
|
4
4
|
import { AtUri } from '@atproto/syntax'
|
|
5
|
-
import { forSnapshot } from '
|
|
6
|
-
import
|
|
7
|
-
import basicSeed from './seeds/basic'
|
|
5
|
+
import { forSnapshot } from '../_util'
|
|
6
|
+
import basicSeed from '../seeds/basic'
|
|
8
7
|
import {
|
|
9
8
|
ACKNOWLEDGE,
|
|
10
9
|
ESCALATE,
|
|
11
10
|
FLAG,
|
|
12
11
|
TAKEDOWN,
|
|
13
|
-
} from '
|
|
12
|
+
} from '../../src/lexicon/types/com/atproto/admin/defs'
|
|
14
13
|
import {
|
|
15
14
|
REASONOTHER,
|
|
16
15
|
REASONSPAM,
|
|
17
|
-
} from '
|
|
18
|
-
import { PeriodicModerationActionReversal } from '
|
|
16
|
+
} from '../../src/lexicon/types/com/atproto/moderation/defs'
|
|
17
|
+
import { PeriodicModerationActionReversal } from '../../src'
|
|
19
18
|
|
|
20
19
|
describe('moderation', () => {
|
|
21
20
|
let network: TestNetwork
|
|
22
21
|
let agent: AtpAgent
|
|
22
|
+
let pdsAgent: AtpAgent
|
|
23
23
|
let sc: SeedClient
|
|
24
24
|
|
|
25
25
|
beforeAll(async () => {
|
|
@@ -27,8 +27,8 @@ describe('moderation', () => {
|
|
|
27
27
|
dbPostgresSchema: 'bsky_moderation',
|
|
28
28
|
})
|
|
29
29
|
agent = network.bsky.getClient()
|
|
30
|
-
|
|
31
|
-
sc =
|
|
30
|
+
pdsAgent = network.pds.getClient()
|
|
31
|
+
sc = network.getSeedClient()
|
|
32
32
|
await basicSeed(sc)
|
|
33
33
|
await network.processAll()
|
|
34
34
|
})
|
|
@@ -962,6 +962,82 @@ describe('moderation', () => {
|
|
|
962
962
|
)
|
|
963
963
|
})
|
|
964
964
|
|
|
965
|
+
it('fans out repo takedowns to pds', async () => {
|
|
966
|
+
const { data: action } =
|
|
967
|
+
await agent.api.com.atproto.admin.takeModerationAction(
|
|
968
|
+
{
|
|
969
|
+
action: TAKEDOWN,
|
|
970
|
+
createdBy: 'did:example:moderator',
|
|
971
|
+
reason: 'Y',
|
|
972
|
+
subject: {
|
|
973
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
974
|
+
did: sc.dids.bob,
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
encoding: 'application/json',
|
|
979
|
+
headers: network.bsky.adminAuthHeaders(),
|
|
980
|
+
},
|
|
981
|
+
)
|
|
982
|
+
|
|
983
|
+
const res1 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
984
|
+
{
|
|
985
|
+
did: sc.dids.bob,
|
|
986
|
+
},
|
|
987
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
988
|
+
)
|
|
989
|
+
expect(res1.data.takedown?.applied).toBe(true)
|
|
990
|
+
|
|
991
|
+
// cleanup
|
|
992
|
+
await reverse(action.id)
|
|
993
|
+
|
|
994
|
+
const res2 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
995
|
+
{
|
|
996
|
+
did: sc.dids.bob,
|
|
997
|
+
},
|
|
998
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
999
|
+
)
|
|
1000
|
+
expect(res2.data.takedown?.applied).toBe(false)
|
|
1001
|
+
})
|
|
1002
|
+
|
|
1003
|
+
it('fans out record takedowns to pds', async () => {
|
|
1004
|
+
const post = sc.posts[sc.dids.bob][0]
|
|
1005
|
+
const uri = post.ref.uriStr
|
|
1006
|
+
const cid = post.ref.cidStr
|
|
1007
|
+
const { data: action } =
|
|
1008
|
+
await agent.api.com.atproto.admin.takeModerationAction(
|
|
1009
|
+
{
|
|
1010
|
+
action: TAKEDOWN,
|
|
1011
|
+
createdBy: 'did:example:moderator',
|
|
1012
|
+
reason: 'Y',
|
|
1013
|
+
subject: {
|
|
1014
|
+
$type: 'com.atproto.repo.strongRef',
|
|
1015
|
+
uri,
|
|
1016
|
+
cid,
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
encoding: 'application/json',
|
|
1021
|
+
headers: network.bsky.adminAuthHeaders(),
|
|
1022
|
+
},
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
const res1 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
1026
|
+
{ uri },
|
|
1027
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
1028
|
+
)
|
|
1029
|
+
expect(res1.data.takedown?.applied).toBe(true)
|
|
1030
|
+
|
|
1031
|
+
// cleanup
|
|
1032
|
+
await reverse(action.id)
|
|
1033
|
+
|
|
1034
|
+
const res2 = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
1035
|
+
{ uri },
|
|
1036
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
1037
|
+
)
|
|
1038
|
+
expect(res2.data.takedown?.applied).toBe(false)
|
|
1039
|
+
})
|
|
1040
|
+
|
|
965
1041
|
it('allows full moderators to takedown.', async () => {
|
|
966
1042
|
const { data: action } =
|
|
967
1043
|
await agent.api.com.atproto.admin.takeModerationAction(
|
|
@@ -1161,6 +1237,17 @@ describe('moderation', () => {
|
|
|
1161
1237
|
expect(await fetchImage.json()).toEqual({ message: 'Image not found' })
|
|
1162
1238
|
})
|
|
1163
1239
|
|
|
1240
|
+
it('fans takedown out to pds', async () => {
|
|
1241
|
+
const res = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
1242
|
+
{
|
|
1243
|
+
did: sc.dids.carol,
|
|
1244
|
+
blob: blob.image.ref.toString(),
|
|
1245
|
+
},
|
|
1246
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
1247
|
+
)
|
|
1248
|
+
expect(res.data.takedown?.applied).toBe(true)
|
|
1249
|
+
})
|
|
1250
|
+
|
|
1164
1251
|
it('restores blob when action is reversed.', async () => {
|
|
1165
1252
|
await agent.api.com.atproto.admin.reverseModerationAction(
|
|
1166
1253
|
{
|
|
@@ -1185,5 +1272,16 @@ describe('moderation', () => {
|
|
|
1185
1272
|
const size = Number(fetchImage.headers.get('content-length'))
|
|
1186
1273
|
expect(size).toBeGreaterThan(9000)
|
|
1187
1274
|
})
|
|
1275
|
+
|
|
1276
|
+
it('fans reversal out to pds', async () => {
|
|
1277
|
+
const res = await pdsAgent.api.com.atproto.admin.getSubjectStatus(
|
|
1278
|
+
{
|
|
1279
|
+
did: sc.dids.carol,
|
|
1280
|
+
blob: blob.image.ref.toString(),
|
|
1281
|
+
},
|
|
1282
|
+
{ headers: network.pds.adminAuthHeaders() },
|
|
1283
|
+
)
|
|
1284
|
+
expect(res.data.takedown?.applied).toBe(false)
|
|
1285
|
+
})
|
|
1188
1286
|
})
|
|
1189
1287
|
})
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { SeedClient, TestNetwork } from '@atproto/dev-env'
|
|
2
|
+
import AtpAgent from '@atproto/api'
|
|
3
|
+
import { TAKEDOWN } from '@atproto/api/src/client/types/com/atproto/admin/defs'
|
|
4
|
+
import { paginateAll } from '../_util'
|
|
5
|
+
import usersBulkSeed from '../seeds/users-bulk'
|
|
6
|
+
|
|
7
|
+
describe('admin repo search view', () => {
|
|
8
|
+
let network: TestNetwork
|
|
9
|
+
let agent: AtpAgent
|
|
10
|
+
let sc: SeedClient
|
|
11
|
+
let headers: { [s: string]: string }
|
|
12
|
+
|
|
13
|
+
beforeAll(async () => {
|
|
14
|
+
network = await TestNetwork.create({
|
|
15
|
+
dbPostgresSchema: 'views_admin_repo_search',
|
|
16
|
+
})
|
|
17
|
+
agent = network.pds.getClient()
|
|
18
|
+
sc = network.getSeedClient()
|
|
19
|
+
await usersBulkSeed(sc)
|
|
20
|
+
headers = network.pds.adminAuthHeaders()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
afterAll(async () => {
|
|
24
|
+
await network.close()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
await sc.takeModerationAction({
|
|
29
|
+
action: TAKEDOWN,
|
|
30
|
+
subject: {
|
|
31
|
+
$type: 'com.atproto.admin.defs#repoRef',
|
|
32
|
+
did: sc.dids['cara-wiegand69.test'],
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('gives relevant results', async () => {
|
|
38
|
+
const result = await agent.api.com.atproto.admin.searchRepos(
|
|
39
|
+
{ term: 'car' },
|
|
40
|
+
{ headers },
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
const handles = result.data.repos.map((u) => u.handle)
|
|
44
|
+
|
|
45
|
+
const shouldContain = [
|
|
46
|
+
'cara-wiegand69.test', // Present despite repo takedown
|
|
47
|
+
'carlos6.test',
|
|
48
|
+
'carolina-mcdermott77.test',
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
shouldContain.forEach((handle) => expect(handles).toContain(handle))
|
|
52
|
+
|
|
53
|
+
const shouldNotContain = [
|
|
54
|
+
'sven70.test',
|
|
55
|
+
'hilario84.test',
|
|
56
|
+
'santa-hermann78.test',
|
|
57
|
+
'dylan61.test',
|
|
58
|
+
'preston-harris.test',
|
|
59
|
+
'loyce95.test',
|
|
60
|
+
'melyna-zboncak.test',
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
shouldNotContain.forEach((handle) => expect(handles).not.toContain(handle))
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('finds repo by did', async () => {
|
|
67
|
+
const term = sc.dids['cara-wiegand69.test']
|
|
68
|
+
const res = await agent.api.com.atproto.admin.searchRepos(
|
|
69
|
+
{ term },
|
|
70
|
+
{ headers },
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
expect(res.data.repos.length).toEqual(1)
|
|
74
|
+
expect(res.data.repos[0].did).toEqual(term)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('paginates with term', async () => {
|
|
78
|
+
const results = (results) => results.flatMap((res) => res.users)
|
|
79
|
+
const paginator = async (cursor?: string) => {
|
|
80
|
+
const res = await agent.api.com.atproto.admin.searchRepos(
|
|
81
|
+
{ term: 'p', cursor, limit: 3 },
|
|
82
|
+
{ headers },
|
|
83
|
+
)
|
|
84
|
+
return res.data
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const paginatedAll = await paginateAll(paginator)
|
|
88
|
+
paginatedAll.forEach((res) =>
|
|
89
|
+
expect(res.repos.length).toBeLessThanOrEqual(3),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
const full = await agent.api.com.atproto.admin.searchRepos(
|
|
93
|
+
{ term: 'p' },
|
|
94
|
+
{ headers },
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
expect(full.data.repos.length).toBeGreaterThan(3)
|
|
98
|
+
expect(results(paginatedAll)).toEqual(results([full.data]))
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('paginates without term', async () => {
|
|
102
|
+
const results = (results) => results.flatMap((res) => res.repos)
|
|
103
|
+
const paginator = async (cursor?: string) => {
|
|
104
|
+
const res = await agent.api.com.atproto.admin.searchRepos(
|
|
105
|
+
{ cursor, limit: 3 },
|
|
106
|
+
{ headers },
|
|
107
|
+
)
|
|
108
|
+
return res.data
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const paginatedAll = await paginateAll(paginator, 5)
|
|
112
|
+
paginatedAll.forEach((res) =>
|
|
113
|
+
expect(res.repos.length).toBeLessThanOrEqual(3),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const full = await agent.api.com.atproto.admin.searchRepos(
|
|
117
|
+
{ limit: 15 },
|
|
118
|
+
{ headers },
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
expect(full.data.repos.length).toEqual(15)
|
|
122
|
+
expect(results(paginatedAll)).toEqual(results([full.data]))
|
|
123
|
+
})
|
|
124
|
+
})
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import AtpAgent, { AtUri } from '@atproto/api'
|
|
2
|
-
import { SeedClient } from '
|
|
2
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
3
3
|
import basicSeed from '../seeds/basic'
|
|
4
4
|
import { makeAlgos } from '../../src'
|
|
5
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
6
5
|
|
|
7
6
|
describe('algo hot-classic', () => {
|
|
8
7
|
let network: TestNetwork
|
|
@@ -26,8 +25,7 @@ describe('algo hot-classic', () => {
|
|
|
26
25
|
bsky: { algos: makeAlgos(feedPublisherDid) },
|
|
27
26
|
})
|
|
28
27
|
agent = new AtpAgent({ service: network.bsky.url })
|
|
29
|
-
|
|
30
|
-
sc = new SeedClient(pdsAgent)
|
|
28
|
+
sc = network.getSeedClient()
|
|
31
29
|
await basicSeed(sc)
|
|
32
30
|
|
|
33
31
|
alice = sc.dids.alice
|
|
@@ -43,7 +41,7 @@ describe('algo hot-classic', () => {
|
|
|
43
41
|
it('returns well liked posts', async () => {
|
|
44
42
|
const img = await sc.uploadFile(
|
|
45
43
|
alice,
|
|
46
|
-
'tests/
|
|
44
|
+
'tests/sample-img/key-landscape-small.jpg',
|
|
47
45
|
'image/jpeg',
|
|
48
46
|
)
|
|
49
47
|
const one = await sc.post(alice, 'first post', undefined, [img])
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { HOUR } from '@atproto/common'
|
|
2
2
|
import AtpAgent, { AtUri } from '@atproto/api'
|
|
3
|
-
import { SeedClient } from '
|
|
3
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
4
4
|
import basicSeed from '../seeds/basic'
|
|
5
5
|
import { makeAlgos } from '../../src'
|
|
6
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
7
6
|
|
|
8
7
|
describe.skip('algo whats-hot', () => {
|
|
9
8
|
let network: TestNetwork
|
|
@@ -28,8 +27,7 @@ describe.skip('algo whats-hot', () => {
|
|
|
28
27
|
bsky: { algos: makeAlgos(feedPublisherDid) },
|
|
29
28
|
})
|
|
30
29
|
agent = new AtpAgent({ service: network.bsky.url })
|
|
31
|
-
|
|
32
|
-
sc = new SeedClient(pdsAgent)
|
|
30
|
+
sc = network.getSeedClient()
|
|
33
31
|
await basicSeed(sc)
|
|
34
32
|
|
|
35
33
|
alice = sc.dids.alice
|
|
@@ -46,7 +44,7 @@ describe.skip('algo whats-hot', () => {
|
|
|
46
44
|
it('returns well liked posts', async () => {
|
|
47
45
|
const img = await sc.uploadFile(
|
|
48
46
|
alice,
|
|
49
|
-
'tests/
|
|
47
|
+
'tests/sample-img/key-landscape-small.jpg',
|
|
50
48
|
'image/jpeg',
|
|
51
49
|
)
|
|
52
50
|
const one = await sc.post(carol, 'carol is in the chat')
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import AtpAgent, { AtUri } from '@atproto/api'
|
|
2
|
-
import { RecordRef, SeedClient } from '../seeds/client'
|
|
3
2
|
import userSeed from '../seeds/users'
|
|
4
3
|
import { makeAlgos } from '../../src'
|
|
5
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
4
|
+
import { TestNetwork, SeedClient, RecordRef } from '@atproto/dev-env'
|
|
6
5
|
|
|
7
6
|
describe.skip('algo with friends', () => {
|
|
8
7
|
let network: TestNetwork
|
|
@@ -28,8 +27,7 @@ describe.skip('algo with friends', () => {
|
|
|
28
27
|
bsky: { algos: makeAlgos(feedPublisherDid) },
|
|
29
28
|
})
|
|
30
29
|
agent = new AtpAgent({ service: network.bsky.url })
|
|
31
|
-
|
|
32
|
-
sc = new SeedClient(pdsAgent)
|
|
30
|
+
sc = network.getSeedClient()
|
|
33
31
|
await userSeed(sc)
|
|
34
32
|
|
|
35
33
|
alice = sc.dids.alice
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import AtpAgent from '@atproto/api'
|
|
2
|
+
import { SeedClient, TestNetwork } from '@atproto/dev-env'
|
|
3
|
+
import usersSeed from './seeds/users'
|
|
4
|
+
import { createServiceJwt } from '@atproto/xrpc-server'
|
|
5
|
+
import { Keypair, Secp256k1Keypair } from '@atproto/crypto'
|
|
6
|
+
|
|
7
|
+
describe('auth', () => {
|
|
8
|
+
let network: TestNetwork
|
|
9
|
+
let agent: AtpAgent
|
|
10
|
+
let sc: SeedClient
|
|
11
|
+
|
|
12
|
+
beforeAll(async () => {
|
|
13
|
+
network = await TestNetwork.create({
|
|
14
|
+
dbPostgresSchema: 'bsky_auth',
|
|
15
|
+
})
|
|
16
|
+
agent = network.bsky.getClient()
|
|
17
|
+
sc = network.getSeedClient()
|
|
18
|
+
await usersSeed(sc)
|
|
19
|
+
await network.processAll()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
afterAll(async () => {
|
|
23
|
+
await network.close()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('handles signing key change for service auth.', async () => {
|
|
27
|
+
const issuer = sc.dids.alice
|
|
28
|
+
const attemptWithKey = async (keypair: Keypair) => {
|
|
29
|
+
const jwt = await createServiceJwt({
|
|
30
|
+
iss: issuer,
|
|
31
|
+
aud: network.bsky.ctx.cfg.serverDid,
|
|
32
|
+
keypair,
|
|
33
|
+
})
|
|
34
|
+
return agent.api.app.bsky.actor.getProfile(
|
|
35
|
+
{ actor: sc.dids.carol },
|
|
36
|
+
{ headers: { authorization: `Bearer ${jwt}` } },
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
const origSigningKey = network.pds.ctx.repoSigningKey
|
|
40
|
+
const newSigningKey = await Secp256k1Keypair.create({ exportable: true })
|
|
41
|
+
// confirm original signing key works
|
|
42
|
+
await expect(attemptWithKey(origSigningKey)).resolves.toBeDefined()
|
|
43
|
+
// confirm next signing key doesn't work yet
|
|
44
|
+
await expect(attemptWithKey(newSigningKey)).rejects.toThrow(
|
|
45
|
+
'jwt signature does not match jwt issuer',
|
|
46
|
+
)
|
|
47
|
+
// update to new signing key
|
|
48
|
+
await network.plc
|
|
49
|
+
.getClient()
|
|
50
|
+
.updateAtprotoKey(
|
|
51
|
+
issuer,
|
|
52
|
+
network.pds.ctx.plcRotationKey,
|
|
53
|
+
newSigningKey.did(),
|
|
54
|
+
)
|
|
55
|
+
// old signing key still works due to did doc cache
|
|
56
|
+
await expect(attemptWithKey(origSigningKey)).resolves.toBeDefined()
|
|
57
|
+
// new signing key works
|
|
58
|
+
await expect(attemptWithKey(newSigningKey)).resolves.toBeDefined()
|
|
59
|
+
// old signing key no longer works after cache is updated
|
|
60
|
+
await expect(attemptWithKey(origSigningKey)).rejects.toThrow(
|
|
61
|
+
'jwt signature does not match jwt issuer',
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
1
2
|
import { FuzzyMatcher, encode } from '../../src/auto-moderator/fuzzy-matcher'
|
|
2
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
3
|
-
import { SeedClient } from '../seeds/client'
|
|
4
3
|
import basicSeed from '../seeds/basic'
|
|
5
4
|
import { AtpAgent } from '@atproto/api'
|
|
6
5
|
import { ImageInvalidator } from '../../src/image/invalidator'
|
|
@@ -25,7 +24,7 @@ describe('fuzzy matcher', () => {
|
|
|
25
24
|
})
|
|
26
25
|
fuzzyMatcher = new FuzzyMatcher(['evil', 'mean', 'bad'], ['baddie'])
|
|
27
26
|
agent = network.pds.getClient()
|
|
28
|
-
sc =
|
|
27
|
+
sc = network.getSeedClient()
|
|
29
28
|
await basicSeed(sc)
|
|
30
29
|
await network.processAll()
|
|
31
30
|
alice = sc.dids.alice
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TestNetwork } from '@atproto/dev-env'
|
|
2
|
+
import { AtUri, BlobRef } from '@atproto/api'
|
|
2
3
|
import { Readable } from 'stream'
|
|
3
4
|
import { AutoModerator } from '../../src/auto-moderator'
|
|
4
5
|
import IndexerContext from '../../src/indexer/context'
|
|
5
6
|
import { cidForRecord } from '@atproto/repo'
|
|
6
|
-
import {
|
|
7
|
+
import { TID } from '@atproto/common'
|
|
7
8
|
import { LabelService } from '../../src/services/label'
|
|
8
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
9
|
-
import { SeedClient } from '../seeds/client'
|
|
10
9
|
import usersSeed from '../seeds/users'
|
|
11
10
|
import { CID } from 'multiformats/cid'
|
|
12
11
|
import { ImgLabeler } from '../../src/auto-moderator/hive'
|
|
@@ -37,8 +36,7 @@ describe('labeler', () => {
|
|
|
37
36
|
autoMod = ctx.autoMod
|
|
38
37
|
autoMod.imgLabeler = new TestImgLabeler()
|
|
39
38
|
labelSrvc = ctx.services.label(ctx.db)
|
|
40
|
-
const
|
|
41
|
-
const sc = new SeedClient(pdsAgent)
|
|
39
|
+
const sc = network.getSeedClient()
|
|
42
40
|
await usersSeed(sc)
|
|
43
41
|
await network.processAll()
|
|
44
42
|
alice = sc.dids.alice
|
|
@@ -58,7 +56,7 @@ describe('labeler', () => {
|
|
|
58
56
|
await repoSvc.blobs.associateBlob(
|
|
59
57
|
preparedBlobRef,
|
|
60
58
|
postUri(),
|
|
61
|
-
|
|
59
|
+
TID.nextStr(),
|
|
62
60
|
alice,
|
|
63
61
|
)
|
|
64
62
|
return blobRef
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import fs from 'fs/promises'
|
|
2
|
+
import { TestNetwork, SeedClient, ImageRef } from '@atproto/dev-env'
|
|
2
3
|
import { AtpAgent } from '@atproto/api'
|
|
3
4
|
import { AutoModerator } from '../../src/auto-moderator'
|
|
4
5
|
import IndexerContext from '../../src/indexer/context'
|
|
5
6
|
import { sha256RawToCid } from '@atproto/common'
|
|
6
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
7
|
-
import { ImageRef, SeedClient } from '../seeds/client'
|
|
8
7
|
import usersSeed from '../seeds/users'
|
|
9
8
|
import { CID } from 'multiformats/cid'
|
|
10
9
|
import { AtUri } from '@atproto/syntax'
|
|
@@ -41,31 +40,31 @@ describe('takedowner', () => {
|
|
|
41
40
|
autoMod = ctx.autoMod
|
|
42
41
|
autoMod.imageFlagger = new TestFlagger()
|
|
43
42
|
pdsAgent = new AtpAgent({ service: network.pds.url })
|
|
44
|
-
sc =
|
|
43
|
+
sc = network.getSeedClient()
|
|
45
44
|
await usersSeed(sc)
|
|
46
45
|
await network.processAll()
|
|
47
46
|
alice = sc.dids.alice
|
|
48
47
|
const fileBytes1 = await fs.readFile(
|
|
49
|
-
'tests/
|
|
48
|
+
'tests/sample-img/key-portrait-small.jpg',
|
|
50
49
|
)
|
|
51
50
|
const fileBytes2 = await fs.readFile(
|
|
52
|
-
'tests/
|
|
51
|
+
'tests/sample-img/key-portrait-large.jpg',
|
|
53
52
|
)
|
|
54
53
|
badCid1 = sha256RawToCid(await sha256(fileBytes1))
|
|
55
54
|
badCid2 = sha256RawToCid(await sha256(fileBytes2))
|
|
56
55
|
goodBlob = await sc.uploadFile(
|
|
57
56
|
alice,
|
|
58
|
-
'tests/
|
|
57
|
+
'tests/sample-img/key-landscape-small.jpg',
|
|
59
58
|
'image/jpeg',
|
|
60
59
|
)
|
|
61
60
|
badBlob1 = await sc.uploadFile(
|
|
62
61
|
alice,
|
|
63
|
-
'tests/
|
|
62
|
+
'tests/sample-img/key-portrait-small.jpg',
|
|
64
63
|
'image/jpeg',
|
|
65
64
|
)
|
|
66
65
|
badBlob2 = await sc.uploadFile(
|
|
67
66
|
alice,
|
|
68
|
-
'tests/
|
|
67
|
+
'tests/sample-img/key-portrait-large.jpg',
|
|
69
68
|
'image/jpeg',
|
|
70
69
|
)
|
|
71
70
|
})
|
|
@@ -97,9 +96,9 @@ describe('takedowner', () => {
|
|
|
97
96
|
const recordPds = await network.pds.ctx.db.db
|
|
98
97
|
.selectFrom('record')
|
|
99
98
|
.where('uri', '=', post.ref.uriStr)
|
|
100
|
-
.select('
|
|
99
|
+
.select('takedownRef')
|
|
101
100
|
.executeTakeFirst()
|
|
102
|
-
expect(recordPds?.
|
|
101
|
+
expect(recordPds?.takedownRef).toEqual(modAction.id.toString())
|
|
103
102
|
|
|
104
103
|
expect(testInvalidator.invalidated.length).toBe(1)
|
|
105
104
|
expect(testInvalidator.invalidated[0].subject).toBe(
|
|
@@ -139,9 +138,9 @@ describe('takedowner', () => {
|
|
|
139
138
|
const recordPds = await network.pds.ctx.db.db
|
|
140
139
|
.selectFrom('record')
|
|
141
140
|
.where('uri', '=', res.data.uri)
|
|
142
|
-
.select('
|
|
141
|
+
.select('takedownRef')
|
|
143
142
|
.executeTakeFirst()
|
|
144
|
-
expect(recordPds?.
|
|
143
|
+
expect(recordPds?.takedownRef).toEqual(modAction.id.toString())
|
|
145
144
|
|
|
146
145
|
expect(testInvalidator.invalidated.length).toBe(2)
|
|
147
146
|
expect(testInvalidator.invalidated[1].subject).toBe(
|
|
@@ -2,7 +2,6 @@ import axios, { AxiosInstance } from 'axios'
|
|
|
2
2
|
import { CID } from 'multiformats/cid'
|
|
3
3
|
import { verifyCidForBytes } from '@atproto/common'
|
|
4
4
|
import { TestNetwork } from '@atproto/dev-env'
|
|
5
|
-
import { SeedClient } from './seeds/client'
|
|
6
5
|
import basicSeed from './seeds/basic'
|
|
7
6
|
import { randomBytes } from '@atproto/crypto'
|
|
8
7
|
|
|
@@ -16,8 +15,7 @@ describe('blob resolver', () => {
|
|
|
16
15
|
network = await TestNetwork.create({
|
|
17
16
|
dbPostgresSchema: 'bsky_blob_resolver',
|
|
18
17
|
})
|
|
19
|
-
const
|
|
20
|
-
const sc = new SeedClient(pdsAgent)
|
|
18
|
+
const sc = network.getSeedClient()
|
|
21
19
|
await basicSeed(sc)
|
|
22
20
|
await network.processAll()
|
|
23
21
|
await network.bsky.processAll()
|
package/tests/did-cache.test.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
3
|
-
import { SeedClient } from './seeds/client'
|
|
1
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
4
2
|
import userSeed from './seeds/users'
|
|
5
3
|
import { IdResolver } from '@atproto/identity'
|
|
6
4
|
import DidSqlCache from '../src/did-cache'
|
|
@@ -23,8 +21,7 @@ describe('did cache', () => {
|
|
|
23
21
|
})
|
|
24
22
|
idResolver = network.bsky.indexer.ctx.idResolver
|
|
25
23
|
didCache = network.bsky.indexer.ctx.didCache
|
|
26
|
-
|
|
27
|
-
sc = new SeedClient(pdsAgent)
|
|
24
|
+
sc = network.getSeedClient()
|
|
28
25
|
await userSeed(sc)
|
|
29
26
|
await network.processAll()
|
|
30
27
|
alice = sc.dids.alice
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { TID } from '@atproto/common'
|
|
2
2
|
import { AtUri, AtpAgent } from '@atproto/api'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
TestNetwork,
|
|
5
|
+
TestFeedGen,
|
|
6
|
+
SeedClient,
|
|
7
|
+
RecordRef,
|
|
8
|
+
} from '@atproto/dev-env'
|
|
9
|
+
import { Handler as SkeletonHandler } from '../src/lexicon/types/app/bsky/feed/getFeedSkeleton'
|
|
6
10
|
import { GeneratorView } from '@atproto/api/src/client/types/app/bsky/feed/defs'
|
|
7
11
|
import { UnknownFeedError } from '@atproto/api/src/client/types/app/bsky/feed/getFeed'
|
|
8
12
|
import { TAKEDOWN } from '@atproto/api/src/client/types/com/atproto/admin/defs'
|
|
@@ -11,9 +15,7 @@ import {
|
|
|
11
15
|
FeedViewPost,
|
|
12
16
|
SkeletonFeedPost,
|
|
13
17
|
} from '../src/lexicon/types/app/bsky/feed/defs'
|
|
14
|
-
import { SeedClient } from './seeds/client'
|
|
15
18
|
import basicSeed from './seeds/basic'
|
|
16
|
-
import { RecordRef } from './seeds/client'
|
|
17
19
|
import { forSnapshot, paginateAll } from './_util'
|
|
18
20
|
|
|
19
21
|
describe('feed generation', () => {
|
|
@@ -38,7 +40,7 @@ describe('feed generation', () => {
|
|
|
38
40
|
})
|
|
39
41
|
agent = network.bsky.getClient()
|
|
40
42
|
pdsAgent = network.pds.getClient()
|
|
41
|
-
sc =
|
|
43
|
+
sc = network.getSeedClient()
|
|
42
44
|
await basicSeed(sc)
|
|
43
45
|
await network.processAll()
|
|
44
46
|
alice = sc.dids.alice
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DAY } from '@atproto/common'
|
|
2
|
-
import { TestNetwork } from '@atproto/dev-env'
|
|
2
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
3
3
|
import { AtpAgent } from '@atproto/api'
|
|
4
|
-
import { SeedClient } from './seeds/client'
|
|
5
4
|
import userSeed from './seeds/users'
|
|
6
5
|
|
|
7
6
|
describe('handle invalidation', () => {
|
|
@@ -20,7 +19,7 @@ describe('handle invalidation', () => {
|
|
|
20
19
|
})
|
|
21
20
|
agent = network.bsky.getClient()
|
|
22
21
|
pdsAgent = network.pds.getClient()
|
|
23
|
-
sc =
|
|
22
|
+
sc = network.getSeedClient()
|
|
24
23
|
await userSeed(sc)
|
|
25
24
|
await network.processAll()
|
|
26
25
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import axios, { AxiosInstance } from 'axios'
|
|
2
2
|
import { CID } from 'multiformats/cid'
|
|
3
|
-
import { AtpAgent } from '@atproto/api'
|
|
4
3
|
import { cidForCbor } from '@atproto/common'
|
|
5
4
|
import { TestNetwork } from '@atproto/dev-env'
|
|
6
5
|
import { getInfo } from '../../src/image/sharp'
|
|
7
|
-
import { SeedClient } from '../seeds/client'
|
|
8
6
|
import basicSeed from '../seeds/basic'
|
|
9
7
|
import { ImageUriBuilder } from '../../src/image/uri'
|
|
10
8
|
|
|
@@ -18,8 +16,7 @@ describe('image processing server', () => {
|
|
|
18
16
|
network = await TestNetwork.create({
|
|
19
17
|
dbPostgresSchema: 'bsky_image_processing_server',
|
|
20
18
|
})
|
|
21
|
-
const
|
|
22
|
-
const sc = new SeedClient(pdsAgent)
|
|
19
|
+
const sc = network.getSeedClient()
|
|
23
20
|
await basicSeed(sc)
|
|
24
21
|
await network.processAll()
|
|
25
22
|
await network.bsky.processAll()
|
|
@@ -178,7 +178,7 @@ describe('sharp image processor', () => {
|
|
|
178
178
|
})
|
|
179
179
|
|
|
180
180
|
async function processFixture(fixture: string, options: Options) {
|
|
181
|
-
const image = createReadStream(
|
|
181
|
+
const image = createReadStream(`tests/sample-img/${fixture}`)
|
|
182
182
|
const resized = await resize(image, options)
|
|
183
183
|
return await getInfo(resized)
|
|
184
184
|
}
|