@zintrust/core 0.1.31 → 0.1.33
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/package.json +1 -1
- package/src/boot/Application.js +1 -1
- package/src/boot/Server.d.ts.map +1 -1
- package/src/boot/Server.js +3 -2
- package/src/boot/bootstrap.js +2 -2
- package/src/cli/commands/WorkerCommands.js +1 -1
- package/src/config/redis.js +2 -2
- package/src/index.js +3 -3
- package/src/routes/error.d.ts.map +1 -1
- package/src/routes/error.js +10 -0
- package/src/routes/errorPages.d.ts +1 -0
- package/src/routes/errorPages.d.ts.map +1 -1
- package/src/routes/errorPages.js +55 -38
package/package.json
CHANGED
package/src/boot/Application.js
CHANGED
|
@@ -126,7 +126,7 @@ const registerFrameworkShutdownHooks = (shutdownManager) => {
|
|
|
126
126
|
.catch(() => {
|
|
127
127
|
/* ignore import failures in restrictive runtimes */
|
|
128
128
|
});
|
|
129
|
-
import('
|
|
129
|
+
import('@zintrust/workers')
|
|
130
130
|
.then((mod) => {
|
|
131
131
|
shutdownManager.add(async () => mod.WorkerShutdown.shutdown({ signal: 'APP_SHUTDOWN', timeout: 5000, forceExit: false }));
|
|
132
132
|
})
|
package/src/boot/Server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.d.ts","sourceRoot":"","sources":["../../../src/boot/Server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAM5C,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAG9C,MAAM,WAAW,OAAO;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,aAAa,IAAI,IAAI,CAAC,MAAM,CAAC;CAC9B;
|
|
1
|
+
{"version":3,"file":"Server.d.ts","sourceRoot":"","sources":["../../../src/boot/Server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAM5C,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAG9C,MAAM,WAAW,OAAO;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,aAAa,IAAI,IAAI,CAAC,MAAM,CAAC;CAC9B;AA4DD;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;gBACS,YAAY,SAAS,MAAM,SAAS,MAAM,WAAU,OAAO,GAAG,IAAI,GAAU,OAAO;EA4D/F,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
package/src/boot/Server.js
CHANGED
|
@@ -19,9 +19,10 @@ const getContentSecurityPolicyForPath = () => {
|
|
|
19
19
|
// Default CSP for the API/framework
|
|
20
20
|
return ("default-src 'self'; " +
|
|
21
21
|
"script-src 'self' 'unsafe-inline'; " +
|
|
22
|
-
"style-src 'self' 'unsafe-inline'; " +
|
|
22
|
+
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
|
|
23
|
+
"style-src-elem 'self' 'unsafe-inline' https://fonts.googleapis.com; " +
|
|
23
24
|
"img-src 'self' data:; " +
|
|
24
|
-
"font-src 'self';");
|
|
25
|
+
"font-src 'self' https://fonts.gstatic.com;");
|
|
25
26
|
};
|
|
26
27
|
const setSecurityHeaders = (res) => {
|
|
27
28
|
res.setHeader(HTTP_HEADERS.X_POWERED_BY, 'ZinTrust');
|
package/src/boot/bootstrap.js
CHANGED
|
@@ -103,7 +103,7 @@ const gracefulShutdown = async (signal) => {
|
|
|
103
103
|
// Shutdown worker management system FIRST (before database closes)
|
|
104
104
|
if (appConfig.detectRuntime() === 'nodejs' || appConfig.detectRuntime() === 'lambda') {
|
|
105
105
|
try {
|
|
106
|
-
const { WorkerShutdown } = await import('
|
|
106
|
+
const { WorkerShutdown } = await import('@zintrust/workers');
|
|
107
107
|
const workerBudgetMs = Math.min(15000, remainingMs());
|
|
108
108
|
await withTimeout(WorkerShutdown.shutdown({ signal, timeout: workerBudgetMs, forceExit: false }), workerBudgetMs, 'Worker shutdown timed out');
|
|
109
109
|
}
|
|
@@ -136,7 +136,7 @@ async function useWorkerStarter() {
|
|
|
136
136
|
// Initialize worker management system
|
|
137
137
|
let workerInit = null;
|
|
138
138
|
try {
|
|
139
|
-
const { WorkerInit } = await import('
|
|
139
|
+
const { WorkerInit } = await import('@zintrust/workers');
|
|
140
140
|
workerInit = WorkerInit;
|
|
141
141
|
await WorkerInit.initialize({
|
|
142
142
|
enableResourceMonitoring: true,
|
|
@@ -13,7 +13,7 @@ let HealthMonitor;
|
|
|
13
13
|
let ResourceMonitor;
|
|
14
14
|
let workersModulePromise;
|
|
15
15
|
const loadWorkersModule = async () => {
|
|
16
|
-
workersModulePromise ??= import('
|
|
16
|
+
workersModulePromise ??= import('@zintrust/workers');
|
|
17
17
|
try {
|
|
18
18
|
return await workersModulePromise;
|
|
19
19
|
}
|
package/src/config/redis.js
CHANGED
|
@@ -29,7 +29,7 @@ export const getRedisUrl = (config) => {
|
|
|
29
29
|
export const ensureDriver = async (type) => {
|
|
30
30
|
if (type === 'publish') {
|
|
31
31
|
// Return Redis publish client with publish() method from package
|
|
32
|
-
const mod = (await import('
|
|
32
|
+
const mod = (await import('@zintrust/queue-redis'));
|
|
33
33
|
if (mod.createRedisPublishClient) {
|
|
34
34
|
return mod.createRedisPublishClient();
|
|
35
35
|
}
|
|
@@ -41,7 +41,7 @@ export const ensureDriver = async (type) => {
|
|
|
41
41
|
}
|
|
42
42
|
catch {
|
|
43
43
|
try {
|
|
44
|
-
const mod = (await import('
|
|
44
|
+
const mod = (await import('@zintrust/queue-redis'));
|
|
45
45
|
if (mod.RedisQueue !== undefined) {
|
|
46
46
|
Queue.register('redis', mod.RedisQueue);
|
|
47
47
|
}
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @zintrust/core v0.1.
|
|
2
|
+
* @zintrust/core v0.1.33
|
|
3
3
|
*
|
|
4
4
|
* ZinTrust Framework - Production-Grade TypeScript Backend
|
|
5
5
|
* Built for performance, type safety, and exceptional developer experience
|
|
6
6
|
*
|
|
7
7
|
* Build Information:
|
|
8
|
-
* Built: 2026-01-29T09:
|
|
8
|
+
* Built: 2026-01-29T09:58:51.202Z
|
|
9
9
|
* Node: >=20.0.0
|
|
10
10
|
* License: MIT
|
|
11
11
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* Available at runtime for debugging and health checks
|
|
22
22
|
*/
|
|
23
23
|
export const ZINTRUST_VERSION = '0.1.23';
|
|
24
|
-
export const ZINTRUST_BUILD_DATE = '2026-01-29T09:
|
|
24
|
+
export const ZINTRUST_BUILD_DATE = '2026-01-29T09:58:51.164Z'; // Replaced during build
|
|
25
25
|
import { Application } from './boot/Application.js';
|
|
26
26
|
import { AwsSigV4 } from './common/index.js';
|
|
27
27
|
import { SignedRequest } from './security/SignedRequest.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/routes/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/routes/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAoKnD;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,OAAO,KAAG,IAGrD,CAAC;AAEF,eAAO,MAAM,YAAY;;kCALmB,OAAO,KAAG,IAAI;8BA7GzB,QAAQ,YAAY,SAAS,cAAc,MAAM,KAAG,IAAI;qDA4B9E,QAAQ,YACP,SAAS,SACZ,OAAO,cACF,MAAM,KACjB,IAAI;wCA0DoC,IAAI,CAAC,cAAc,KAAG,IAAI;EA8BnE,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
package/src/routes/error.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { appConfig } from '../config/app.js';
|
|
6
6
|
import { HTTP_HEADERS, MIME_TYPES } from '../config/constants.js';
|
|
7
|
+
import { serveErrorPagesFile, serveZintrustSvgFile } from './errorPages.js';
|
|
7
8
|
import { getPublicRoot } from './publicRoot.js';
|
|
8
9
|
import { Router } from './Router.js';
|
|
9
10
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
@@ -50,6 +51,15 @@ const trySendHtmlErrorPage = (request, response, input) => {
|
|
|
50
51
|
return true;
|
|
51
52
|
};
|
|
52
53
|
const handleNotFound = (request, response, requestId) => {
|
|
54
|
+
const path = request.getPath();
|
|
55
|
+
if (path.startsWith('/error-pages/')) {
|
|
56
|
+
serveErrorPagesFile(path, response);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (path === '/zintrust.svg') {
|
|
60
|
+
serveZintrustSvgFile(response);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
53
63
|
response.setStatus(404);
|
|
54
64
|
if (trySendHtmlErrorPage(request, response, {
|
|
55
65
|
statusCode: 404,
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { IRouter } from './Router';
|
|
6
6
|
import type { IResponse } from '../http/Response';
|
|
7
7
|
export declare const serveErrorPagesFile: (urlPath: string, response: IResponse) => boolean;
|
|
8
|
+
export declare const serveZintrustSvgFile: (response: IResponse) => boolean;
|
|
8
9
|
export declare const registerErrorPagesRoutes: (router: IRouter) => void;
|
|
9
10
|
declare const _default: {
|
|
10
11
|
registerErrorPagesRoutes: (router: IRouter) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorPages.d.ts","sourceRoot":"","sources":["../../../src/routes/errorPages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"errorPages.d.ts","sourceRoot":"","sources":["../../../src/routes/errorPages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAoDhD,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,UAAU,SAAS,KAAG,OAkD1E,CAAC;AAeF,eAAO,MAAM,oBAAoB,GAAI,UAAU,SAAS,KAAG,OAE1D,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,QAAQ,OAAO,KAAG,IAO1D,CAAC;;uCAP+C,OAAO,KAAG,IAAI;mCArElB,MAAM,YAAY,SAAS,KAAG,OAAO;;AA8ElF,wBAAiE"}
|
package/src/routes/errorPages.js
CHANGED
|
@@ -4,33 +4,51 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { HTTP_HEADERS, MIME_TYPES } from '../config/constants.js';
|
|
6
6
|
import { MIME_TYPES_MAP, resolveSafePath, tryDecodeURIComponent } from './common.js';
|
|
7
|
-
import {
|
|
7
|
+
import { getFrameworkPublicRoots } from './publicRoot.js';
|
|
8
8
|
import { Router } from './Router.js';
|
|
9
9
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
10
10
|
import * as fs from '../node-singletons/fs.js';
|
|
11
11
|
import * as path from '../node-singletons/path.js';
|
|
12
|
+
const getCandidatePublicRoots = () => {
|
|
13
|
+
const roots = [path.join(process.cwd(), 'public'), ...getFrameworkPublicRoots()];
|
|
14
|
+
const unique = new Set(roots.map((root) => root.trim()).filter((root) => root !== ''));
|
|
15
|
+
return [...unique];
|
|
16
|
+
};
|
|
17
|
+
const findFirstExistingFile = (candidates) => {
|
|
18
|
+
for (const candidate of candidates) {
|
|
19
|
+
try {
|
|
20
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile())
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// ignore and continue
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
};
|
|
12
29
|
const servePublicRootFile = (relativePath, response, contentType) => {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
30
|
+
const candidateRoots = getCandidatePublicRoots();
|
|
31
|
+
const candidates = candidateRoots.map((root) => path.join(root, relativePath));
|
|
32
|
+
const filePath = findFirstExistingFile(candidates);
|
|
15
33
|
try {
|
|
16
|
-
if (!
|
|
34
|
+
if (!filePath) {
|
|
17
35
|
response.setStatus(404);
|
|
18
36
|
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
|
|
19
37
|
response.send('Not Found');
|
|
20
|
-
return;
|
|
38
|
+
return false;
|
|
21
39
|
}
|
|
22
40
|
const content = fs.readFileSync(filePath);
|
|
23
41
|
response.setStatus(200);
|
|
24
42
|
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, contentType);
|
|
25
43
|
response.send(content);
|
|
26
|
-
return;
|
|
44
|
+
return true;
|
|
27
45
|
}
|
|
28
46
|
catch (error) {
|
|
29
47
|
ErrorFactory.createTryCatchError(`Error serving public file ${filePath}`, error);
|
|
30
48
|
response.setStatus(500);
|
|
31
49
|
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
|
|
32
50
|
response.send('Internal Server Error');
|
|
33
|
-
return;
|
|
51
|
+
return false;
|
|
34
52
|
}
|
|
35
53
|
};
|
|
36
54
|
export const serveErrorPagesFile = (urlPath, response) => {
|
|
@@ -42,45 +60,41 @@ export const serveErrorPagesFile = (urlPath, response) => {
|
|
|
42
60
|
}
|
|
43
61
|
if (!urlPath.startsWith('/error-pages/'))
|
|
44
62
|
return false;
|
|
45
|
-
const
|
|
46
|
-
const baseDir = path.join(publicRoot, 'error-pages');
|
|
63
|
+
const candidateRoots = getCandidatePublicRoots();
|
|
47
64
|
const rawRelative = urlPath.slice('/error-pages/'.length);
|
|
48
65
|
const normalizedRelative = tryDecodeURIComponent(rawRelative).replaceAll('\\', '/');
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
for (const root of candidateRoots) {
|
|
67
|
+
const baseDir = path.join(root, 'error-pages');
|
|
68
|
+
const filePath = resolveSafePath(baseDir, normalizedRelative);
|
|
69
|
+
if (filePath === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
try {
|
|
72
|
+
if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!fs.existsSync(filePath)) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
79
|
+
const contentType = MIME_TYPES_MAP[ext] || 'application/octet-stream';
|
|
80
|
+
const content = fs.readFileSync(filePath);
|
|
81
|
+
response.setStatus(200);
|
|
82
|
+
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, contentType);
|
|
83
|
+
response.send(content);
|
|
61
84
|
return true;
|
|
62
85
|
}
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
catch (error) {
|
|
87
|
+
ErrorFactory.createTryCatchError(`Error serving error-pages file ${filePath}`, error);
|
|
88
|
+
response.setStatus(500);
|
|
65
89
|
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
|
|
66
|
-
response.send('
|
|
90
|
+
response.send('Internal Server Error');
|
|
67
91
|
return true;
|
|
68
92
|
}
|
|
69
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
70
|
-
const contentType = MIME_TYPES_MAP[ext] || 'application/octet-stream';
|
|
71
|
-
const content = fs.readFileSync(filePath);
|
|
72
|
-
response.setStatus(200);
|
|
73
|
-
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, contentType);
|
|
74
|
-
response.send(content);
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
ErrorFactory.createTryCatchError(`Error serving error-pages file ${filePath}`, error);
|
|
79
|
-
response.setStatus(500);
|
|
80
|
-
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
|
|
81
|
-
response.send('Internal Server Error');
|
|
82
|
-
return true;
|
|
83
93
|
}
|
|
94
|
+
response.setStatus(404);
|
|
95
|
+
response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
|
|
96
|
+
response.send('Not Found');
|
|
97
|
+
return true;
|
|
84
98
|
};
|
|
85
99
|
const handleErrorPagesRequest = (req, res) => {
|
|
86
100
|
const urlPath = req.getPath();
|
|
@@ -93,6 +107,9 @@ const handleErrorPagesRequest = (req, res) => {
|
|
|
93
107
|
const handleZintrustSvgRequest = (_req, res) => {
|
|
94
108
|
servePublicRootFile('zintrust.svg', res, MIME_TYPES.SVG);
|
|
95
109
|
};
|
|
110
|
+
export const serveZintrustSvgFile = (response) => {
|
|
111
|
+
return servePublicRootFile('zintrust.svg', response, MIME_TYPES.SVG);
|
|
112
|
+
};
|
|
96
113
|
export const registerErrorPagesRoutes = (router) => {
|
|
97
114
|
Router.get(router, '/error-pages', handleErrorPagesRequest);
|
|
98
115
|
Router.get(router, '/error-pages/', handleErrorPagesRequest);
|