@devmoods/express-extras 0.66.1 → 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 +8 -0
- package/dist/middleware.d.ts +2 -1
- package/dist/middleware.js +2 -1
- package/dist/vite/ssr.js +11 -20
- package/dist/webapi.d.ts +2 -2
- package/dist/webapi.js +20 -28
- package/package.json +10 -10
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/middleware.d.ts
CHANGED
|
@@ -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 };
|
package/dist/middleware.js
CHANGED
|
@@ -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 {
|
|
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
|
|
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,
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
75
|
-
"@hey-api/openapi-ts": "^0.
|
|
76
|
-
"@sentry/node": "^10.
|
|
77
|
-
"@sentry/node-native": "^10.
|
|
78
|
-
"@sentry/profiling-node": "^10.
|
|
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.
|
|
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": "
|
|
115
|
+
"gitHead": "ddc79e0157d354d9c25cfbb0ba86d8e61d560fbc"
|
|
116
116
|
}
|