// ── module-uo's server entry point ───────────────────────────────────────── // // Core requires this file once, synchronously, while `app.js` is still being // required, and calls the exported function with `(ctx, api)`. The normative // contract is docs/website/MODULE_API.md §2.2; the three rules that shape every // line below are worth restating where they will be read: // // 1. **No `await`, and no database.** `scripts/routeManifest.js` and // `swagger/swagger.js` both require core's `app.js` with the pool pointed // at a dead port, so a module that queried at registration time would hang // both. Anything needing a live database belongs in `onBoot`. // 2. **Never resolve what core owns.** This module lives at // `/modules/uo/`, outside `server/`, so Node's resolver never // reaches core's `node_modules` and `require('express')` fails outright. // express and express-validator arrive on `ctx`; so do the database, the // logger, the middleware and the rest of §2.3. // 3. **Never reach into core's tree.** No relative path may escape this // module's root. `scripts/checkImports.js` enforces that in CI (§5.1) // rather than leaving it to review. // // Slice 0 of the Phase 3 extraction (MODULE_SYSTEM.md §2.7.1) deliberately // registers NOTHING. The bundle exists, core discovers it, validates it, mounts // its zero routes, serves its client chunk and reports it `started` — which is // the whole delivery path proved end to end before a single UO file moves into // it. Slice 1 brings the atlas; every slice after that adds registrations here // and deletes the matching files from core. /** * @param {object} ctx what core hands the module (MODULE_API.md §2.3), frozen * @param {object} api what the module registers (§2.4) */ module.exports = function register(ctx, api) { const log = ctx.log() // Registrations land here, slice by slice: // // api.registerRoutes({ public: {...}, admin: {...}, player: {...} }) // api.registerExtension('admin.users.detail', usersShardRouter) // api.registerNotificationStreams(streams) // api.registerAnnounceLeg({ leg: 'towncrier', ... }) // api.onBoot(async (ctx) => { ... }) // api.onShutdown(async () => { ... }) // // `api` is referenced by this log line and nothing else yet, on purpose: an // entry point that took `api` and never named it would read like an oversight // rather than a stage of the extraction. log.info('registered', { version: require('../module.json').version, registers: Object.keys(api).length, }) }