@devmoods/express-extras 0.66.0 → 0.67.0

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/dist/faktory.js CHANGED
@@ -65,6 +65,14 @@ export async function createFaktoryWorker({ queues, jobs, faktory: createFactory
65
65
  return job.execute(...args, jobContext);
66
66
  });
67
67
  }
68
+ /* c8 ignore start */
69
+ const onSignal = async (signal) => {
70
+ logger.info('faktory worker received signal', { signal });
71
+ };
72
+ for (const signal of ['SIGTERM', 'SIGINT']) {
73
+ process.once(signal, onSignal);
74
+ }
75
+ /* c8 ignore end */
68
76
  return {
69
77
  async start(workerOptions = {}) {
70
78
  try {
package/dist/listen.js CHANGED
@@ -105,8 +105,9 @@ export const impress = (options = {}) => {
105
105
  export function createExpressServer(app, options = {}) {
106
106
  const server = http.createServer(app);
107
107
  const ctl = stoppable(server, options.gracePeriodMs ?? config.GRACE_PERIOD_MS);
108
- if (options.trustProxy ?? true) {
109
- app.set('trust proxy', options.trustProxy);
108
+ const trustProxy = options.trustProxy ?? true;
109
+ if (trustProxy) {
110
+ app.set('trust proxy', trustProxy);
110
111
  }
111
112
  let stopping = false;
112
113
  async function onSignal(signal) {
@@ -1,5 +1,5 @@
1
1
  import { type ServerResponse, type IncomingMessage } from 'node:http';
2
- import { type NextFunction, type RequestHandler, type Request, type Response, json as jsonParser, urlencoded as urlencodedParser } from 'express';
2
+ import { type NextFunction, type RequestHandler, type Request, type Response, json as jsonParser, urlencoded as urlencodedParser, static as staticMiddleware } from 'express';
3
3
  import { type createAuth } from './auth.js';
4
4
  import { compose } from './composeMiddleware.js';
5
5
  import { type CsrfMiddlewareOptions } from './csrf.js';
@@ -82,3 +82,4 @@ export declare function asyncMiddleware<RequestBody, RequestQuery extends Record
82
82
  export declare function withTransaction(wrapper: {
83
83
  transaction: (fn: () => Promise<void>) => Promise<void>;
84
84
  }): RequestHandler;
85
+ export { staticMiddleware };
@@ -3,7 +3,7 @@ import {} from 'node:http';
3
3
  import { config } from '@devmoods/config';
4
4
  import { startTimer } from '@devmoods/observability';
5
5
  import cookieParser from 'cookie-parser';
6
- import { json as jsonParser, urlencoded as urlencodedParser, } from 'express';
6
+ import { json as jsonParser, urlencoded as urlencodedParser, static as staticMiddleware, } from 'express';
7
7
  import helmet from 'helmet';
8
8
  import {} from './auth.js';
9
9
  import { compose } from './composeMiddleware.js';
@@ -236,3 +236,4 @@ export function withTransaction(wrapper) {
236
236
  }
237
237
  };
238
238
  }
239
+ export { staticMiddleware };
package/dist/vite/ssr.js CHANGED
@@ -2,7 +2,7 @@ import * as fs from 'node:fs/promises';
2
2
  import * as path from 'node:path';
3
3
  import { config } from '@devmoods/config';
4
4
  import express, {} from 'express';
5
- import { createServer as createViteServer } from 'vite';
5
+ import {} from 'vite';
6
6
  import {} from '../composeMiddleware.js';
7
7
  import {} from './types.js';
8
8
  import { generateCsrfToken } from '../csrf.js';
@@ -16,30 +16,28 @@ import { createFetchRequest } from '../webapi.js';
16
16
  export async function createSsrMiddleware({ root = process.cwd(), getInitialData, useDevServer = config.VITE_USE_DEV_SERVER, } = {}) {
17
17
  const resolve = (p) => path.resolve(root, p);
18
18
  let vite;
19
+ let render;
20
+ let assetLinks = { preload: '', css: '', js: '' };
19
21
  const middlewares = [];
20
22
  if (useDevServer) {
21
- vite = await createViteServer({
23
+ vite = await import('vite').then((mod) => mod.createServer({
22
24
  root,
23
25
  server: { middlewareMode: true },
24
26
  appType: 'custom',
25
- });
27
+ }));
28
+ render = (await vite.ssrLoadModule('/src/entry-server.tsx')).render;
26
29
  middlewares.push(vite.middlewares);
27
30
  }
28
31
  else {
32
+ const result = await import(path.join(root, 'dist/server/entry-server.js'));
33
+ render = result.render;
34
+ assetLinks = await getAssetLinks(resolve('dist/client/.vite/manifest.json'), 'src/entry-client.tsx');
29
35
  middlewares.push(express.static(resolve('dist/client'), { index: false }));
30
36
  }
31
37
  middlewares.push(route(async (req, res) => {
32
38
  try {
33
- let render;
34
- if (useDevServer) {
35
- render = (await vite.ssrLoadModule('/src/entry-server.tsx')).render;
36
- }
37
- else {
38
- const result = await import(path.join(root, 'dist/server/entry-server.js'));
39
- render = result.render;
40
- }
41
39
  const nonce = useCspNonce();
42
- const rendered = await render(createFetchRequest(req), {
40
+ const rendered = await render(createFetchRequest(req, res), {
43
41
  useDevServer,
44
42
  getInitialData: getInitialData || (async () => ({})),
45
43
  placeholders: `
@@ -61,13 +59,6 @@ export async function createSsrMiddleware({ root = process.cwd(), getInitialData
61
59
  publicUrl: new URL(config.PUBLIC_URL),
62
60
  csrfToken: generateCsrfToken(req, res),
63
61
  });
64
- const readManifest = async () => {
65
- if (useDevServer) {
66
- return { preload: '', css: '', js: '' };
67
- }
68
- const manifestPath = path.resolve(root, 'dist/client/.vite/manifest.json');
69
- return getAssetLinks(manifestPath, 'src/entry-client.tsx');
70
- };
71
62
  let html = rendered.html;
72
63
  const context = Object.assign({
73
64
  fouc: `
@@ -76,7 +67,7 @@ export async function createSsrMiddleware({ root = process.cwd(), getInitialData
76
67
  setTimeout(() => { document.getElementById('fouc').remove(); }, 2000);
77
68
  </script>
78
69
  `,
79
- }, rendered.context, await readManifest());
70
+ }, rendered.context, assetLinks);
80
71
  const ssrPlaceholders = Object.fromEntries(Object.entries(context).map(([k, v]) => [`ssr-${k}`, v.toString()]));
81
72
  // Add nonce to all bare script tags
82
73
  html = html.replace(/<script>/g, `<script nonce="${nonce}">`);
package/dist/webapi.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { type Request as ExpressRequest } from 'express';
1
+ import { type Request as ExpressRequest, type Response as ExpressResponse } from 'express';
2
2
  export declare function createFetchHeaders(requestHeaders: ExpressRequest['headers']): Headers;
3
- export declare function createFetchRequest(req: ExpressRequest): Request;
3
+ export declare function createFetchRequest(req: ExpressRequest, res: ExpressResponse): Request;
package/dist/webapi.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import {} from 'express';
2
- import { BadRequest } from './errors.js';
3
2
  export function createFetchHeaders(requestHeaders) {
4
3
  const headers = new Headers();
5
4
  for (const [key, values] of Object.entries(requestHeaders)) {
@@ -17,32 +16,25 @@ export function createFetchHeaders(requestHeaders) {
17
16
  }
18
17
  return headers;
19
18
  }
20
- export function createFetchRequest(req) {
21
- try {
22
- const origin = `${req.protocol}://${req.get('host')}`;
23
- // Note: This had to take originalUrl into account for presumably vite's proxying
24
- /* c8 ignore next 1 */
25
- const url = new URL(req.originalUrl || req.url, origin);
26
- const controller = new AbortController();
27
- /* c8 ignore next 3 */
28
- req.on('close', () => {
29
- controller.abort();
30
- });
31
- const init = {
32
- method: req.method,
33
- headers: createFetchHeaders(req.headers),
34
- signal: controller.signal,
35
- };
36
- if (req.method !== 'GET' && req.method !== 'HEAD') {
37
- init.body = req.body;
38
- }
39
- return new Request(url.href, init);
40
- /* c8 ignore next 7 */
41
- }
42
- catch (error) {
43
- if (error instanceof TypeError) {
44
- throw BadRequest('Invalid request');
45
- }
46
- throw error;
19
+ export function createFetchRequest(req, res) {
20
+ const origin = `${req.protocol}://${req.get('host')}`;
21
+ /* c8 ignore next 1 */
22
+ const url = new URL(req.originalUrl || req.url, origin);
23
+ let controller = new AbortController();
24
+ const init = {
25
+ method: req.method,
26
+ headers: createFetchHeaders(req.headers),
27
+ signal: controller.signal,
28
+ };
29
+ /* c8 ignore next 6 */
30
+ res.on('finish', () => {
31
+ controller = null;
32
+ });
33
+ res.on('close', () => {
34
+ controller?.abort();
35
+ });
36
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
37
+ init.body = req.body;
47
38
  }
39
+ return new Request(url.href, init);
48
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devmoods/express-extras",
3
- "version": "0.66.0",
3
+ "version": "0.67.0",
4
4
  "description": "Kubernetes-ready utilities for rapid Node.js application development",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -61,21 +61,21 @@
61
61
  "license": "ISC",
62
62
  "devDependencies": {
63
63
  "@vitejs/plugin-react": "^5.0.4",
64
- "arktype": "^2.1.22",
64
+ "arktype": "^2.1.23",
65
65
  "faktory-worker": "^4.7.1",
66
66
  "react": "^19.2.0",
67
67
  "react-dom": "^19.2.0",
68
- "vite": "^7.1.9"
68
+ "vite": "^7.1.10"
69
69
  },
70
70
  "dependencies": {
71
71
  "@devmoods/config": "0.2.0",
72
72
  "@devmoods/fetch": "^4.2.0",
73
73
  "@devmoods/observability": "0.1.1",
74
- "@devmoods/postgres": "0.2.0",
75
- "@hey-api/openapi-ts": "^0.85.1",
76
- "@sentry/node": "^10.19.0",
77
- "@sentry/node-native": "^10.19.0",
78
- "@sentry/profiling-node": "^10.19.0",
74
+ "@devmoods/postgres": "0.2.1",
75
+ "@hey-api/openapi-ts": "^0.86.0",
76
+ "@sentry/node": "^10.20.0",
77
+ "@sentry/node-native": "^10.20.0",
78
+ "@sentry/profiling-node": "^10.20.0",
79
79
  "@standard-schema/spec": "^1.0.0",
80
80
  "@types/bcrypt": "^6.0.0",
81
81
  "@types/cookie-parser": "^1.4.9",
@@ -92,7 +92,7 @@
92
92
  "cookie-parser": "^1.4.7",
93
93
  "dotenv": "^17.2.3",
94
94
  "express": "^4.21.2",
95
- "google-auth-library": "^10.4.0",
95
+ "google-auth-library": "^10.4.1",
96
96
  "helmet": "^8.1.0",
97
97
  "jsonwebtoken": "^9.0.2",
98
98
  "nodemailer": "^7.0.9",
@@ -112,5 +112,5 @@
112
112
  "engines": {
113
113
  "node": ">=20 <25"
114
114
  },
115
- "gitHead": "b5f134aecebb1937c1aba9403d0e35c9504aeaa3"
115
+ "gitHead": "ddc79e0157d354d9c25cfbb0ba86d8e61d560fbc"
116
116
  }