peers/peerjs-server

View on GitHub
bin/peerjs.ts

Summary

Maintainability
A
0 mins
Test Coverage
#!/usr/bin/env node

import path from "node:path";
import fs from "node:fs";
const optimistUsageLength = 98;
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import { PeerServer } from "../src/index.ts";
import type { AddressInfo } from "node:net";
import type { CorsOptions } from "cors";

const y = yargs(hideBin(process.argv));

const portEnvIsSet = !!process.env["PORT"];

const opts = y
    .usage("Usage: $0")
    .wrap(Math.min(optimistUsageLength, y.terminalWidth()))
    .options({
        expire_timeout: {
            demandOption: false,
            alias: "t",
            describe: "timeout (milliseconds)",
            default: 5000,
        },
        concurrent_limit: {
            demandOption: false,
            alias: "c",
            describe: "concurrent limit",
            default: 5000,
        },
        alive_timeout: {
            demandOption: false,
            describe: "broken connection check timeout (milliseconds)",
            default: 60000,
        },
        key: {
            demandOption: false,
            alias: "k",
            describe: "connection key",
            default: "peerjs",
        },
        sslkey: {
            type: "string",
            demandOption: false,
            describe: "path to SSL key",
        },
        sslcert: {
            type: "string",
            demandOption: false,
            describe: "path to SSL certificate",
        },
        host: {
            type: "string",
            demandOption: false,
            alias: "H",
            describe: "host",
        },
        port: {
            type: "number",
            demandOption: !portEnvIsSet,
            alias: "p",
            describe: "port",
        },
        path: {
            type: "string",
            demandOption: false,
            describe: "custom path",
            default: process.env["PEERSERVER_PATH"] ?? "/",
        },
        allow_discovery: {
            type: "boolean",
            demandOption: false,
            describe: "allow discovery of peers",
        },
        proxied: {
            type: "boolean",
            demandOption: false,
            describe: "Set true if PeerServer stays behind a reverse proxy",
            default: false,
        },
        cors: {
            type: "string",
            array: true,
            describe: "Set the list of CORS origins",
        },
    })
    .boolean("allow_discovery")
    .parseSync();

if (!opts.port) {
    // .port is only not set if the PORT env var is set
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    opts.port = parseInt(process.env["PORT"]!);
}
if (opts.cors) {
    opts["corsOptions"] = {
        origin: opts.cors,
    } satisfies CorsOptions;
}
process.on("uncaughtException", function (e) {
    console.error("Error: " + e.toString());
});

if (opts.sslkey ?? opts.sslcert) {
    if (opts.sslkey && opts.sslcert) {
        opts["ssl"] = {
            key: fs.readFileSync(path.resolve(opts.sslkey)),
            cert: fs.readFileSync(path.resolve(opts.sslcert)),
        };
    } else {
        console.error(
            "Warning: PeerServer will not run because either " +
                "the key or the certificate has not been provided.",
        );
        process.exit(1);
    }
}

const userPath = opts.path;
const server = PeerServer(opts, (server) => {
    const { address: host, port } = server.address() as AddressInfo;

    console.log(
        "Started PeerServer on %s, port: %s, path: %s",
        host,
        port,
        userPath || "/",
    );

    const shutdownApp = () => {
        server.close(() => {
            console.log("Http server closed.");

            process.exit(0);
        });
    };

    process.on("SIGINT", shutdownApp);
    process.on("SIGTERM", shutdownApp);
});

server.on("connection", (client) => {
    console.log(`Client connected: ${client.getId()}`);
});

server.on("disconnect", (client) => {
    console.log(`Client disconnected: ${client.getId()}`);
});