@atproto/dev-env 0.6.8 → 0.6.10
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 +40 -0
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +18 -0
- package/dist/mock/index.js.map +1 -1
- package/dist/pds.d.ts +5 -3
- package/dist/pds.d.ts.map +1 -1
- package/dist/pds.js +22 -13
- package/dist/pds.js.map +1 -1
- package/package.json +13 -13
- package/src/mock/index.ts +20 -0
- package/src/pds.ts +66 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @atproto/dev-env
|
|
2
2
|
|
|
3
|
+
## 0.6.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5572](https://github.com/bluesky-social/atproto/pull/5572) [`0ecd50b`](https://github.com/bluesky-social/atproto/commit/0ecd50b23dffce229ce671d1fac95dd647d06d10) Thanks [@foysalit](https://github.com/foysalit)! - Seed Alice and Bob with adult birthdates and full age assurance in the local development environment.
|
|
8
|
+
- Updated dependencies [[`cd736b3`](https://github.com/bluesky-social/atproto/commit/cd736b3dbbec957cf4eaa7e67fa5b8be8f8ae04e), [`f8ed258`](https://github.com/bluesky-social/atproto/commit/f8ed25853dc91a16639decfaee2e0dcbb60808cd), [`61c915a`](https://github.com/bluesky-social/atproto/commit/61c915a4b7304720496975a07f2f35d38a23bcd4), [`3cd9fa6`](https://github.com/bluesky-social/atproto/commit/3cd9fa6013efad3ab57704ae804952be097e5d26), [`13b7cb0`](https://github.com/bluesky-social/atproto/commit/13b7cb000d7358a570be46854a93e441c8fa791e), [`e8b89ff`](https://github.com/bluesky-social/atproto/commit/e8b89ff4c211a10519b54bd83eb64950035942c3), [`a6561d5`](https://github.com/bluesky-social/atproto/commit/a6561d54227756876a0901e4a87675df17972d32), [`9ce8595`](https://github.com/bluesky-social/atproto/commit/9ce85957ce98c4b8a4ab6b51e0c24c4cd213d464)]:
|
|
9
|
+
- @atproto/api@0.23.0
|
|
10
|
+
- @atproto/bsky@0.1.0
|
|
11
|
+
- @atproto/ozone@0.5.1
|
|
12
|
+
- @atproto/pds@0.5.37
|
|
13
|
+
- @atproto/crypto@0.5.7
|
|
14
|
+
- @atproto/lexicon@0.7.16
|
|
15
|
+
- @atproto/sync@0.4.13
|
|
16
|
+
- @atproto/identity@0.5.16
|
|
17
|
+
- @atproto/xrpc-server@0.13.4
|
|
18
|
+
- @atproto/bsync@0.1.2
|
|
19
|
+
- @atproto/common-web@0.5.14
|
|
20
|
+
- @atproto/lex@0.3.14
|
|
21
|
+
|
|
22
|
+
## 0.6.9
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- [#5562](https://github.com/bluesky-social/atproto/pull/5562) [`f632a35`](https://github.com/bluesky-social/atproto/commit/f632a35e8641644022bf430c6e3b34b1382cab55) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Remove the need to provide a `plcRotationKey` secret when and override is provided
|
|
27
|
+
|
|
28
|
+
- [#5562](https://github.com/bluesky-social/atproto/pull/5562) [`f632a35`](https://github.com/bluesky-social/atproto/commit/f632a35e8641644022bf430c6e3b34b1382cab55) Thanks [@matthieusieben](https://github.com/matthieusieben)! - `TestPds.create` accepts optional `PDS.create` overrides as a second argument.
|
|
29
|
+
- Updated dependencies [[`4c725e6`](https://github.com/bluesky-social/atproto/commit/4c725e670ae67adf0711d08b53108be054e9dcf3), [`f632a35`](https://github.com/bluesky-social/atproto/commit/f632a35e8641644022bf430c6e3b34b1382cab55), [`af8c350`](https://github.com/bluesky-social/atproto/commit/af8c3501cd32e82cf8128683445656aa6708608d), [`5019f55`](https://github.com/bluesky-social/atproto/commit/5019f5537317ee75ad4527db212bc27c3085fe67), [`f632a35`](https://github.com/bluesky-social/atproto/commit/f632a35e8641644022bf430c6e3b34b1382cab55), [`af8c350`](https://github.com/bluesky-social/atproto/commit/af8c3501cd32e82cf8128683445656aa6708608d), [`f5f0aab`](https://github.com/bluesky-social/atproto/commit/f5f0aab4cf3046de3dddd9251a07003d29e3c0be), [`b3d7c33`](https://github.com/bluesky-social/atproto/commit/b3d7c3391e50e4ae9e1b1cbfc9d561c8693507e7), [`136e214`](https://github.com/bluesky-social/atproto/commit/136e2145b893773a94e9620df37be5215cdb57a3), [`7a85798`](https://github.com/bluesky-social/atproto/commit/7a857989751ae31518509d69ab7194a922064f3d), [`f5f0aab`](https://github.com/bluesky-social/atproto/commit/f5f0aab4cf3046de3dddd9251a07003d29e3c0be), [`f632a35`](https://github.com/bluesky-social/atproto/commit/f632a35e8641644022bf430c6e3b34b1382cab55), [`b3d7c33`](https://github.com/bluesky-social/atproto/commit/b3d7c3391e50e4ae9e1b1cbfc9d561c8693507e7), [`136e214`](https://github.com/bluesky-social/atproto/commit/136e2145b893773a94e9620df37be5215cdb57a3)]:
|
|
30
|
+
- @atproto/api@0.22.0
|
|
31
|
+
- @atproto/bsky@0.0.282
|
|
32
|
+
- @atproto/pds@0.5.36
|
|
33
|
+
- @atproto/bsync@0.1.1
|
|
34
|
+
- @atproto/common-web@0.5.13
|
|
35
|
+
- @atproto/crypto@0.5.6
|
|
36
|
+
- @atproto/identity@0.5.15
|
|
37
|
+
- @atproto/lexicon@0.7.15
|
|
38
|
+
- @atproto/ozone@0.5.0
|
|
39
|
+
- @atproto/sync@0.4.12
|
|
40
|
+
- @atproto/xrpc-server@0.13.3
|
|
41
|
+
- @atproto/lex@0.3.13
|
|
42
|
+
|
|
3
43
|
## 0.6.8
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/dist/mock/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mock/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAkB1E,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mock/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAkB1E,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,WAAW,iBA+pBvD"}
|
package/dist/mock/index.js
CHANGED
|
@@ -83,6 +83,24 @@ export async function generateMockSetup(env) {
|
|
|
83
83
|
return agent;
|
|
84
84
|
}));
|
|
85
85
|
const [alice, bob, carla, triage, mod, adminMod, labeler] = userAgents;
|
|
86
|
+
// @NOTE The client uses declared age outside regions requiring age assurance.
|
|
87
|
+
for (const user of [alice, bob]) {
|
|
88
|
+
await user.app.bsky.actor.putPreferences({
|
|
89
|
+
preferences: [
|
|
90
|
+
{
|
|
91
|
+
$type: 'app.bsky.actor.defs#personalDetailsPref',
|
|
92
|
+
birthDate: '1990-01-01T00:00:00.000Z',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// @NOTE Wait for actor rows to exist before seeding age assurance state.
|
|
98
|
+
await env.processAll();
|
|
99
|
+
await env.bsky.db.db
|
|
100
|
+
.updateTable('actor')
|
|
101
|
+
.set({ ageAssuranceStatus: 'assured', ageAssuranceAccess: 'full' })
|
|
102
|
+
.where('did', 'in', [alice.did, bob.did])
|
|
103
|
+
.execute();
|
|
86
104
|
// Create chat declarations for all users
|
|
87
105
|
for (const user of userAgents) {
|
|
88
106
|
await user.chat.bsky.actor.declaration.create({ repo: user.did }, { allowIncoming: 'all' });
|
package/dist/mock/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mock/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtpAgent,\n COM_ATPROTO_MODERATION,\n ToolsOzoneQueueCreateQueue,\n} from '@atproto/api'\nimport type { Database } from '@atproto/bsky'\nimport { AtUri, type AtUriString } from '@atproto/syntax'\nimport { EXAMPLE_LABELER, RecordRef, type TestNetwork } from '../index.js'\nimport { postTexts, replyTexts } from './data.js'\nimport blurHashB64 from './img/blur-hash-avatar-b64.js'\nimport labeledImgB64 from './img/labeled-img-b64.js'\n\n// NOTE\n// deterministic date generator\n// we use this to ensure the mock dataset is always the same\n// which is very useful when testing\n// (not everything is currently deterministic but it could be)\nfunction* dateGen(): Generator<string, never> {\n let start = 1657846031914\n while (true) {\n yield new Date(start).toISOString()\n start += 1e3\n }\n}\n\nexport async function generateMockSetup(env: TestNetwork) {\n const date = dateGen()\n\n const rand = (n: number) => Math.floor(Math.random() * n)\n const picka = <T>(arr: Array<T>): T => {\n if (arr.length) {\n return arr[rand(arr.length)] || arr[0]\n }\n throw new Error('Not found')\n }\n\n const users = [\n {\n email: 'alice@test.com',\n handle: `alice.test`,\n password: 'hunter2',\n displayName: 'Alice',\n description: 'Test user 0',\n },\n {\n email: 'bob@test.com',\n handle: `bob.test`,\n password: 'hunter2',\n displayName: 'Bob',\n description: 'Test user 1',\n },\n {\n email: 'carla@test.com',\n handle: `carla.test`,\n password: 'hunter2',\n displayName: 'Carla',\n description: 'Test user 2',\n },\n {\n email: 'triage@test.com',\n handle: 'triage.test',\n password: 'triage-pass',\n },\n {\n email: 'mod@test.com',\n handle: 'mod.test',\n password: 'mod-pass',\n },\n {\n email: 'admin-mod@test.com',\n handle: 'admin-mod.test',\n password: 'admin-mod-pass',\n },\n {\n email: 'labeler@test.com',\n handle: 'labeler.test',\n password: 'hunter2',\n displayName: 'Test Labeler',\n description: 'Labeling things across the atmosphere',\n },\n ]\n\n const userAgents = await Promise.all(\n users.map(async (user) => {\n const agent: AtpAgent = env.pds.getAgent()\n await agent.createAccount(user)\n agent.assertAuthenticated()\n if (user.displayName || user.description) {\n await agent.app.bsky.actor.profile.create(\n { repo: agent.did },\n {\n displayName: user.displayName,\n description: user.description,\n },\n )\n }\n return agent\n }),\n )\n\n const [alice, bob, carla, triage, mod, adminMod, labeler] = userAgents\n\n // Create chat declarations for all users\n for (const user of userAgents) {\n await user.chat.bsky.actor.declaration.create(\n { repo: user.did },\n { allowIncoming: 'all' },\n )\n }\n\n // Add moderator roles\n await env.ozone.addTriageDid(triage.did)\n await env.ozone.addModeratorDid(mod.did)\n await env.ozone.addAdminDid(adminMod.did)\n\n // Create report queues\n const ozoneAgent = env.ozone.getAgent()\n const adminHeaders = async (nsid: string) =>\n env.ozone.modHeaders(nsid, 'admin')\n\n const createQueue = async (input: {\n name: string\n subjectTypes: string[]\n reportTypes: string[]\n collection?: string\n }): Promise<void> => {\n try {\n await ozoneAgent.tools.ozone.queue.createQueue(input, {\n encoding: 'application/json',\n headers: await adminHeaders('tools.ozone.queue.createQueue'),\n })\n } catch (err) {\n if (!(err instanceof ToolsOzoneQueueCreateQueue.ConflictingQueueError)) {\n throw err\n }\n }\n }\n\n await Promise.all([\n createQueue({\n name: 'Spammy Accounts',\n subjectTypes: ['account'],\n reportTypes: [COM_ATPROTO_MODERATION.DefsReasonSpam],\n }),\n createQueue({\n name: 'Threatening Accounts',\n subjectTypes: ['account'],\n reportTypes: ['tools.ozone.report.defs#reasonViolenceThreats'],\n }),\n createQueue({\n name: 'Spammy Posts',\n subjectTypes: ['record'],\n reportTypes: [COM_ATPROTO_MODERATION.DefsReasonSpam],\n collection: 'app.bsky.feed.post',\n }),\n ])\n\n // Report one user (random)\n const reporter = picka(userAgents)\n await reporter.com.atproto.moderation.createReport({\n reasonType: picka([\n COM_ATPROTO_MODERATION.DefsReasonSpam,\n COM_ATPROTO_MODERATION.DefsReasonOther,\n ]),\n reason: picka([\"Didn't look right to me\", undefined, undefined]),\n subject: {\n $type: 'com.atproto.admin.defs#repoRef',\n did: picka(userAgents).did,\n },\n })\n\n // Reports that target queues\n await alice.com.atproto.moderation.createReport({\n reasonType: COM_ATPROTO_MODERATION.DefsReasonSpam,\n reason: 'This account is spamming',\n subject: { $type: 'com.atproto.admin.defs#repoRef', did: bob.did },\n })\n await bob.com.atproto.moderation.createReport({\n reasonType: 'tools.ozone.report.defs#reasonViolenceThreats',\n reason: 'Threatened me',\n subject: {\n $type: 'com.atproto.admin.defs#repoRef',\n did: carla.did,\n },\n })\n\n // everybody follows everybody\n const follow = async (author: AtpAgent, subject: AtpAgent) => {\n await author.app.bsky.graph.follow.create(\n { repo: author.assertDid },\n {\n subject: subject.assertDid,\n createdAt: date.next().value,\n },\n )\n }\n await follow(alice, bob)\n await follow(alice, carla)\n await follow(bob, alice)\n await follow(bob, carla)\n await follow(carla, alice)\n await follow(carla, bob)\n\n // a set of posts and reposts\n const posts: { uri: string; cid: string }[] = []\n for (let i = 0; i < postTexts.length; i++) {\n const author = picka(userAgents)\n const post = await author.app.bsky.feed.post.create(\n { repo: author.did },\n {\n text: postTexts[i],\n createdAt: date.next().value,\n },\n )\n posts.push(post)\n if (rand(10) === 0) {\n const reposter = picka(userAgents)\n await reposter.app.bsky.feed.repost.create(\n { repo: reposter.did },\n {\n subject: picka(posts),\n createdAt: date.next().value,\n },\n )\n }\n if (rand(6) === 0) {\n const reporter = picka(userAgents)\n await reporter.com.atproto.moderation.createReport({\n reasonType: picka([\n COM_ATPROTO_MODERATION.DefsReasonSpam,\n COM_ATPROTO_MODERATION.DefsReasonOther,\n ]),\n reason: picka([\"Didn't look right to me\", undefined, undefined]),\n subject: {\n $type: 'com.atproto.repo.strongRef',\n uri: post.uri,\n cid: post.cid,\n },\n })\n }\n }\n\n // Spam post report\n if (posts.length > 0) {\n await carla.com.atproto.moderation.createReport({\n reasonType: COM_ATPROTO_MODERATION.DefsReasonSpam,\n reason: 'This post is spam',\n subject: {\n $type: 'com.atproto.repo.strongRef',\n uri: posts[0].uri,\n cid: posts[0].cid,\n },\n })\n }\n\n // Route all reports to queues\n await env.ozone.daemon.ctx.queueRouter.routeReports()\n\n // make some naughty posts & label them\n const file = Buffer.from(labeledImgB64, 'base64')\n const uploadedImg = await bob.com.atproto.repo.uploadBlob(file, {\n encoding: 'image/png',\n })\n const labeledPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'naughty post',\n embed: {\n $type: 'app.bsky.embed.images',\n images: [\n {\n image: uploadedImg.data.blob,\n alt: 'naughty naughty',\n },\n ],\n },\n createdAt: date.next().value,\n },\n )\n\n const filteredPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'really bad post should be deleted',\n createdAt: date.next().value,\n },\n )\n\n await createLabel(env.bsky.db, {\n uri: labeledPost.uri,\n cid: labeledPost.cid,\n val: 'nudity',\n })\n await createLabel(env.bsky.db, {\n uri: filteredPost.uri,\n cid: filteredPost.cid,\n val: 'dmca-violation',\n })\n\n // post with a gallery of images\n const galleryItems: Array<any> = []\n for (let i = 0; i < 10; i++) {\n galleryItems.push({\n $type: 'app.bsky.embed.gallery#image',\n image: uploadedImg.data.blob,\n alt: 'naughty ' + (i + 1),\n aspectRatio: {\n $type: 'app.bsky.embed.defs#aspectRatio',\n width: 10,\n height: 10,\n },\n })\n }\n const galleryPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'look at my cool pics',\n embed: {\n $type: 'app.bsky.embed.gallery',\n items: galleryItems,\n },\n createdAt: date.next().value,\n },\n )\n posts.push(galleryPost)\n\n // a set of replies\n for (let i = 0; i < 100; i++) {\n const targetUri = picka(posts).uri\n const urip = new AtUri(targetUri)\n const target = await alice.app.bsky.feed.post.get({\n repo: urip.host,\n rkey: urip.rkey,\n })\n const author = picka(userAgents)\n try {\n const post = await author.app.bsky.feed.post.create(\n { repo: author.did },\n {\n text: picka(replyTexts),\n reply: {\n root: target.value.reply?.root ?? target,\n parent: target,\n },\n createdAt: date.next().value,\n },\n )\n\n posts.push(post)\n } catch (err) {\n // @TODO Investigate why this sometimes fails.\n console.error('Failed to create reply', err)\n }\n }\n\n // a set of likes\n for (const post of posts) {\n for (const user of userAgents) {\n if (rand(3) === 0) {\n await user.app.bsky.feed.like.create(\n { repo: user.did },\n {\n subject: post,\n createdAt: date.next().value,\n },\n )\n }\n }\n }\n\n // a couple feed generators that returns some posts\n const fg1Uri = AtUri.make(\n alice.assertDid,\n 'app.bsky.feed.generator',\n 'alice-favs',\n )\n const fg1 = await env.createFeedGen({\n [fg1Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const avatarImg = Buffer.from(blurHashB64, 'base64')\n const avatarRes = await alice.com.atproto.repo.uploadBlob(avatarImg, {\n encoding: 'image/png',\n })\n const fgAliceRes = await alice.app.bsky.feed.generator.create(\n { repo: alice.assertDid, rkey: fg1Uri.rkey },\n {\n did: fg1.did,\n displayName: 'alices feed',\n description: 'all my fav stuff',\n avatar: avatarRes.data.blob,\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: 'check out my algorithm!',\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgAliceRes,\n },\n createdAt: date.next().value,\n },\n )\n for (const user of [alice, bob, carla]) {\n await user.app.bsky.feed.like.create(\n { repo: user.did },\n {\n subject: fgAliceRes,\n createdAt: date.next().value,\n },\n )\n }\n\n const fg2Uri = AtUri.make(\n bob.assertDid,\n 'app.bsky.feed.generator',\n 'bob-redux',\n )\n const fg2 = await env.createFeedGen({\n [fg2Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const fgBobRes = await bob.app.bsky.feed.generator.create(\n { repo: bob.assertDid, rkey: fg2Uri.rkey },\n {\n did: fg2.did,\n displayName: 'Bobby boy hot new algo',\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: `bobs feed is neat too`,\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgBobRes,\n },\n createdAt: date.next().value,\n },\n )\n\n const fg3Uri = AtUri.make(\n carla.assertDid,\n 'app.bsky.feed.generator',\n 'carla-intr-algo',\n )\n const fg3 = await env.createFeedGen({\n [fg3Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const fgCarlaRes = await carla.app.bsky.feed.generator.create(\n { repo: carla.assertDid, rkey: fg3Uri.rkey },\n {\n did: fg3.did,\n displayName: `Acceptin' Generator`,\n acceptsInteractions: true,\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: `carla accepts interactions on her feed`,\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgCarlaRes,\n },\n createdAt: date.next().value,\n },\n )\n\n // create labeler service\n {\n await labeler.app.bsky.labeler.service.create(\n { repo: labeler.did, rkey: 'self' },\n {\n policies: {\n labelValues: [\n '!hide',\n 'porn',\n 'rude',\n 'spam',\n 'spider',\n 'misinfo',\n 'cool',\n 'curate',\n ],\n labelValueDefinitions: [\n {\n identifier: 'rude',\n blurs: 'content',\n severity: 'alert',\n defaultSetting: 'warn',\n adultOnly: true,\n locales: [\n {\n lang: 'en',\n name: 'Rude',\n description: 'Just such a jerk, you wouldnt believe it.',\n },\n ],\n },\n {\n identifier: 'spam',\n blurs: 'content',\n severity: 'inform',\n defaultSetting: 'hide',\n locales: [\n {\n lang: 'en',\n name: 'Spam',\n description:\n 'Low quality posts that dont add to the conversation.',\n },\n ],\n },\n {\n identifier: 'spider',\n blurs: 'media',\n severity: 'alert',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Spider!',\n description: 'Oh no its a spider.',\n },\n ],\n },\n {\n identifier: 'cool',\n blurs: 'none',\n severity: 'inform',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Cool',\n description: 'The coolest peeps in the atmosphere.',\n },\n ],\n },\n {\n identifier: 'curate',\n blurs: 'none',\n severity: 'none',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Curation filter',\n description: 'We just dont want to see it as much.',\n },\n ],\n },\n ],\n },\n createdAt: date.next().value,\n },\n )\n await createLabel(env.bsky.db, {\n uri: alice.assertDid,\n cid: '',\n val: 'rude',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: `at://${alice.assertDid}/app.bsky.feed.generator/alice-favs`,\n cid: '',\n val: 'cool',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: bob.assertDid,\n cid: '',\n val: 'cool',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: carla.assertDid,\n cid: '',\n val: 'spam',\n src: labeler.did,\n })\n }\n\n // Create lists and add people to the lists\n {\n const flowerLovers = await alice.app.bsky.graph.list.create(\n { repo: alice.assertDid },\n {\n name: 'Flower Lovers',\n purpose: 'app.bsky.graph.defs#curatelist',\n createdAt: new Date().toISOString(),\n description: 'A list of posts about flowers',\n },\n )\n const labelHaters = await bob.app.bsky.graph.list.create(\n { repo: bob.assertDid },\n {\n name: 'Label Haters',\n purpose: 'app.bsky.graph.defs#modlist',\n createdAt: new Date().toISOString(),\n description: 'A list of people who hate labels',\n },\n )\n await alice.app.bsky.graph.listitem.create(\n { repo: alice.assertDid },\n {\n subject: bob.assertDid,\n createdAt: new Date().toISOString(),\n list: new RecordRef(flowerLovers.uri, flowerLovers.cid).uriStr,\n },\n )\n await bob.app.bsky.graph.listitem.create(\n { repo: bob.assertDid },\n {\n subject: alice.assertDid,\n createdAt: new Date().toISOString(),\n list: new RecordRef(labelHaters.uri, labelHaters.cid).uriStr,\n },\n )\n }\n\n await setVerifier(env.bsky.db, alice.assertDid)\n\n // @TODO These are useful when testing complex threads, but don't need to be enabled all the time. We could make it configurable.\n // import * as seedThreadV2 from '../seed/thread-v2.js'\n // const sc = env.getSeedClient()\n // await seedThreadV2.simple(sc)\n // await seedThreadV2.long(sc)\n // await seedThreadV2.deep(sc)\n // await seedThreadV2.branchingFactor(sc)\n // await seedThreadV2.annotateMoreReplies(sc)\n // await seedThreadV2.annotateOP(sc)\n // await seedThreadV2.sort(sc)\n // await seedThreadV2.bumpOpAndViewer(sc)\n // await seedThreadV2.bumpGroupSorting(sc)\n // await seedThreadV2.bumpFollows(sc)\n // await seedThreadV2.blockDeletionAuth(sc, env.bsky.ctx.cfg.modServiceDid)\n // await seedThreadV2.mutes(sc)\n // await seedThreadV2.threadgated(sc)\n // await seedThreadV2.tags(sc)\n}\n\nconst createLabel = async (\n db: Database,\n opts: { uri: string; cid: string; val: string; src?: string },\n) => {\n await db.db\n .insertInto('label')\n .values({\n uri: opts.uri,\n cid: opts.cid,\n val: opts.val,\n cts: new Date().toISOString(),\n neg: false,\n src: opts.src ?? EXAMPLE_LABELER,\n })\n .execute()\n}\n\nconst setVerifier = async (db: Database, did: string) => {\n await db.db\n .updateTable('actor')\n .set({ trustedVerifier: true })\n .where('did', '=', did)\n .execute()\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mock/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AtpAgent,\n COM_ATPROTO_MODERATION,\n ToolsOzoneQueueCreateQueue,\n} from '@atproto/api'\nimport type { Database } from '@atproto/bsky'\nimport { AtUri, type AtUriString } from '@atproto/syntax'\nimport { EXAMPLE_LABELER, RecordRef, type TestNetwork } from '../index.js'\nimport { postTexts, replyTexts } from './data.js'\nimport blurHashB64 from './img/blur-hash-avatar-b64.js'\nimport labeledImgB64 from './img/labeled-img-b64.js'\n\n// NOTE\n// deterministic date generator\n// we use this to ensure the mock dataset is always the same\n// which is very useful when testing\n// (not everything is currently deterministic but it could be)\nfunction* dateGen(): Generator<string, never> {\n let start = 1657846031914\n while (true) {\n yield new Date(start).toISOString()\n start += 1e3\n }\n}\n\nexport async function generateMockSetup(env: TestNetwork) {\n const date = dateGen()\n\n const rand = (n: number) => Math.floor(Math.random() * n)\n const picka = <T>(arr: Array<T>): T => {\n if (arr.length) {\n return arr[rand(arr.length)] || arr[0]\n }\n throw new Error('Not found')\n }\n\n const users = [\n {\n email: 'alice@test.com',\n handle: `alice.test`,\n password: 'hunter2',\n displayName: 'Alice',\n description: 'Test user 0',\n },\n {\n email: 'bob@test.com',\n handle: `bob.test`,\n password: 'hunter2',\n displayName: 'Bob',\n description: 'Test user 1',\n },\n {\n email: 'carla@test.com',\n handle: `carla.test`,\n password: 'hunter2',\n displayName: 'Carla',\n description: 'Test user 2',\n },\n {\n email: 'triage@test.com',\n handle: 'triage.test',\n password: 'triage-pass',\n },\n {\n email: 'mod@test.com',\n handle: 'mod.test',\n password: 'mod-pass',\n },\n {\n email: 'admin-mod@test.com',\n handle: 'admin-mod.test',\n password: 'admin-mod-pass',\n },\n {\n email: 'labeler@test.com',\n handle: 'labeler.test',\n password: 'hunter2',\n displayName: 'Test Labeler',\n description: 'Labeling things across the atmosphere',\n },\n ]\n\n const userAgents = await Promise.all(\n users.map(async (user) => {\n const agent: AtpAgent = env.pds.getAgent()\n await agent.createAccount(user)\n agent.assertAuthenticated()\n if (user.displayName || user.description) {\n await agent.app.bsky.actor.profile.create(\n { repo: agent.did },\n {\n displayName: user.displayName,\n description: user.description,\n },\n )\n }\n return agent\n }),\n )\n\n const [alice, bob, carla, triage, mod, adminMod, labeler] = userAgents\n\n // @NOTE The client uses declared age outside regions requiring age assurance.\n for (const user of [alice, bob]) {\n await user.app.bsky.actor.putPreferences({\n preferences: [\n {\n $type: 'app.bsky.actor.defs#personalDetailsPref',\n birthDate: '1990-01-01T00:00:00.000Z',\n },\n ],\n })\n }\n\n // @NOTE Wait for actor rows to exist before seeding age assurance state.\n await env.processAll()\n await env.bsky.db.db\n .updateTable('actor')\n .set({ ageAssuranceStatus: 'assured', ageAssuranceAccess: 'full' })\n .where('did', 'in', [alice.did, bob.did])\n .execute()\n\n // Create chat declarations for all users\n for (const user of userAgents) {\n await user.chat.bsky.actor.declaration.create(\n { repo: user.did },\n { allowIncoming: 'all' },\n )\n }\n\n // Add moderator roles\n await env.ozone.addTriageDid(triage.did)\n await env.ozone.addModeratorDid(mod.did)\n await env.ozone.addAdminDid(adminMod.did)\n\n // Create report queues\n const ozoneAgent = env.ozone.getAgent()\n const adminHeaders = async (nsid: string) =>\n env.ozone.modHeaders(nsid, 'admin')\n\n const createQueue = async (input: {\n name: string\n subjectTypes: string[]\n reportTypes: string[]\n collection?: string\n }): Promise<void> => {\n try {\n await ozoneAgent.tools.ozone.queue.createQueue(input, {\n encoding: 'application/json',\n headers: await adminHeaders('tools.ozone.queue.createQueue'),\n })\n } catch (err) {\n if (!(err instanceof ToolsOzoneQueueCreateQueue.ConflictingQueueError)) {\n throw err\n }\n }\n }\n\n await Promise.all([\n createQueue({\n name: 'Spammy Accounts',\n subjectTypes: ['account'],\n reportTypes: [COM_ATPROTO_MODERATION.DefsReasonSpam],\n }),\n createQueue({\n name: 'Threatening Accounts',\n subjectTypes: ['account'],\n reportTypes: ['tools.ozone.report.defs#reasonViolenceThreats'],\n }),\n createQueue({\n name: 'Spammy Posts',\n subjectTypes: ['record'],\n reportTypes: [COM_ATPROTO_MODERATION.DefsReasonSpam],\n collection: 'app.bsky.feed.post',\n }),\n ])\n\n // Report one user (random)\n const reporter = picka(userAgents)\n await reporter.com.atproto.moderation.createReport({\n reasonType: picka([\n COM_ATPROTO_MODERATION.DefsReasonSpam,\n COM_ATPROTO_MODERATION.DefsReasonOther,\n ]),\n reason: picka([\"Didn't look right to me\", undefined, undefined]),\n subject: {\n $type: 'com.atproto.admin.defs#repoRef',\n did: picka(userAgents).did,\n },\n })\n\n // Reports that target queues\n await alice.com.atproto.moderation.createReport({\n reasonType: COM_ATPROTO_MODERATION.DefsReasonSpam,\n reason: 'This account is spamming',\n subject: { $type: 'com.atproto.admin.defs#repoRef', did: bob.did },\n })\n await bob.com.atproto.moderation.createReport({\n reasonType: 'tools.ozone.report.defs#reasonViolenceThreats',\n reason: 'Threatened me',\n subject: {\n $type: 'com.atproto.admin.defs#repoRef',\n did: carla.did,\n },\n })\n\n // everybody follows everybody\n const follow = async (author: AtpAgent, subject: AtpAgent) => {\n await author.app.bsky.graph.follow.create(\n { repo: author.assertDid },\n {\n subject: subject.assertDid,\n createdAt: date.next().value,\n },\n )\n }\n await follow(alice, bob)\n await follow(alice, carla)\n await follow(bob, alice)\n await follow(bob, carla)\n await follow(carla, alice)\n await follow(carla, bob)\n\n // a set of posts and reposts\n const posts: { uri: string; cid: string }[] = []\n for (let i = 0; i < postTexts.length; i++) {\n const author = picka(userAgents)\n const post = await author.app.bsky.feed.post.create(\n { repo: author.did },\n {\n text: postTexts[i],\n createdAt: date.next().value,\n },\n )\n posts.push(post)\n if (rand(10) === 0) {\n const reposter = picka(userAgents)\n await reposter.app.bsky.feed.repost.create(\n { repo: reposter.did },\n {\n subject: picka(posts),\n createdAt: date.next().value,\n },\n )\n }\n if (rand(6) === 0) {\n const reporter = picka(userAgents)\n await reporter.com.atproto.moderation.createReport({\n reasonType: picka([\n COM_ATPROTO_MODERATION.DefsReasonSpam,\n COM_ATPROTO_MODERATION.DefsReasonOther,\n ]),\n reason: picka([\"Didn't look right to me\", undefined, undefined]),\n subject: {\n $type: 'com.atproto.repo.strongRef',\n uri: post.uri,\n cid: post.cid,\n },\n })\n }\n }\n\n // Spam post report\n if (posts.length > 0) {\n await carla.com.atproto.moderation.createReport({\n reasonType: COM_ATPROTO_MODERATION.DefsReasonSpam,\n reason: 'This post is spam',\n subject: {\n $type: 'com.atproto.repo.strongRef',\n uri: posts[0].uri,\n cid: posts[0].cid,\n },\n })\n }\n\n // Route all reports to queues\n await env.ozone.daemon.ctx.queueRouter.routeReports()\n\n // make some naughty posts & label them\n const file = Buffer.from(labeledImgB64, 'base64')\n const uploadedImg = await bob.com.atproto.repo.uploadBlob(file, {\n encoding: 'image/png',\n })\n const labeledPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'naughty post',\n embed: {\n $type: 'app.bsky.embed.images',\n images: [\n {\n image: uploadedImg.data.blob,\n alt: 'naughty naughty',\n },\n ],\n },\n createdAt: date.next().value,\n },\n )\n\n const filteredPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'really bad post should be deleted',\n createdAt: date.next().value,\n },\n )\n\n await createLabel(env.bsky.db, {\n uri: labeledPost.uri,\n cid: labeledPost.cid,\n val: 'nudity',\n })\n await createLabel(env.bsky.db, {\n uri: filteredPost.uri,\n cid: filteredPost.cid,\n val: 'dmca-violation',\n })\n\n // post with a gallery of images\n const galleryItems: Array<any> = []\n for (let i = 0; i < 10; i++) {\n galleryItems.push({\n $type: 'app.bsky.embed.gallery#image',\n image: uploadedImg.data.blob,\n alt: 'naughty ' + (i + 1),\n aspectRatio: {\n $type: 'app.bsky.embed.defs#aspectRatio',\n width: 10,\n height: 10,\n },\n })\n }\n const galleryPost = await bob.app.bsky.feed.post.create(\n { repo: bob.assertDid },\n {\n text: 'look at my cool pics',\n embed: {\n $type: 'app.bsky.embed.gallery',\n items: galleryItems,\n },\n createdAt: date.next().value,\n },\n )\n posts.push(galleryPost)\n\n // a set of replies\n for (let i = 0; i < 100; i++) {\n const targetUri = picka(posts).uri\n const urip = new AtUri(targetUri)\n const target = await alice.app.bsky.feed.post.get({\n repo: urip.host,\n rkey: urip.rkey,\n })\n const author = picka(userAgents)\n try {\n const post = await author.app.bsky.feed.post.create(\n { repo: author.did },\n {\n text: picka(replyTexts),\n reply: {\n root: target.value.reply?.root ?? target,\n parent: target,\n },\n createdAt: date.next().value,\n },\n )\n\n posts.push(post)\n } catch (err) {\n // @TODO Investigate why this sometimes fails.\n console.error('Failed to create reply', err)\n }\n }\n\n // a set of likes\n for (const post of posts) {\n for (const user of userAgents) {\n if (rand(3) === 0) {\n await user.app.bsky.feed.like.create(\n { repo: user.did },\n {\n subject: post,\n createdAt: date.next().value,\n },\n )\n }\n }\n }\n\n // a couple feed generators that returns some posts\n const fg1Uri = AtUri.make(\n alice.assertDid,\n 'app.bsky.feed.generator',\n 'alice-favs',\n )\n const fg1 = await env.createFeedGen({\n [fg1Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const avatarImg = Buffer.from(blurHashB64, 'base64')\n const avatarRes = await alice.com.atproto.repo.uploadBlob(avatarImg, {\n encoding: 'image/png',\n })\n const fgAliceRes = await alice.app.bsky.feed.generator.create(\n { repo: alice.assertDid, rkey: fg1Uri.rkey },\n {\n did: fg1.did,\n displayName: 'alices feed',\n description: 'all my fav stuff',\n avatar: avatarRes.data.blob,\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: 'check out my algorithm!',\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgAliceRes,\n },\n createdAt: date.next().value,\n },\n )\n for (const user of [alice, bob, carla]) {\n await user.app.bsky.feed.like.create(\n { repo: user.did },\n {\n subject: fgAliceRes,\n createdAt: date.next().value,\n },\n )\n }\n\n const fg2Uri = AtUri.make(\n bob.assertDid,\n 'app.bsky.feed.generator',\n 'bob-redux',\n )\n const fg2 = await env.createFeedGen({\n [fg2Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const fgBobRes = await bob.app.bsky.feed.generator.create(\n { repo: bob.assertDid, rkey: fg2Uri.rkey },\n {\n did: fg2.did,\n displayName: 'Bobby boy hot new algo',\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: `bobs feed is neat too`,\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgBobRes,\n },\n createdAt: date.next().value,\n },\n )\n\n const fg3Uri = AtUri.make(\n carla.assertDid,\n 'app.bsky.feed.generator',\n 'carla-intr-algo',\n )\n const fg3 = await env.createFeedGen({\n [fg3Uri.toString()]: async () => {\n const feed = posts\n .filter(() => rand(2) === 0)\n .map((post) => ({ post: post.uri as AtUriString }))\n return {\n encoding: 'application/json',\n body: {\n feed,\n },\n }\n },\n })\n const fgCarlaRes = await carla.app.bsky.feed.generator.create(\n { repo: carla.assertDid, rkey: fg3Uri.rkey },\n {\n did: fg3.did,\n displayName: `Acceptin' Generator`,\n acceptsInteractions: true,\n createdAt: date.next().value,\n },\n )\n\n await alice.app.bsky.feed.post.create(\n { repo: alice.assertDid },\n {\n text: `carla accepts interactions on her feed`,\n embed: {\n $type: 'app.bsky.embed.record',\n record: fgCarlaRes,\n },\n createdAt: date.next().value,\n },\n )\n\n // create labeler service\n {\n await labeler.app.bsky.labeler.service.create(\n { repo: labeler.did, rkey: 'self' },\n {\n policies: {\n labelValues: [\n '!hide',\n 'porn',\n 'rude',\n 'spam',\n 'spider',\n 'misinfo',\n 'cool',\n 'curate',\n ],\n labelValueDefinitions: [\n {\n identifier: 'rude',\n blurs: 'content',\n severity: 'alert',\n defaultSetting: 'warn',\n adultOnly: true,\n locales: [\n {\n lang: 'en',\n name: 'Rude',\n description: 'Just such a jerk, you wouldnt believe it.',\n },\n ],\n },\n {\n identifier: 'spam',\n blurs: 'content',\n severity: 'inform',\n defaultSetting: 'hide',\n locales: [\n {\n lang: 'en',\n name: 'Spam',\n description:\n 'Low quality posts that dont add to the conversation.',\n },\n ],\n },\n {\n identifier: 'spider',\n blurs: 'media',\n severity: 'alert',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Spider!',\n description: 'Oh no its a spider.',\n },\n ],\n },\n {\n identifier: 'cool',\n blurs: 'none',\n severity: 'inform',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Cool',\n description: 'The coolest peeps in the atmosphere.',\n },\n ],\n },\n {\n identifier: 'curate',\n blurs: 'none',\n severity: 'none',\n defaultSetting: 'warn',\n locales: [\n {\n lang: 'en',\n name: 'Curation filter',\n description: 'We just dont want to see it as much.',\n },\n ],\n },\n ],\n },\n createdAt: date.next().value,\n },\n )\n await createLabel(env.bsky.db, {\n uri: alice.assertDid,\n cid: '',\n val: 'rude',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: `at://${alice.assertDid}/app.bsky.feed.generator/alice-favs`,\n cid: '',\n val: 'cool',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: bob.assertDid,\n cid: '',\n val: 'cool',\n src: labeler.did,\n })\n await createLabel(env.bsky.db, {\n uri: carla.assertDid,\n cid: '',\n val: 'spam',\n src: labeler.did,\n })\n }\n\n // Create lists and add people to the lists\n {\n const flowerLovers = await alice.app.bsky.graph.list.create(\n { repo: alice.assertDid },\n {\n name: 'Flower Lovers',\n purpose: 'app.bsky.graph.defs#curatelist',\n createdAt: new Date().toISOString(),\n description: 'A list of posts about flowers',\n },\n )\n const labelHaters = await bob.app.bsky.graph.list.create(\n { repo: bob.assertDid },\n {\n name: 'Label Haters',\n purpose: 'app.bsky.graph.defs#modlist',\n createdAt: new Date().toISOString(),\n description: 'A list of people who hate labels',\n },\n )\n await alice.app.bsky.graph.listitem.create(\n { repo: alice.assertDid },\n {\n subject: bob.assertDid,\n createdAt: new Date().toISOString(),\n list: new RecordRef(flowerLovers.uri, flowerLovers.cid).uriStr,\n },\n )\n await bob.app.bsky.graph.listitem.create(\n { repo: bob.assertDid },\n {\n subject: alice.assertDid,\n createdAt: new Date().toISOString(),\n list: new RecordRef(labelHaters.uri, labelHaters.cid).uriStr,\n },\n )\n }\n\n await setVerifier(env.bsky.db, alice.assertDid)\n\n // @TODO These are useful when testing complex threads, but don't need to be enabled all the time. We could make it configurable.\n // import * as seedThreadV2 from '../seed/thread-v2.js'\n // const sc = env.getSeedClient()\n // await seedThreadV2.simple(sc)\n // await seedThreadV2.long(sc)\n // await seedThreadV2.deep(sc)\n // await seedThreadV2.branchingFactor(sc)\n // await seedThreadV2.annotateMoreReplies(sc)\n // await seedThreadV2.annotateOP(sc)\n // await seedThreadV2.sort(sc)\n // await seedThreadV2.bumpOpAndViewer(sc)\n // await seedThreadV2.bumpGroupSorting(sc)\n // await seedThreadV2.bumpFollows(sc)\n // await seedThreadV2.blockDeletionAuth(sc, env.bsky.ctx.cfg.modServiceDid)\n // await seedThreadV2.mutes(sc)\n // await seedThreadV2.threadgated(sc)\n // await seedThreadV2.tags(sc)\n}\n\nconst createLabel = async (\n db: Database,\n opts: { uri: string; cid: string; val: string; src?: string },\n) => {\n await db.db\n .insertInto('label')\n .values({\n uri: opts.uri,\n cid: opts.cid,\n val: opts.val,\n cts: new Date().toISOString(),\n neg: false,\n src: opts.src ?? EXAMPLE_LABELER,\n })\n .execute()\n}\n\nconst setVerifier = async (db: Database, did: string) => {\n await db.db\n .updateTable('actor')\n .set({ trustedVerifier: true })\n .where('did', '=', did)\n .execute()\n}\n"]}
|
package/dist/pds.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { AtpAgent } from '@atproto/api';
|
|
2
2
|
import { Client, type UriString } from '@atproto/lex';
|
|
3
|
-
import { type AppContext, PDS } from '@atproto/pds';
|
|
3
|
+
import { type AppContext, type AppContextOptions, type KeyObject, PDS } from '@atproto/pds';
|
|
4
4
|
import type { PdsConfig } from './types.js';
|
|
5
|
+
export { AtpAgent, Client, PDS };
|
|
6
|
+
export type { AppContextOptions, KeyObject, PdsConfig, UriString };
|
|
5
7
|
export declare class TestPds {
|
|
6
8
|
url: UriString;
|
|
7
9
|
port: number;
|
|
8
10
|
server: PDS;
|
|
9
11
|
constructor(url: UriString, port: number, server: PDS);
|
|
10
|
-
static create(
|
|
12
|
+
static create(env: PdsConfig, overrides?: Partial<AppContextOptions>): Promise<TestPds>;
|
|
11
13
|
get ctx(): AppContext;
|
|
12
14
|
getAgent(): AtpAgent;
|
|
13
15
|
getClient(): Client;
|
|
@@ -15,7 +17,7 @@ export declare class TestPds {
|
|
|
15
17
|
adminAuthHeaders(): {
|
|
16
18
|
authorization: string;
|
|
17
19
|
};
|
|
18
|
-
jwtSecretKey():
|
|
20
|
+
jwtSecretKey(): KeyObject;
|
|
19
21
|
processAll(): Promise<void>;
|
|
20
22
|
close(): Promise<void>;
|
|
21
23
|
[Symbol.asyncDispose](): Promise<void>;
|
package/dist/pds.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pds.d.ts","sourceRoot":"","sources":["../src/pds.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,
|
|
1
|
+
{"version":3,"file":"pds.d.ts","sourceRoot":"","sources":["../src/pds.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EACL,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,GAAG,EAEJ,MAAM,cAAc,CAAA;AAGrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;AAChC,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,CAAA;AAElE,qBAAa,OAAO;IAET,GAAG,EAAE,SAAS;IACd,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,GAAG;IAHpB,YACS,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,GAAG,EAChB;IAEJ,OAAa,MAAM,CACjB,GAAG,EAAE,SAAS,EACd,SAAS,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACrC,OAAO,CAAC,OAAO,CAAC,CAgDlB;IAED,IAAI,GAAG,IAAI,UAAU,CAEpB;IAED,QAAQ,IAAI,QAAQ,CAInB;IAED,SAAS,IAAI,MAAM,CAIlB;IAED,SAAS,IAAI,MAAM,CAQlB;IAED,gBAAgB;QAEZ,aAAa;MAEhB;IAED,YAAY,cAEX;IAEK,UAAU,kBAEf;IAEK,KAAK,kBAEV;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,kBAE1B;CACF"}
|
package/dist/pds.js
CHANGED
|
@@ -5,29 +5,26 @@ import * as ui8 from 'uint8arrays';
|
|
|
5
5
|
import { AtpAgent } from '@atproto/api';
|
|
6
6
|
import { Secp256k1Keypair, randomStr } from '@atproto/crypto';
|
|
7
7
|
import { Client } from '@atproto/lex';
|
|
8
|
-
import { PDS, createSecretKeyObject } from '@atproto/pds';
|
|
8
|
+
import { PDS, createSecretKeyObject, } from '@atproto/pds';
|
|
9
9
|
import { ADMIN_PASSWORD, EXAMPLE_LABELER, JWT_SECRET } from './const.js';
|
|
10
10
|
import getPort from './get-port.js';
|
|
11
|
+
// Re-export types that are part of the public API
|
|
12
|
+
export { AtpAgent, Client, PDS };
|
|
11
13
|
export class TestPds {
|
|
12
14
|
constructor(url, port, server) {
|
|
13
15
|
this.url = url;
|
|
14
16
|
this.port = port;
|
|
15
17
|
this.server = server;
|
|
16
18
|
}
|
|
17
|
-
static async create(
|
|
18
|
-
const plcRotationKey = await Secp256k1Keypair.create({ exportable: true });
|
|
19
|
-
const plcRotationPriv = ui8.toString(await plcRotationKey.export(), 'hex');
|
|
19
|
+
static async create(env, overrides) {
|
|
20
20
|
const recoveryKey = (await Secp256k1Keypair.create()).did();
|
|
21
|
-
const port =
|
|
21
|
+
const port = env.port || (await getPort());
|
|
22
22
|
const url = `http://localhost:${port}`;
|
|
23
|
-
const blobstoreLoc = path.join(os.tmpdir(), randomStr(8, 'base32'));
|
|
24
|
-
const dataDirectory = path.join(os.tmpdir(), randomStr(8, 'base32'));
|
|
25
|
-
await fs.mkdir(dataDirectory, { recursive: true });
|
|
26
23
|
const server = await PDS.fromEnv({
|
|
27
24
|
devMode: true,
|
|
28
25
|
port,
|
|
29
|
-
dataDirectory:
|
|
30
|
-
blobstoreDiskLocation:
|
|
26
|
+
dataDirectory: await mkTmpdir(),
|
|
27
|
+
blobstoreDiskLocation: await mkTmpdir(),
|
|
31
28
|
recoveryDidKey: recoveryKey,
|
|
32
29
|
adminPassword: ADMIN_PASSWORD,
|
|
33
30
|
jwtSecret: JWT_SECRET,
|
|
@@ -39,7 +36,9 @@ export class TestPds {
|
|
|
39
36
|
bskyAppViewCdnUrlPattern: 'http://cdn.appview.com/%s/%s/%s',
|
|
40
37
|
modServiceUrl: 'https://moderator.invalid',
|
|
41
38
|
modServiceDid: 'did:example:invalid',
|
|
42
|
-
plcRotationKeyK256PrivateKeyHex:
|
|
39
|
+
plcRotationKeyK256PrivateKeyHex: overrides?.plcRotationKey
|
|
40
|
+
? undefined // @NOTE the plcRotationKey might not be exportable
|
|
41
|
+
: await createRotationKey(),
|
|
43
42
|
inviteRequired: false,
|
|
44
43
|
disableSsrfProtection: true,
|
|
45
44
|
serviceName: 'Development PDS',
|
|
@@ -54,8 +53,8 @@ export class TestPds {
|
|
|
54
53
|
termsOfServiceUrl: 'https://bsky.social/about/support/tos',
|
|
55
54
|
privacyPolicyUrl: 'https://bsky.social/about/support/privacy-policy',
|
|
56
55
|
supportUrl: 'https://blueskyweb.zendesk.com/hc/en-us',
|
|
57
|
-
...
|
|
58
|
-
});
|
|
56
|
+
...env,
|
|
57
|
+
}, overrides);
|
|
59
58
|
await server.start();
|
|
60
59
|
return new TestPds(url, port, server);
|
|
61
60
|
}
|
|
@@ -94,4 +93,14 @@ export class TestPds {
|
|
|
94
93
|
await this.close();
|
|
95
94
|
}
|
|
96
95
|
}
|
|
96
|
+
async function createRotationKey() {
|
|
97
|
+
const plcRotationKey = await Secp256k1Keypair.create({ exportable: true });
|
|
98
|
+
const plcRotationPriv = await plcRotationKey.export();
|
|
99
|
+
return Buffer.from(plcRotationPriv).toString('hex');
|
|
100
|
+
}
|
|
101
|
+
async function mkTmpdir() {
|
|
102
|
+
const location = path.join(os.tmpdir(), randomStr(8, 'base32'));
|
|
103
|
+
await fs.mkdir(location, { recursive: true });
|
|
104
|
+
return location;
|
|
105
|
+
}
|
|
97
106
|
//# sourceMappingURL=pds.js.map
|
package/dist/pds.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pds.js","sourceRoot":"","sources":["../src/pds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAkB,MAAM,cAAc,CAAA;AACrD,OAAO,
|
|
1
|
+
{"version":3,"file":"pds.js","sourceRoot":"","sources":["../src/pds.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport * as ui8 from 'uint8arrays'\nimport { AtpAgent } from '@atproto/api'\nimport { Secp256k1Keypair, randomStr } from '@atproto/crypto'\nimport { Client, type UriString } from '@atproto/lex'\nimport {\n type AppContext,\n type AppContextOptions,\n type KeyObject,\n PDS,\n createSecretKeyObject,\n} from '@atproto/pds'\nimport { ADMIN_PASSWORD, EXAMPLE_LABELER, JWT_SECRET } from './const.js'\nimport getPort from './get-port.js'\nimport type { PdsConfig } from './types.js'\n\n// Re-export types that are part of the public API\nexport { AtpAgent, Client, PDS }\nexport type { AppContextOptions, KeyObject, PdsConfig, UriString }\n\nexport class TestPds {\n constructor(\n public url: UriString,\n public port: number,\n public server: PDS,\n ) {}\n\n static async create(\n env: PdsConfig,\n overrides?: Partial<AppContextOptions>,\n ): Promise<TestPds> {\n const recoveryKey = (await Secp256k1Keypair.create()).did()\n\n const port = env.port || (await getPort())\n const url: UriString = `http://localhost:${port}`\n\n const server = await PDS.fromEnv(\n {\n devMode: true,\n port,\n dataDirectory: await mkTmpdir(),\n blobstoreDiskLocation: await mkTmpdir(),\n recoveryDidKey: recoveryKey,\n adminPassword: ADMIN_PASSWORD,\n jwtSecret: JWT_SECRET,\n // @NOTE \".example\" will not actually work and is only used to display\n // multiple domains in the sing-up UI\n serviceHandleDomains: ['.test', '.example'],\n bskyAppViewUrl: 'https://appview.invalid',\n bskyAppViewDid: 'did:example:invalid',\n bskyAppViewCdnUrlPattern: 'http://cdn.appview.com/%s/%s/%s',\n modServiceUrl: 'https://moderator.invalid',\n modServiceDid: 'did:example:invalid',\n plcRotationKeyK256PrivateKeyHex: overrides?.plcRotationKey\n ? undefined // @NOTE the plcRotationKey might not be exportable\n : await createRotationKey(),\n inviteRequired: false,\n disableSsrfProtection: true,\n serviceName: 'Development PDS',\n primaryColor: '#f0828d',\n errorColor: 'rgb(238, 0, 78)', // rgb() notation should work too\n logoUrl:\n // Using a \"data:\" instead of a real URL to avoid making CORS requests in dev.\n // License: https://uxwing.com/license/\n // Source: https://uxwing.com/bee-icon/\n `data:image/svg+xml;base64,${Buffer.from('<svg xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"geometricPrecision\" text-rendering=\"geometricPrecision\" image-rendering=\"optimizeQuality\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" viewBox=\"0 0 503 511.623\"><path fill=\"#FFB9B9\" d=\"M379.75 85.311l90.022 89.879C503.264 128.804 502.534 31.13 476.188 0c-27.441 31.966-59.103 60.767-96.438 85.311z\"/><path fill=\"#E2828D\" d=\"M399.445 104.976l70.327 70.214c26.443-36.622 31.549-105.205 19.563-147.778-26.692 28.309-56.413 54.344-89.89 77.564z\"/><path fill=\"#FFB9B9\" d=\"M119.595 85.311L29.573 175.19C-3.919 128.804-3.189 31.13 23.156 0c27.441 31.966 59.103 60.767 96.439 85.311z\"/><path fill=\"#E2828D\" d=\"M99.899 104.976L29.573 175.19C3.13 138.568-1.976 69.985 10.01 27.412c26.692 28.309 56.413 54.344 89.889 77.564z\"/><path fill=\"#FFB9B9\" d=\"M251.5 51.303c138.898 0 251.5 103.046 251.5 230.16 0 127.114-112.602 230.16-251.5 230.16C112.6 511.623 0 408.577 0 281.463c0-127.114 112.6-230.16 251.5-230.16z\"/><path fill=\"#331400\" d=\"M138.142 188.245c16.387 0 29.672 13.283 29.672 29.672 0 16.389-13.285 29.673-29.672 29.673-16.389 0-29.675-13.284-29.675-29.673 0-16.389 13.286-29.672 29.675-29.672zM360.695 188.245c16.389 0 29.674 13.283 29.674 29.672 0 16.389-13.285 29.673-29.674 29.673-16.387 0-29.673-13.284-29.673-29.673 0-16.389 13.286-29.672 29.673-29.672z\"/><path fill=\"#F0828D\" fill-rule=\"nonzero\" d=\"M251.5 255.548c37.407 0 71.438 11.136 96.213 29.138 25.886 18.808 41.905 45.125 41.905 74.487 0 29.36-16.017 55.679-41.908 74.49-24.772 18.001-58.805 29.138-96.21 29.138-37.405 0-71.438-11.137-96.21-29.138-25.891-18.811-41.908-45.13-41.908-74.49 0-29.362 16.019-55.679 41.905-74.487 24.775-18.002 58.808-29.138 96.213-29.138z\"/><circle fill=\"#A5414B\" cx=\"203.259\" cy=\"358.515\" r=\"29.673\"/><circle fill=\"#A5414B\" cx=\"298.744\" cy=\"358.515\" r=\"29.673\"/></svg>', 'utf8').toString('base64')}`,\n homeUrl: 'https://bsky.social/',\n termsOfServiceUrl: 'https://bsky.social/about/support/tos',\n privacyPolicyUrl: 'https://bsky.social/about/support/privacy-policy',\n supportUrl: 'https://blueskyweb.zendesk.com/hc/en-us',\n ...env,\n },\n overrides,\n )\n\n await server.start()\n\n return new TestPds(url, port, server)\n }\n\n get ctx(): AppContext {\n return this.server.ctx\n }\n\n getAgent(): AtpAgent {\n const agent = new AtpAgent({ service: this.url })\n agent.configureLabelers([EXAMPLE_LABELER])\n return agent\n }\n\n getClient(): Client {\n const client = new Client({ service: this.url })\n client.setLabelers([EXAMPLE_LABELER])\n return client\n }\n\n adminAuth(): string {\n return (\n 'Basic ' +\n ui8.toString(\n ui8.fromString(`admin:${ADMIN_PASSWORD}`, 'utf8'),\n 'base64pad',\n )\n )\n }\n\n adminAuthHeaders() {\n return {\n authorization: this.adminAuth(),\n }\n }\n\n jwtSecretKey() {\n return createSecretKeyObject(JWT_SECRET)\n }\n\n async processAll() {\n await this.ctx.backgroundQueue.processAll()\n }\n\n async close() {\n await this.server.destroy()\n }\n\n async [Symbol.asyncDispose]() {\n await this.close()\n }\n}\n\nasync function createRotationKey(): Promise<string> {\n const plcRotationKey = await Secp256k1Keypair.create({ exportable: true })\n const plcRotationPriv = await plcRotationKey.export()\n return Buffer.from(plcRotationPriv).toString('hex')\n}\n\nasync function mkTmpdir(): Promise<string> {\n const location = path.join(os.tmpdir(), randomStr(8, 'base32'))\n await fs.mkdir(location, { recursive: true })\n return location\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/dev-env",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Local development environment helper for atproto development",
|
|
6
6
|
"keywords": [
|
|
@@ -39,19 +39,19 @@
|
|
|
39
39
|
"multiformats": "^13.0.0",
|
|
40
40
|
"uint8arrays": "^5.0.0",
|
|
41
41
|
"undici": "^8.5.0",
|
|
42
|
-
"@atproto/
|
|
43
|
-
"@atproto/
|
|
44
|
-
"@atproto/bsync": "^0.1.
|
|
45
|
-
"@atproto/common-web": "^0.5.
|
|
46
|
-
"@atproto/crypto": "^0.5.
|
|
47
|
-
"@atproto/
|
|
48
|
-
"@atproto/
|
|
49
|
-
"@atproto/lexicon": "^0.7.
|
|
50
|
-
"@atproto/ozone": "^0.
|
|
51
|
-
"@atproto/pds": "^0.5.
|
|
52
|
-
"@atproto/sync": "^0.4.
|
|
42
|
+
"@atproto/bsky": "^0.1.0",
|
|
43
|
+
"@atproto/api": "^0.23.0",
|
|
44
|
+
"@atproto/bsync": "^0.1.2",
|
|
45
|
+
"@atproto/common-web": "^0.5.14",
|
|
46
|
+
"@atproto/crypto": "^0.5.7",
|
|
47
|
+
"@atproto/lex": "^0.3.14",
|
|
48
|
+
"@atproto/identity": "^0.5.16",
|
|
49
|
+
"@atproto/lexicon": "^0.7.16",
|
|
50
|
+
"@atproto/ozone": "^0.5.1",
|
|
51
|
+
"@atproto/pds": "^0.5.37",
|
|
52
|
+
"@atproto/sync": "^0.4.13",
|
|
53
53
|
"@atproto/syntax": "^0.7.6",
|
|
54
|
-
"@atproto/xrpc-server": "^0.13.
|
|
54
|
+
"@atproto/xrpc-server": "^0.13.4"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/express": "^4.17.13"
|
package/src/mock/index.ts
CHANGED
|
@@ -100,6 +100,26 @@ export async function generateMockSetup(env: TestNetwork) {
|
|
|
100
100
|
|
|
101
101
|
const [alice, bob, carla, triage, mod, adminMod, labeler] = userAgents
|
|
102
102
|
|
|
103
|
+
// @NOTE The client uses declared age outside regions requiring age assurance.
|
|
104
|
+
for (const user of [alice, bob]) {
|
|
105
|
+
await user.app.bsky.actor.putPreferences({
|
|
106
|
+
preferences: [
|
|
107
|
+
{
|
|
108
|
+
$type: 'app.bsky.actor.defs#personalDetailsPref',
|
|
109
|
+
birthDate: '1990-01-01T00:00:00.000Z',
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// @NOTE Wait for actor rows to exist before seeding age assurance state.
|
|
116
|
+
await env.processAll()
|
|
117
|
+
await env.bsky.db.db
|
|
118
|
+
.updateTable('actor')
|
|
119
|
+
.set({ ageAssuranceStatus: 'assured', ageAssuranceAccess: 'full' })
|
|
120
|
+
.where('did', 'in', [alice.did, bob.did])
|
|
121
|
+
.execute()
|
|
122
|
+
|
|
103
123
|
// Create chat declarations for all users
|
|
104
124
|
for (const user of userAgents) {
|
|
105
125
|
await user.chat.bsky.actor.declaration.create(
|
package/src/pds.ts
CHANGED
|
@@ -5,11 +5,21 @@ import * as ui8 from 'uint8arrays'
|
|
|
5
5
|
import { AtpAgent } from '@atproto/api'
|
|
6
6
|
import { Secp256k1Keypair, randomStr } from '@atproto/crypto'
|
|
7
7
|
import { Client, type UriString } from '@atproto/lex'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type AppContext,
|
|
10
|
+
type AppContextOptions,
|
|
11
|
+
type KeyObject,
|
|
12
|
+
PDS,
|
|
13
|
+
createSecretKeyObject,
|
|
14
|
+
} from '@atproto/pds'
|
|
9
15
|
import { ADMIN_PASSWORD, EXAMPLE_LABELER, JWT_SECRET } from './const.js'
|
|
10
16
|
import getPort from './get-port.js'
|
|
11
17
|
import type { PdsConfig } from './types.js'
|
|
12
18
|
|
|
19
|
+
// Re-export types that are part of the public API
|
|
20
|
+
export { AtpAgent, Client, PDS }
|
|
21
|
+
export type { AppContextOptions, KeyObject, PdsConfig, UriString }
|
|
22
|
+
|
|
13
23
|
export class TestPds {
|
|
14
24
|
constructor(
|
|
15
25
|
public url: UriString,
|
|
@@ -17,51 +27,53 @@ export class TestPds {
|
|
|
17
27
|
public server: PDS,
|
|
18
28
|
) {}
|
|
19
29
|
|
|
20
|
-
static async create(
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
static async create(
|
|
31
|
+
env: PdsConfig,
|
|
32
|
+
overrides?: Partial<AppContextOptions>,
|
|
33
|
+
): Promise<TestPds> {
|
|
23
34
|
const recoveryKey = (await Secp256k1Keypair.create()).did()
|
|
24
35
|
|
|
25
|
-
const port =
|
|
36
|
+
const port = env.port || (await getPort())
|
|
26
37
|
const url: UriString = `http://localhost:${port}`
|
|
27
38
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
39
|
+
const server = await PDS.fromEnv(
|
|
40
|
+
{
|
|
41
|
+
devMode: true,
|
|
42
|
+
port,
|
|
43
|
+
dataDirectory: await mkTmpdir(),
|
|
44
|
+
blobstoreDiskLocation: await mkTmpdir(),
|
|
45
|
+
recoveryDidKey: recoveryKey,
|
|
46
|
+
adminPassword: ADMIN_PASSWORD,
|
|
47
|
+
jwtSecret: JWT_SECRET,
|
|
48
|
+
// @NOTE ".example" will not actually work and is only used to display
|
|
49
|
+
// multiple domains in the sing-up UI
|
|
50
|
+
serviceHandleDomains: ['.test', '.example'],
|
|
51
|
+
bskyAppViewUrl: 'https://appview.invalid',
|
|
52
|
+
bskyAppViewDid: 'did:example:invalid',
|
|
53
|
+
bskyAppViewCdnUrlPattern: 'http://cdn.appview.com/%s/%s/%s',
|
|
54
|
+
modServiceUrl: 'https://moderator.invalid',
|
|
55
|
+
modServiceDid: 'did:example:invalid',
|
|
56
|
+
plcRotationKeyK256PrivateKeyHex: overrides?.plcRotationKey
|
|
57
|
+
? undefined // @NOTE the plcRotationKey might not be exportable
|
|
58
|
+
: await createRotationKey(),
|
|
59
|
+
inviteRequired: false,
|
|
60
|
+
disableSsrfProtection: true,
|
|
61
|
+
serviceName: 'Development PDS',
|
|
62
|
+
primaryColor: '#f0828d',
|
|
63
|
+
errorColor: 'rgb(238, 0, 78)', // rgb() notation should work too
|
|
64
|
+
logoUrl:
|
|
65
|
+
// Using a "data:" instead of a real URL to avoid making CORS requests in dev.
|
|
66
|
+
// License: https://uxwing.com/license/
|
|
67
|
+
// Source: https://uxwing.com/bee-icon/
|
|
68
|
+
`data:image/svg+xml;base64,${Buffer.from('<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 503 511.623"><path fill="#FFB9B9" d="M379.75 85.311l90.022 89.879C503.264 128.804 502.534 31.13 476.188 0c-27.441 31.966-59.103 60.767-96.438 85.311z"/><path fill="#E2828D" d="M399.445 104.976l70.327 70.214c26.443-36.622 31.549-105.205 19.563-147.778-26.692 28.309-56.413 54.344-89.89 77.564z"/><path fill="#FFB9B9" d="M119.595 85.311L29.573 175.19C-3.919 128.804-3.189 31.13 23.156 0c27.441 31.966 59.103 60.767 96.439 85.311z"/><path fill="#E2828D" d="M99.899 104.976L29.573 175.19C3.13 138.568-1.976 69.985 10.01 27.412c26.692 28.309 56.413 54.344 89.889 77.564z"/><path fill="#FFB9B9" d="M251.5 51.303c138.898 0 251.5 103.046 251.5 230.16 0 127.114-112.602 230.16-251.5 230.16C112.6 511.623 0 408.577 0 281.463c0-127.114 112.6-230.16 251.5-230.16z"/><path fill="#331400" d="M138.142 188.245c16.387 0 29.672 13.283 29.672 29.672 0 16.389-13.285 29.673-29.672 29.673-16.389 0-29.675-13.284-29.675-29.673 0-16.389 13.286-29.672 29.675-29.672zM360.695 188.245c16.389 0 29.674 13.283 29.674 29.672 0 16.389-13.285 29.673-29.674 29.673-16.387 0-29.673-13.284-29.673-29.673 0-16.389 13.286-29.672 29.673-29.672z"/><path fill="#F0828D" fill-rule="nonzero" d="M251.5 255.548c37.407 0 71.438 11.136 96.213 29.138 25.886 18.808 41.905 45.125 41.905 74.487 0 29.36-16.017 55.679-41.908 74.49-24.772 18.001-58.805 29.138-96.21 29.138-37.405 0-71.438-11.137-96.21-29.138-25.891-18.811-41.908-45.13-41.908-74.49 0-29.362 16.019-55.679 41.905-74.487 24.775-18.002 58.808-29.138 96.213-29.138z"/><circle fill="#A5414B" cx="203.259" cy="358.515" r="29.673"/><circle fill="#A5414B" cx="298.744" cy="358.515" r="29.673"/></svg>', 'utf8').toString('base64')}`,
|
|
69
|
+
homeUrl: 'https://bsky.social/',
|
|
70
|
+
termsOfServiceUrl: 'https://bsky.social/about/support/tos',
|
|
71
|
+
privacyPolicyUrl: 'https://bsky.social/about/support/privacy-policy',
|
|
72
|
+
supportUrl: 'https://blueskyweb.zendesk.com/hc/en-us',
|
|
73
|
+
...env,
|
|
74
|
+
},
|
|
75
|
+
overrides,
|
|
76
|
+
)
|
|
65
77
|
|
|
66
78
|
await server.start()
|
|
67
79
|
|
|
@@ -116,3 +128,15 @@ export class TestPds {
|
|
|
116
128
|
await this.close()
|
|
117
129
|
}
|
|
118
130
|
}
|
|
131
|
+
|
|
132
|
+
async function createRotationKey(): Promise<string> {
|
|
133
|
+
const plcRotationKey = await Secp256k1Keypair.create({ exportable: true })
|
|
134
|
+
const plcRotationPriv = await plcRotationKey.export()
|
|
135
|
+
return Buffer.from(plcRotationPriv).toString('hex')
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function mkTmpdir(): Promise<string> {
|
|
139
|
+
const location = path.join(os.tmpdir(), randomStr(8, 'base32'))
|
|
140
|
+
await fs.mkdir(location, { recursive: true })
|
|
141
|
+
return location
|
|
142
|
+
}
|