@powerhousedao/switchboard 6.0.0-dev.6 → 6.0.0-dev.60
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 +524 -0
- package/Dockerfile +4 -4
- package/dist/src/index.js +2 -2
- package/dist/src/profiler.d.ts +6 -1
- package/dist/src/profiler.d.ts.map +1 -1
- package/dist/src/profiler.js +31 -5
- package/dist/src/profiler.js.map +1 -1
- package/dist/src/renown.d.ts +16 -0
- package/dist/src/renown.d.ts.map +1 -0
- package/dist/src/renown.js +33 -0
- package/dist/src/renown.js.map +1 -0
- package/dist/src/server.d.ts +0 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +83 -47
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +16 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/entrypoint.sh +3 -1
- package/package.json +23 -22
- package/tsconfig.json +11 -4
- package/dist/src/connect-crypto.d.ts +0 -41
- package/dist/src/connect-crypto.d.ts.map +0 -1
- package/dist/src/connect-crypto.js +0 -127
- package/dist/src/connect-crypto.js.map +0 -1
package/entrypoint.sh
CHANGED
|
@@ -5,10 +5,12 @@ set -e
|
|
|
5
5
|
echo "[entrypoint] Regenerating Prisma client for current platform..."
|
|
6
6
|
prisma generate --schema node_modules/document-drive/dist/prisma/schema.prisma
|
|
7
7
|
|
|
8
|
-
# Run
|
|
8
|
+
# Run migrations if DATABASE_URL is postgres and migrations not skipped
|
|
9
9
|
if [ -n "$DATABASE_URL" ] && echo "$DATABASE_URL" | grep -q "^postgres" && [ "$SKIP_DB_MIGRATIONS" != "true" ]; then
|
|
10
10
|
echo "[entrypoint] Running Prisma db push..."
|
|
11
11
|
prisma db push --schema node_modules/document-drive/dist/prisma/schema.prisma --skip-generate
|
|
12
|
+
echo "[entrypoint] Running migrations..."
|
|
13
|
+
ph switchboard --migrate
|
|
12
14
|
fi
|
|
13
15
|
|
|
14
16
|
echo "[entrypoint] Starting switchboard on port ${PORT:-3000}..."
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/switchboard",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.0.0-dev.
|
|
4
|
+
"version": "6.0.0-dev.60",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -11,8 +11,15 @@
|
|
|
11
11
|
"./server": {
|
|
12
12
|
"import": "./dist/src/server.js",
|
|
13
13
|
"types": "./dist/src/server.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./utils": {
|
|
16
|
+
"import": "./dist/src/utils.js",
|
|
17
|
+
"types": "./dist/src/utils.d.ts"
|
|
14
18
|
}
|
|
15
19
|
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=24.0.0"
|
|
22
|
+
},
|
|
16
23
|
"bin": {
|
|
17
24
|
"switchboard": "dist/src/index.js"
|
|
18
25
|
},
|
|
@@ -24,42 +31,36 @@
|
|
|
24
31
|
"license": "ISC",
|
|
25
32
|
"description": "",
|
|
26
33
|
"dependencies": {
|
|
27
|
-
"@electric-sql/pglite": "0.
|
|
34
|
+
"@electric-sql/pglite": "0.3.15",
|
|
28
35
|
"@openfeature/core": "^1.9.1",
|
|
29
36
|
"@openfeature/env-var-provider": "^0.3.1",
|
|
30
37
|
"@openfeature/server-sdk": "^1.19.0",
|
|
31
|
-
"@powerhousedao/analytics-engine-core": "^0.5.0",
|
|
32
|
-
"@powerhousedao/analytics-engine-knex": "^0.6.0",
|
|
33
38
|
"@pyroscope/nodejs": "^0.4.5",
|
|
34
39
|
"@sentry/node": "^9.6.1",
|
|
35
|
-
"body-parser": "^1.20.3",
|
|
36
|
-
"cors": "^2.8.5",
|
|
37
40
|
"dotenv": "^16.4.7",
|
|
38
|
-
"exponential-backoff": "^3.1.1",
|
|
39
41
|
"express": "^4.21.2",
|
|
40
|
-
"
|
|
41
|
-
"kysely": "
|
|
42
|
-
"
|
|
43
|
-
"pg": "^8.13.0",
|
|
42
|
+
"kysely": "0.28.11",
|
|
43
|
+
"kysely-pglite-dialect": "1.2.0",
|
|
44
|
+
"pg": "8.18.0",
|
|
44
45
|
"redis": "^4.7.0",
|
|
45
|
-
"@powerhousedao/config": "6.0.0-dev.
|
|
46
|
-
"@powerhousedao/reactor
|
|
47
|
-
"@powerhousedao/reactor": "6.0.0-dev.
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"document-model": "6.0.0-dev.
|
|
46
|
+
"@powerhousedao/config": "6.0.0-dev.60",
|
|
47
|
+
"@powerhousedao/reactor": "6.0.0-dev.60",
|
|
48
|
+
"@powerhousedao/reactor-api": "6.0.0-dev.60",
|
|
49
|
+
"document-drive": "6.0.0-dev.60",
|
|
50
|
+
"@renown/sdk": "6.0.0-dev.60",
|
|
51
|
+
"document-model": "6.0.0-dev.60"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@types/express": "^4.17.25",
|
|
54
|
-
"@types/node": "
|
|
55
|
-
"@types/pg": "
|
|
56
|
-
"concurrently": "
|
|
57
|
-
"nodemon": "
|
|
55
|
+
"@types/node": "25.2.3",
|
|
56
|
+
"@types/pg": "8.16.0",
|
|
57
|
+
"concurrently": "9.2.1",
|
|
58
|
+
"nodemon": "3.1.11"
|
|
58
59
|
},
|
|
59
60
|
"scripts": {
|
|
60
61
|
"tsc": "tsc",
|
|
61
62
|
"lint": "eslint",
|
|
62
|
-
"build": "pnpm run install-packages",
|
|
63
|
+
"build:misc": "pnpm run install-packages",
|
|
63
64
|
"start": "node dist/src/index.js",
|
|
64
65
|
"start:profile": "mkdir -p .prof && node --cpu-prof --cpu-prof-dir=.prof dist/src/index.js",
|
|
65
66
|
"start:profile:bun": "mkdir -p .prof && bun --cpu-prof --cpu-prof-dir=.prof dist/src/index.js",
|
package/tsconfig.json
CHANGED
|
@@ -2,18 +2,25 @@
|
|
|
2
2
|
"extends": "../../tsconfig.options.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"outDir": "./dist",
|
|
5
|
-
"lib": [
|
|
5
|
+
"lib": [
|
|
6
|
+
"ESNext"
|
|
7
|
+
]
|
|
6
8
|
},
|
|
7
|
-
"include": [
|
|
9
|
+
"include": [
|
|
10
|
+
"**/*"
|
|
11
|
+
],
|
|
8
12
|
"references": [
|
|
9
13
|
{
|
|
10
|
-
"path": "../../packages/
|
|
14
|
+
"path": "../../packages/config"
|
|
11
15
|
},
|
|
12
16
|
{
|
|
13
17
|
"path": "../../packages/document-drive"
|
|
14
18
|
},
|
|
15
19
|
{
|
|
16
|
-
"path": "../../packages/
|
|
20
|
+
"path": "../../packages/document-model"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"path": "../../packages/reactor"
|
|
17
24
|
},
|
|
18
25
|
{
|
|
19
26
|
"path": "../../packages/reactor-api"
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { type IConnectCrypto, type JsonWebKeyPairStorage, type JwkKeyPair } from "@renown/sdk";
|
|
2
|
-
/**
|
|
3
|
-
* Key storage that supports:
|
|
4
|
-
* 1. PH_RENOWN_PRIVATE_KEY environment variable (JSON-encoded JwkKeyPair)
|
|
5
|
-
* 2. Custom file path passed via options
|
|
6
|
-
* 3. Falls back to file storage at .keypair.json in current working directory
|
|
7
|
-
*/
|
|
8
|
-
export declare class SwitchboardKeyStorage implements JsonWebKeyPairStorage {
|
|
9
|
-
#private;
|
|
10
|
-
constructor(filePath?: string);
|
|
11
|
-
loadKeyPair(): Promise<JwkKeyPair | undefined>;
|
|
12
|
-
saveKeyPair(keyPair: JwkKeyPair): Promise<void>;
|
|
13
|
-
}
|
|
14
|
-
export interface ConnectCryptoOptions {
|
|
15
|
-
/** Path to the keypair file. Defaults to .keypair.json in cwd */
|
|
16
|
-
keypairPath?: string;
|
|
17
|
-
/** If true, won't generate a new keypair if none exists */
|
|
18
|
-
requireExisting?: boolean;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Initialize ConnectCrypto for the switchboard.
|
|
22
|
-
* This allows the switchboard to authenticate with remote services
|
|
23
|
-
* using the same identity established during `ph login`.
|
|
24
|
-
*/
|
|
25
|
-
export declare function initConnectCrypto(options?: ConnectCryptoOptions): Promise<IConnectCrypto | null>;
|
|
26
|
-
/**
|
|
27
|
-
* Get the current ConnectCrypto instance.
|
|
28
|
-
* Returns null if not initialized.
|
|
29
|
-
*/
|
|
30
|
-
export declare function getConnectCrypto(): IConnectCrypto | null;
|
|
31
|
-
/**
|
|
32
|
-
* Get the DID of the current ConnectCrypto instance.
|
|
33
|
-
* Returns null if not initialized.
|
|
34
|
-
*/
|
|
35
|
-
export declare function getConnectDid(): Promise<string | null>;
|
|
36
|
-
/**
|
|
37
|
-
* Get a bearer token for authenticating with remote services.
|
|
38
|
-
* Returns null if ConnectCrypto is not initialized.
|
|
39
|
-
*/
|
|
40
|
-
export declare function getBearerToken(driveUrl: string, address?: string, refresh?: boolean): Promise<string | null>;
|
|
41
|
-
//# sourceMappingURL=connect-crypto.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connect-crypto.d.ts","sourceRoot":"","sources":["../../src/connect-crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAUrB;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,qBAAqB;;gBAGrD,QAAQ,CAAC,EAAE,MAAM;IAUvB,WAAW,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAuB9C,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAgCtD;AAKD,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0BhC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,GAAG,IAAI,CAExD;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAK5D;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,UAAQ,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKxB"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { ConnectCrypto, } from "@renown/sdk";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { childLogger } from "document-drive";
|
|
5
|
-
const logger = childLogger(["switchboard", "connect-crypto"]);
|
|
6
|
-
const ENV_KEY_NAME = "PH_RENOWN_PRIVATE_KEY";
|
|
7
|
-
const DEFAULT_KEYPAIR_PATH = join(process.cwd(), ".keypair.json");
|
|
8
|
-
/**
|
|
9
|
-
* Key storage that supports:
|
|
10
|
-
* 1. PH_RENOWN_PRIVATE_KEY environment variable (JSON-encoded JwkKeyPair)
|
|
11
|
-
* 2. Custom file path passed via options
|
|
12
|
-
* 3. Falls back to file storage at .keypair.json in current working directory
|
|
13
|
-
*/
|
|
14
|
-
export class SwitchboardKeyStorage {
|
|
15
|
-
#filePath;
|
|
16
|
-
constructor(filePath) {
|
|
17
|
-
this.#filePath = filePath || DEFAULT_KEYPAIR_PATH;
|
|
18
|
-
// Ensure directory exists
|
|
19
|
-
const dir = dirname(this.#filePath);
|
|
20
|
-
if (!existsSync(dir)) {
|
|
21
|
-
mkdirSync(dir, { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
async loadKeyPair() {
|
|
25
|
-
// First check environment variable
|
|
26
|
-
const envKey = process.env[ENV_KEY_NAME];
|
|
27
|
-
if (envKey) {
|
|
28
|
-
try {
|
|
29
|
-
const keyPair = JSON.parse(envKey);
|
|
30
|
-
// Validate it has the required structure
|
|
31
|
-
if (keyPair.publicKey && keyPair.privateKey) {
|
|
32
|
-
logger.debug("Loaded keypair from environment variable");
|
|
33
|
-
return keyPair;
|
|
34
|
-
}
|
|
35
|
-
logger.warn(`${ENV_KEY_NAME} is set but doesn't contain valid publicKey and privateKey`);
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
logger.warn(`Failed to parse ${ENV_KEY_NAME} as JSON:`, e);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// Fall back to file storage
|
|
42
|
-
return this.#loadFromFile();
|
|
43
|
-
}
|
|
44
|
-
async saveKeyPair(keyPair) {
|
|
45
|
-
// Don't save if using env var
|
|
46
|
-
if (process.env[ENV_KEY_NAME]) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
// Save to file
|
|
50
|
-
this.#saveToFile(keyPair);
|
|
51
|
-
}
|
|
52
|
-
#loadFromFile() {
|
|
53
|
-
try {
|
|
54
|
-
if (!existsSync(this.#filePath)) {
|
|
55
|
-
return undefined;
|
|
56
|
-
}
|
|
57
|
-
const data = readFileSync(this.#filePath, "utf-8");
|
|
58
|
-
const parsed = JSON.parse(data);
|
|
59
|
-
const keyPair = parsed.keyPair;
|
|
60
|
-
if (keyPair) {
|
|
61
|
-
logger.debug(`Loaded keypair from ${this.#filePath}`);
|
|
62
|
-
}
|
|
63
|
-
return keyPair;
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
#saveToFile(keyPair) {
|
|
70
|
-
const data = { keyPair };
|
|
71
|
-
writeFileSync(this.#filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
72
|
-
logger.debug(`Saved keypair to ${this.#filePath}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// Singleton instance of ConnectCrypto for the switchboard
|
|
76
|
-
let connectCryptoInstance = null;
|
|
77
|
-
/**
|
|
78
|
-
* Initialize ConnectCrypto for the switchboard.
|
|
79
|
-
* This allows the switchboard to authenticate with remote services
|
|
80
|
-
* using the same identity established during `ph login`.
|
|
81
|
-
*/
|
|
82
|
-
export async function initConnectCrypto(options = {}) {
|
|
83
|
-
const { keypairPath, requireExisting = false } = options;
|
|
84
|
-
const keyStorage = new SwitchboardKeyStorage(keypairPath);
|
|
85
|
-
// Check if we have an existing keypair
|
|
86
|
-
const existingKeyPair = await keyStorage.loadKeyPair();
|
|
87
|
-
if (!existingKeyPair && requireExisting) {
|
|
88
|
-
logger.warn("No existing keypair found and requireExisting is true. " +
|
|
89
|
-
'Run "ph login" to create one.');
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
if (!existingKeyPair) {
|
|
93
|
-
logger.info("No existing keypair found. A new one will be generated.");
|
|
94
|
-
}
|
|
95
|
-
connectCryptoInstance = new ConnectCrypto(keyStorage);
|
|
96
|
-
const did = await connectCryptoInstance.did();
|
|
97
|
-
logger.info(`Switchboard identity initialized: ${did}`);
|
|
98
|
-
return connectCryptoInstance;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Get the current ConnectCrypto instance.
|
|
102
|
-
* Returns null if not initialized.
|
|
103
|
-
*/
|
|
104
|
-
export function getConnectCrypto() {
|
|
105
|
-
return connectCryptoInstance;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Get the DID of the current ConnectCrypto instance.
|
|
109
|
-
* Returns null if not initialized.
|
|
110
|
-
*/
|
|
111
|
-
export async function getConnectDid() {
|
|
112
|
-
if (!connectCryptoInstance) {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
return connectCryptoInstance.did();
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Get a bearer token for authenticating with remote services.
|
|
119
|
-
* Returns null if ConnectCrypto is not initialized.
|
|
120
|
-
*/
|
|
121
|
-
export async function getBearerToken(driveUrl, address, refresh = false) {
|
|
122
|
-
if (!connectCryptoInstance) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
return connectCryptoInstance.getBearerToken(driveUrl, address, refresh);
|
|
126
|
-
}
|
|
127
|
-
//# sourceMappingURL=connect-crypto.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connect-crypto.js","sourceRoot":"","sources":["../../src/connect-crypto.ts"],"names":[],"mappings":"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"}
|