diff --git a/index.d.ts b/index.d.ts index 83eb8f9b1..b566dc355 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,8 +1,36 @@ -import { UserDirectoryList, User } from "./src/users"; -import { CommandLineArguments } from "./src/command-line"; -import { CsrfSyncedToken } from "csrf-sync"; +import { EventEmitter } from 'node:events'; +import { CsrfSyncedToken } from 'csrf-sync'; +import { UserDirectoryList, User } from './src/users.js'; +import { CommandLineArguments } from './src/command-line.js'; +import { EVENT_NAMES } from './src/server-events.js'; + +/** + * Event payload for SERVER_STARTED event. + */ +export interface ServerStartedEvent { + /** + * The URL the server is listening on. + */ + url: URL; +} + +/** + * Map of all server events to their payload types. + */ +export interface ServerEventMap { + [EVENT_NAMES.SERVER_STARTED]: [ServerStartedEvent]; +} declare global { + declare namespace NodeJS { + export interface Process { + /** + * A global instance of the server events emitter. + */ + serverEvents: EventEmitter; + } + } + declare namespace CookieSessionInterfaces { export interface CookieSessionObject { /** diff --git a/server.js b/server.js index 6e4155068..ab06c2cce 100644 --- a/server.js +++ b/server.js @@ -20,6 +20,7 @@ import bodyParser from 'body-parser'; import open from 'open'; // local library imports +import { serverEvents, EVENT_NAMES } from './src/server-events.js'; import { CommandLineParser } from './src/command-line.js'; import { loadPlugins } from './src/plugin-loader.js'; import { @@ -348,6 +349,7 @@ async function postSetupTasks(result) { console.log('\n' + getSeparator(plainGoToLog.length) + '\n'); setupLogLevel(); + serverEvents.emit(EVENT_NAMES.SERVER_STARTED, { url: autorunUrl }); } /** diff --git a/src/server-events.js b/src/server-events.js new file mode 100644 index 000000000..fa26a45bd --- /dev/null +++ b/src/server-events.js @@ -0,0 +1,21 @@ +import EventEmitter from 'node:events'; +import process from 'node:process'; + +/** + * @typedef {import('../index').ServerEventMap} ServerEventMap + * @type {EventEmitter} The default event source. + */ +export const serverEvents = new EventEmitter(); +process.serverEvents = serverEvents; +export default serverEvents; + +/** + * @enum {string} + * @readonly + */ +export const EVENT_NAMES = Object.freeze({ + /** + * Emitted when the server has started. + */ + SERVER_STARTED: 'server-started', +});