@peerbit/server 5.3.2-79582c9 → 5.3.2-951a98f

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.
@@ -23,7 +23,7 @@
23
23
  Learn how to configure a non-root public URL by running `npm run build`.
24
24
  -->
25
25
  <title>Peerbit</title>
26
- <script type="module" crossorigin src="/assets/index-D7nQ7uHD.js"></script>
26
+ <script type="module" crossorigin src="/assets/index-D-KTj4Kv.js"></script>
27
27
  <link rel="stylesheet" crossorigin href="/assets/index-CIfVvUo9.css">
28
28
  </head>
29
29
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/server",
3
- "version": "5.3.2-79582c9",
3
+ "version": "5.3.2-951a98f",
4
4
  "author": "dao.xyz",
5
5
  "repository": {
6
6
  "type": "git",
@@ -66,8 +66,8 @@
66
66
  "lint": "aegir lint"
67
67
  },
68
68
  "devDependencies": {
69
- "@peerbit/test-lib": "0.0.1-79582c9",
70
- "@peerbit/test-utils": "2.1.44-79582c9",
69
+ "@peerbit/test-lib": "0.0.1-951a98f",
70
+ "@peerbit/test-utils": "2.1.44-951a98f",
71
71
  "@types/yargs": "17.0.24",
72
72
  "aws-sdk": "^2.1259.0",
73
73
  "dotenv": "^16.1.4",
@@ -78,7 +78,7 @@
78
78
  "dependencies": {
79
79
  "axios": "^1.4.0",
80
80
  "chalk": "^5.3.0",
81
- "peerbit": "4.1.34-79582c9",
81
+ "peerbit": "4.1.34-951a98f",
82
82
  "yargs": "^17.7.2",
83
83
  "tar-stream": "^3.1.7",
84
84
  "tmp": "^0.2.1",
package/src/cli.ts CHANGED
@@ -1129,6 +1129,25 @@ export const cli = async (args?: string[]) => {
1129
1129
  }
1130
1130
  },
1131
1131
  })
1132
+ .command({
1133
+ command: "versions",
1134
+ describe:
1135
+ "Print <pkg>@<version> for every dependency installed on the target node",
1136
+
1137
+ handler: async (args) => {
1138
+ for (const api of apis) {
1139
+ const packageWithVersion: Record<string, string> =
1140
+ await api.api.dependency.versions();
1141
+
1142
+ for (const [packageName, version] of Object.entries(
1143
+ packageWithVersion,
1144
+ )) {
1145
+ api.log(`${packageName}@${version}`);
1146
+ }
1147
+ }
1148
+ },
1149
+ })
1150
+
1132
1151
  .command({
1133
1152
  command: "restart",
1134
1153
  describe: "Restart the server",
package/src/client.ts CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  BOOTSTRAP_PATH,
16
16
  INSTALL_PATH,
17
17
  LOCAL_API_PORT,
18
- LOG_PATH, // <-- Added the log route constant
18
+ LOG_PATH,
19
19
  PEER_ID_PATH,
20
20
  PROGRAMS_PATH,
21
21
  PROGRAM_PATH,
@@ -24,6 +24,7 @@ import {
24
24
  RESTART_PATH,
25
25
  STOP_PATH,
26
26
  TRUST_PATH,
27
+ VERSIONS_PATH,
27
28
  } from "./routes.js";
28
29
  import { signRequest } from "./signed-request.js";
29
30
  import type { InstallDependency, StartProgram } from "./types.js";
@@ -257,6 +258,14 @@ export const createClient = async (
257
258
  }
258
259
  return resp.data;
259
260
  },
261
+ versions: async (): Promise<Record<string, string>> => {
262
+ const resp = throwIfNot200(
263
+ await axiosInstance.get(endpoint + VERSIONS_PATH, {
264
+ validateStatus,
265
+ }),
266
+ );
267
+ return resp.data as Record<string, string>;
268
+ },
260
269
  },
261
270
  network: {
262
271
  bootstrap: async (): Promise<void> => {
package/src/routes.ts CHANGED
@@ -23,3 +23,4 @@ export const RESTART_PATH = "/restart";
23
23
  export const TERMINATE_PATH = "/terminate";
24
24
  export const STOP_PATH = "/path";
25
25
  export const LOG_PATH = "/log";
26
+ export const VERSIONS_PATH = "/versions";
package/src/server.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  } from "@peerbit/program";
11
11
  import { waitFor } from "@peerbit/time";
12
12
  import { execSync, spawn } from "child_process";
13
+ import { spawnSync } from "child_process";
13
14
  import { setMaxListeners } from "events";
14
15
  import fs from "fs";
15
16
  import http from "http";
@@ -37,6 +38,7 @@ import {
37
38
  RESTART_PATH,
38
39
  STOP_PATH,
39
40
  TRUST_PATH,
41
+ VERSIONS_PATH,
40
42
  } from "./routes.js";
41
43
  import { Session } from "./session.js";
42
44
  import { getBody, verifyRequest } from "./signed-request.js";
@@ -53,6 +55,32 @@ const MAX_LISTENER_LIMIT = 1e5;
53
55
  // eslint-disable-next-line @typescript-eslint/naming-convention
54
56
  const __dirname = dirname(fileURLToPath(import.meta.url));
55
57
 
58
+ const getInstallDir = (): string | null => {
59
+ return (
60
+ process.env.PEERBIT_MODULES_PATH ||
61
+ findPeerbitProgramFolder(__dirname) || // same util used by /install
62
+ null
63
+ );
64
+ };
65
+ // add next to execSync
66
+
67
+ const listVersions = (dir: string): Record<string, string> => {
68
+ const proc = spawnSync("npm", ["ls", "--depth", "0", "--json", "--silent"], {
69
+ cwd: dir,
70
+ encoding: "utf8",
71
+ });
72
+
73
+ // npm may exit 1, but proc.stdout usually contains valid JSON
74
+ if (!proc.stdout) throw new Error(proc.stderr || "npm ls failed");
75
+
76
+ const tree = JSON.parse(proc.stdout);
77
+ const versions: Record<string, string> = {};
78
+ for (const [name, info] of Object.entries(tree.dependencies || {})) {
79
+ versions[name] = (info as any)?.version || "UNKNOWN";
80
+ }
81
+ return versions;
82
+ };
83
+
56
84
  export const stopAndWait = (server: http.Server) => {
57
85
  let closed = false;
58
86
  server.on("close", () => {
@@ -496,9 +524,8 @@ export const startApiServer = async (
496
524
  } else {
497
525
  try {
498
526
  // TODO do this without sudo. i.e. for servers provide arguments so that this app folder is writeable by default by the user
499
- const installDir =
500
- process.env.PEERBIT_MODULES_PATH ||
501
- findPeerbitProgramFolder(__dirname);
527
+ const installDir = getInstallDir();
528
+
502
529
  let permission = "";
503
530
  if (!installDir) {
504
531
  res.writeHead(400);
@@ -565,6 +592,31 @@ export const startApiServer = async (
565
592
  break;
566
593
  }
567
594
  }
595
+ } else if (req.url.startsWith(VERSIONS_PATH)) {
596
+ if (req.method === "GET") {
597
+ try {
598
+ const installDir = getInstallDir();
599
+ if (!installDir) {
600
+ res.writeHead(400);
601
+ res.end("Cannot determine install directory");
602
+ return;
603
+ }
604
+
605
+ const versions = listVersions(installDir);
606
+
607
+ res.setHeader("Content-Type", "application/json");
608
+ res.writeHead(200);
609
+ res.end(JSON.stringify(versions, null, 2));
610
+ } catch (err) {
611
+ console.error("Failed to list versions:", err);
612
+ res.writeHead(500);
613
+ res.end("Error fetching versions");
614
+ }
615
+ } else {
616
+ r404();
617
+ }
618
+
619
+ /* keep the remaining else-if blocks (PEER_ID_PATH, etc.) unchanged */
568
620
  } else if (req.url.startsWith(BOOTSTRAP_PATH)) {
569
621
  switch (req.method) {
570
622
  case "POST":