@molecule/api-server-default-express 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -3,15 +3,11 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-06T05:03:58.023Z
6
+ Generated: 2026-10-16T23:31:50.537Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-server-default-express
10
10
 
11
- > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
- > It is written to be read by coding agents as much as by people, and is generated from this
13
- > package's source — edit `src/index.ts` JSDoc, not this file.
14
-
15
11
  `@molecule/api-server-default-express` — drop-in Express server
16
12
  factory used by the molecule fleet's `api/src/server.ts`.
17
13
 
@@ -20,6 +16,10 @@ returns a `(port?) => Promise<server>` function that runs
20
16
  migrations, wires bonds, mounts router + middleware, and starts
21
17
  an HTTP (or self-signed HTTPS for local dev) listener.
22
18
 
19
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
20
+ > It is written to be read by coding agents as much as by people, and is generated from this
21
+ > package's source — edit `src/index.ts` JSDoc, not this file.
22
+
23
23
  ## Quick Start
24
24
 
25
25
  ```ts
@@ -58,6 +58,21 @@ npm install -D @types/express
58
58
 
59
59
  ### Interfaces
60
60
 
61
+ #### `TaggedError`
62
+
63
+ A deliberately-tagged molecule error mapped to a real HTTP status by the API.
64
+
65
+ ```typescript
66
+ interface TaggedError {
67
+ /** HTTP status to return (e.g. 503 for a missing provider config). */
68
+ statusCode: number
69
+ /** Machine-readable key the app/IDE maps to a friendly message. */
70
+ errorKey: string
71
+ /** Human-readable message. */
72
+ message: string
73
+ }
74
+ ```
75
+
61
76
  #### `CreateServerOptions`
62
77
 
63
78
  Options for `createServerFactory`.
@@ -96,21 +111,6 @@ interface CreateServerOptions {
96
111
  }
97
112
  ```
98
113
 
99
- #### `TaggedError`
100
-
101
- A deliberately-tagged molecule error mapped to a real HTTP status by the API.
102
-
103
- ```typescript
104
- interface TaggedError {
105
- /** HTTP status to return (e.g. 503 for a missing provider config). */
106
- statusCode: number
107
- /** Machine-readable key the app/IDE maps to a friendly message. */
108
- errorKey: string
109
- /** Human-readable message. */
110
- message: string
111
- }
112
- ```
113
-
114
114
  ### Functions
115
115
 
116
116
  #### `classifyTaggedError(error)`
@@ -135,30 +135,6 @@ function classifyTaggedError(error: unknown): TaggedError | null
135
135
 
136
136
  **Returns:** The classified tagged error, or `null` if it isn't a molecule-tagged error.
137
137
 
138
- #### `createServerFactory(opts)`
139
-
140
- Returns an Express server-creation function bound to the given
141
- setupBonds / runMigrations / router loaders. The returned `create`
142
- builds the canonical molecule fleet server:
143
-
144
- - Migrations run first, then bonds, then router import.
145
- - Global browser-security headers ({@link securityHeadersMiddleware})
146
- applied before any router (anti-clickjacking + nosniff + referrer baseline).
147
- - `bodyParser` / `cookieParser` / `cors` middleware applied.
148
- - Router mounted at `/api`.
149
- - `/health` endpoint with `{ status: 'ok', timestamp }`.
150
- - Bare-string `Unauthorized` / `Unauthorized.` errors normalized to 401.
151
- - HTTPS in dev if `process.env.HTTPS` is set, using self-signed
152
- certs from optional dependency `pem`.
153
- - `process.on('uncaughtException')` + `unhandledRejection` registered
154
- on first call (idempotent across multiple `create()` invocations).
155
-
156
- ```typescript
157
- function createServerFactory(
158
- opts: CreateServerOptions,
159
- ): (port?: number) => Promise<express.Express | https.Server>
160
- ```
161
-
162
138
  #### `errorMiddleware(error, req, res, _next)`
163
139
 
164
140
  Terminal Express error middleware for the canonical molecule fleet server.
@@ -185,8 +161,8 @@ depend on `NODE_ENV`. Calling `next(error)` here would fall through to Express's
185
161
  `finalhandler`, which embeds `err.stack` in the HTTP response body whenever
186
162
  `app.get('env') !== 'production'` (the default when `NODE_ENV` is unset or
187
163
  `development`), disclosing absolute server paths, module layout, dependency
188
- versions, and query/data fragments. Returning the opaque 500 unconditionally
189
- removes that leak for every flagship app regardless of how it is deployed.
164
+
165
+ _(description truncated — read the full text in `node_modules/@molecule/api-server-default-express/dist/server.d.ts`.)_
190
166
 
191
167
  ```typescript
192
168
  function errorMiddleware(
@@ -248,6 +224,30 @@ function securityHeadersMiddleware(
248
224
  - `res` — The response to set headers on.
249
225
  - `next` — Express next.
250
226
 
227
+ #### `createServerFactory(opts)`
228
+
229
+ Returns an Express server-creation function bound to the given
230
+ setupBonds / runMigrations / router loaders. The returned `create`
231
+ builds the canonical molecule fleet server:
232
+
233
+ - Migrations run first, then bonds, then router import.
234
+ - Global browser-security headers ({@link securityHeadersMiddleware})
235
+ applied before any router (anti-clickjacking + nosniff + referrer baseline).
236
+ - `bodyParser` / `cookieParser` / `cors` middleware applied.
237
+ - Router mounted at `/api`.
238
+ - `/health` endpoint with `{ status: 'ok', timestamp }`.
239
+ - Bare-string `Unauthorized` / `Unauthorized.` errors normalized to 401.
240
+ - HTTPS in dev if `process.env.HTTPS` is set, using self-signed
241
+ certs from optional dependency `pem`.
242
+ - `process.on('uncaughtException')` + `unhandledRejection` registered
243
+ on first call (idempotent across multiple `create()` invocations).
244
+
245
+ ```typescript
246
+ function createServerFactory(
247
+ opts: CreateServerOptions,
248
+ ): (port?: number) => Promise<express.Express | https.Server>
249
+ ```
250
+
251
251
  ## Injection Notes
252
252
 
253
253
  ### Requirements
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,MAAM,YAAY,CAAA;AAI9B,OAAO,OAAO,MAAM,SAAS,CAAA;AAS7B,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAetE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,mBA6CrC,CAAA;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,6EAA6E;IAC7E,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;;OAGG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC9D;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC3C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC9D;AAYD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACjE,IAAI,CAEN;AAYD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,yBAAyB,EAAE,OAAO,CAAC,cAU/C,CAAA;AA6BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,mBAAmB,GACxB,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAuG5D"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,MAAM,YAAY,CAAA;AAI9B,OAAO,OAAO,MAAM,SAAS,CAAA;AAS7B,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAetE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,CAAC,mBA6CrC,CAAA;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,6EAA6E;IAC7E,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;;OAGG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC9D;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC3C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC9D;AAYD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACjE,IAAI,CAEN;AAYD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,yBAAyB,EAAE,OAAO,CAAC,cAU/C,CAAA;AA6BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,mBAAmB,GACxB,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAqH5D"}
package/dist/server.js CHANGED
@@ -288,6 +288,19 @@ export function createServerFactory(opts) {
288
288
  const httpServer = process.env.HTTPS
289
289
  ? server
290
290
  : http.createServer(app);
291
+ // Outlive every connection pool that sits in front of this server. Node's
292
+ // default keepAliveTimeout is 5000 ms — exactly what Node's global http
293
+ // agent (what a proxy's `http.request` uses with no agent given) keeps an
294
+ // idle socket for. With both sides on the same 5 s timer, an idle
295
+ // connection is closed by the server at the very moment a proxy reuses it,
296
+ // and that one request is lost (measured against the platform front: a
297
+ // dropped reuse answers it a fast ECONNRESET, which costs a retry). A
298
+ // server-side timeout well above the client's makes the CLIENT always let
299
+ // go first, so a reuse can never land on a socket the server is closing.
300
+ // `headersTimeout` must stay greater than `keepAliveTimeout` (Node throws
301
+ // on boot otherwise).
302
+ httpServer.keepAliveTimeout = 65_000;
303
+ httpServer.headersTimeout = 66_000;
291
304
  await runServerCreatedHooks(httpServer);
292
305
  httpServer.listen(port, () => {
293
306
  logger.info(`Started ${process.env.NODE_ENV} ${process.env.HTTPS ? 'HTTPS' : 'HTTP'} server on port ${port}.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-server-default-express",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Default Express server factory: bonds setup, DB migrations, body/cookie/cors middleware, /api router mount, /health endpoint, 401 normalization, optional HTTPS via self-signed pem certs. Extracts 80-line server.ts shipped by 79 fleet apps.",
5
5
  "homepage": "https://www.molecule.dev/packages/api-server-default-express",
6
6
  "type": "module",