@atproto/dev-env 0.6.8 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/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/pds.ts +66 -42
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atproto/dev-env
|
|
2
2
|
|
|
3
|
+
## 0.6.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#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
|
|
8
|
+
|
|
9
|
+
- [#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.
|
|
10
|
+
- 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)]:
|
|
11
|
+
- @atproto/api@0.22.0
|
|
12
|
+
- @atproto/bsky@0.0.282
|
|
13
|
+
- @atproto/pds@0.5.36
|
|
14
|
+
- @atproto/bsync@0.1.1
|
|
15
|
+
- @atproto/common-web@0.5.13
|
|
16
|
+
- @atproto/crypto@0.5.6
|
|
17
|
+
- @atproto/identity@0.5.15
|
|
18
|
+
- @atproto/lexicon@0.7.15
|
|
19
|
+
- @atproto/ozone@0.5.0
|
|
20
|
+
- @atproto/sync@0.4.12
|
|
21
|
+
- @atproto/xrpc-server@0.13.3
|
|
22
|
+
- @atproto/lex@0.3.13
|
|
23
|
+
|
|
3
24
|
## 0.6.8
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
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.9",
|
|
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/api": "^0.
|
|
43
|
-
"@atproto/bsky": "^0.0.
|
|
44
|
-
"@atproto/bsync": "^0.1.
|
|
45
|
-
"@atproto/common-web": "^0.5.
|
|
46
|
-
"@atproto/crypto": "^0.5.
|
|
47
|
-
"@atproto/identity": "^0.5.
|
|
48
|
-
"@atproto/lex": "^0.3.
|
|
49
|
-
"@atproto/lexicon": "^0.7.
|
|
50
|
-
"@atproto/ozone": "^0.
|
|
51
|
-
"@atproto/pds": "^0.5.
|
|
52
|
-
"@atproto/sync": "^0.4.
|
|
42
|
+
"@atproto/api": "^0.22.0",
|
|
43
|
+
"@atproto/bsky": "^0.0.282",
|
|
44
|
+
"@atproto/bsync": "^0.1.1",
|
|
45
|
+
"@atproto/common-web": "^0.5.13",
|
|
46
|
+
"@atproto/crypto": "^0.5.6",
|
|
47
|
+
"@atproto/identity": "^0.5.15",
|
|
48
|
+
"@atproto/lex": "^0.3.13",
|
|
49
|
+
"@atproto/lexicon": "^0.7.15",
|
|
50
|
+
"@atproto/ozone": "^0.5.0",
|
|
51
|
+
"@atproto/pds": "^0.5.36",
|
|
52
|
+
"@atproto/sync": "^0.4.12",
|
|
53
53
|
"@atproto/syntax": "^0.7.6",
|
|
54
|
-
"@atproto/xrpc-server": "^0.13.
|
|
54
|
+
"@atproto/xrpc-server": "^0.13.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/express": "^4.17.13"
|
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
|
+
}
|