@futdevpro/nts-dynamo 1.15.153 → 1.15.155
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 +25 -6
- package/__documentations/2026-08-22-content-free-process-error-boundary.md +91 -0
- package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
- package/build/_models/control-models/app-params.control-model.js +1 -2
- package/build/_models/control-models/app-params.control-model.js.map +1 -1
- package/build/_modules/server/index.d.ts +4 -0
- package/build/_modules/server/index.d.ts.map +1 -1
- package/build/_modules/server/index.js +5 -0
- package/build/_modules/server/index.js.map +1 -1
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.d.ts +9 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.d.ts.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.js +13 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.js.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts +20 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js +24 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.d.ts +19 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.d.ts.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.js +83 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.js.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.d.ts +19 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.d.ts.map +1 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.js +3 -0
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.js.map +1 -0
- package/build/_services/core/global.service.d.ts +3 -3
- package/build/_services/core/global.service.d.ts.map +1 -1
- package/build/_services/core/global.service.js +24 -18
- package/build/_services/core/global.service.js.map +1 -1
- package/build/_services/server/app.server.d.ts +2 -0
- package/build/_services/server/app.server.d.ts.map +1 -1
- package/build/_services/server/app.server.js +71 -199
- package/build/_services/server/app.server.js.map +1 -1
- package/build/_services/shared.static-service.d.ts +11 -4
- package/build/_services/shared.static-service.d.ts.map +1 -1
- package/build/_services/shared.static-service.js +26 -6
- package/build/_services/shared.static-service.js.map +1 -1
- package/package.json +15 -9
- package/src/_models/control-models/app-params.control-model.spec.ts +9 -5
- package/src/_models/control-models/app-params.control-model.ts +4 -3
- package/src/_modules/server/index.ts +6 -0
- package/src/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.ts +8 -0
- package/src/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.ts +19 -0
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.spec.ts +124 -0
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.ts +99 -0
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.interface.ts +20 -0
- package/src/_modules/server/server-status/db-readiness-probe.control-service.spec.ts +2 -2
- package/src/_services/core/global.service.ts +34 -33
- package/src/_services/server/app-safe-diagnostic.spec.ts +124 -0
- package/src/_services/server/app.server.ts +209 -262
- package/src/_services/shared.static-service.spec.ts +57 -23
- package/src/_services/shared.static-service.ts +48 -19
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
|
|
3
|
+
import { DyFM_GeoIpLocation } from '@futdevpro/fsm-dynamo/location';
|
|
4
|
+
|
|
5
|
+
import { DyNTS_Shared } from './shared.static-service';
|
|
4
6
|
|
|
5
7
|
describe('| DyNTS_Shared', () => {
|
|
6
8
|
describe('| getIpFromRequest', () => {
|
|
7
|
-
it('| should extract IP from x-forwarded-for header', () => {
|
|
8
|
-
const
|
|
9
|
+
it('| should extract IP from x-forwarded-for header', () => {
|
|
10
|
+
const consoleLogSpy: jasmine.Spy = spyOn(console, 'log');
|
|
11
|
+
const mockRequest = {
|
|
9
12
|
headers: {
|
|
10
13
|
'x-forwarded-for': '192.168.1.1, 10.0.0.1, 172.16.0.1',
|
|
11
14
|
},
|
|
@@ -15,8 +18,9 @@ describe('| DyNTS_Shared', () => {
|
|
|
15
18
|
} as any as Request;
|
|
16
19
|
|
|
17
20
|
const ip = DyNTS_Shared.getIpFromRequest(mockRequest);
|
|
18
|
-
|
|
19
|
-
expect(ip).toBe('172.16.0.1');
|
|
21
|
+
|
|
22
|
+
expect(ip).toBe('172.16.0.1');
|
|
23
|
+
expect(consoleLogSpy).not.toHaveBeenCalled();
|
|
20
24
|
});
|
|
21
25
|
|
|
22
26
|
it('| should extract IP from socket.remoteAddress when x-forwarded-for is not present', () => {
|
|
@@ -63,22 +67,52 @@ describe('| DyNTS_Shared', () => {
|
|
|
63
67
|
});
|
|
64
68
|
});
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
describe('| getLocationDataByRequest', () => {
|
|
71
|
+
it('| should return null without logging the request IP when provider is unavailable', () => {
|
|
72
|
+
const consoleLogSpy: jasmine.Spy = spyOn(console, 'log');
|
|
73
|
+
|
|
74
|
+
spyOn<any>(DyNTS_Shared, 'getGeoIpProvider').and.returnValue(null);
|
|
75
|
+
const mockRequest = {
|
|
76
|
+
headers: {
|
|
77
|
+
'x-forwarded-for': '198.51.100.17',
|
|
78
|
+
},
|
|
79
|
+
socket: {
|
|
80
|
+
remoteAddress: '127.0.0.1',
|
|
81
|
+
},
|
|
82
|
+
} as any as Request;
|
|
83
|
+
|
|
84
|
+
expect(DyNTS_Shared.getLocationDataByRequest(mockRequest)).toBeNull();
|
|
85
|
+
expect(consoleLogSpy).not.toHaveBeenCalled();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('| getLocationByIp', () => {
|
|
90
|
+
it('| should use the optional local provider when available', () => {
|
|
91
|
+
const location: DyFM_GeoIpLocation = {
|
|
92
|
+
range: [ 0, 1 ],
|
|
93
|
+
country: 'HU',
|
|
94
|
+
region: '',
|
|
95
|
+
eu: '1',
|
|
96
|
+
timezone: 'Europe/Budapest',
|
|
97
|
+
city: 'Budapest',
|
|
98
|
+
ll: [ 47.4979, 19.0402 ],
|
|
99
|
+
metro: 0,
|
|
100
|
+
area: 10,
|
|
101
|
+
};
|
|
102
|
+
const lookupSpy: jasmine.Spy = jasmine.createSpy('lookup').and.returnValue(location);
|
|
103
|
+
|
|
104
|
+
spyOn<any>(DyNTS_Shared, 'getGeoIpProvider').and.returnValue({ lookup: lookupSpy });
|
|
105
|
+
|
|
106
|
+
expect(DyNTS_Shared.getLocationByIp('203.0.113.7')).toEqual(location);
|
|
107
|
+
expect(lookupSpy).toHaveBeenCalledOnceWith('203.0.113.7');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('| should return null when the optional provider is unavailable', () => {
|
|
111
|
+
spyOn<any>(DyNTS_Shared, 'getGeoIpProvider').and.returnValue(null);
|
|
112
|
+
|
|
113
|
+
expect(DyNTS_Shared.getLocationByIp('203.0.113.7')).toBeNull();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
82
116
|
|
|
83
117
|
describe('| prompt', () => {
|
|
84
118
|
it('| should be accessible', () => {
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
import * as ReadLine from 'readline';
|
|
3
|
-
import
|
|
4
|
-
import { Request } from 'express';
|
|
2
|
+
import * as ReadLine from 'readline';
|
|
3
|
+
import { createRequire } from 'module';
|
|
4
|
+
import { Request } from 'express';
|
|
5
5
|
|
|
6
6
|
import { DyFM_Object } from '@futdevpro/fsm-dynamo';
|
|
7
|
-
import { DyFM_GeoIpLocation } from '@futdevpro/fsm-dynamo/location';
|
|
7
|
+
import { DyFM_GeoIpLocation } from '@futdevpro/fsm-dynamo/location';
|
|
8
|
+
|
|
9
|
+
interface DyNTS_GeoIpProvider {
|
|
10
|
+
lookup(ip: string): DyFM_GeoIpLocation | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const DyNTS_optionalRequire: NodeJS.Require = createRequire(__filename);
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* Collection of static helper utilities shared across modules.
|
|
@@ -20,11 +26,10 @@ export class DyNTS_Shared extends DyFM_Object {
|
|
|
20
26
|
static getIpFromRequest(request: Request): string {
|
|
21
27
|
let ip: string;
|
|
22
28
|
|
|
23
|
-
if (request?.headers?.['x-forwarded-for']) {
|
|
24
|
-
const route: string[] = (request.headers['x-forwarded-for'] as string).split(', ');
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ip = route[route.length - 1];
|
|
29
|
+
if (request?.headers?.['x-forwarded-for']) {
|
|
30
|
+
const route: string[] = (request.headers['x-forwarded-for'] as string).split(', ');
|
|
31
|
+
|
|
32
|
+
ip = route[route.length - 1];
|
|
28
33
|
} else {
|
|
29
34
|
ip = request.socket.remoteAddress;
|
|
30
35
|
}
|
|
@@ -36,21 +41,45 @@ export class DyNTS_Shared extends DyFM_Object {
|
|
|
36
41
|
* Lookup the Geo location of a request based on its IP address.
|
|
37
42
|
*
|
|
38
43
|
* @param request Incoming request
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
* The optional GeoIP provider is loaded only for this capability. When it is not installed,
|
|
45
|
+
* the method returns `null` and does not transmit or log the address.
|
|
46
|
+
*
|
|
47
|
+
* @returns Resolved geo location information, or `null` when unavailable
|
|
48
|
+
*/
|
|
49
|
+
static getLocationDataByRequest(request: Request): DyFM_GeoIpLocation | null {
|
|
50
|
+
return this.getLocationByIp(this.getIpFromRequest(request));
|
|
51
|
+
}
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
54
|
* Lookup the Geo location of a raw IP address.
|
|
47
55
|
*
|
|
48
56
|
* @param ip IP address string
|
|
49
|
-
*
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
* The lookup is local-only: the IP address is never sent to an external service. The optional
|
|
58
|
+
* provider may be omitted by consumers that do not use geolocation.
|
|
59
|
+
*
|
|
60
|
+
* @returns Geo location information, or `null` when unavailable
|
|
61
|
+
*/
|
|
62
|
+
static getLocationByIp(ip: string): DyFM_GeoIpLocation | null {
|
|
63
|
+
const geoIpProvider: DyNTS_GeoIpProvider | null = this.getGeoIpProvider();
|
|
64
|
+
|
|
65
|
+
return geoIpProvider?.lookup(ip) ?? null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private static getGeoIpProvider(): DyNTS_GeoIpProvider | null {
|
|
69
|
+
let geoIpModulePath: string;
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
geoIpModulePath = DyNTS_optionalRequire.resolve('geoip-lite');
|
|
73
|
+
} catch (error: unknown) {
|
|
74
|
+
if (error instanceof Error && 'code' in error && error.code === 'MODULE_NOT_FOUND') {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return DyNTS_optionalRequire(geoIpModulePath);
|
|
82
|
+
}
|
|
54
83
|
|
|
55
84
|
/**
|
|
56
85
|
* Simple CLI helper to prompt the user for input.
|