@futdevpro/nts-dynamo 1.15.154 → 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 +28 -24
- package/__documentations/2026-08-22-content-free-process-error-boundary.md +91 -91
- 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 +23 -23
- package/src/_models/control-models/app-params.control-model.ts +10 -10
- package/src/_modules/server/index.ts +8 -8
- package/src/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.ts +8 -8
- package/src/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.ts +19 -19
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.spec.ts +124 -124
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.control-service.ts +99 -99
- package/src/_modules/server/safe-diagnostic/safe-diagnostic.interface.ts +20 -20
- package/src/_services/core/global.service.ts +55 -55
- package/src/_services/server/app-safe-diagnostic.spec.ts +124 -124
- package/src/_services/server/app.server.ts +294 -294
- package/src/_services/shared.static-service.spec.ts +57 -23
- package/src/_services/shared.static-service.ts +48 -19
package/README.md
CHANGED
|
@@ -28,26 +28,26 @@ Dynamo-NTS simplifies complex system definitions by abstracting common backend i
|
|
|
28
28
|
- **Axios Usage**: HTTP client requests to external APIs are standardized through `DyNTS_ApiService` with `DyNTS_ApiCall_Params` configuration (simplifies Axios request setup, error handling, and response management)
|
|
29
29
|
- **Discord.js / Slack / Teams Bot Development**: Platform-agnostic bot framework through `DyNTS_Bot_MessagingProvider_ServiceBase` and bot modules (simplifies Discord.js, Slack, and Teams bot development with unified interfaces)
|
|
30
30
|
- **OpenAI / AI Provider Integration**: AI/LLM operations including chat, embeddings, and vector search are abstracted through `DyNTS_AI_Provider_ServiceBase` and provider implementations (simplifies OpenAI SDK usage and enables multi-provider architecture)
|
|
31
|
-
- **Location Tracking**:
|
|
31
|
+
- **Location Tracking**: Optional, local-only IP geolocation through `geoip-lite`; addresses are not sent to an external service or written to logs by Dynamo-NTS
|
|
32
32
|
|
|
33
|
-
This parameterization approach eliminates boilerplate code and provides a consistent, type-safe interface for all backend operations. Instead of learning multiple library APIs and their configuration patterns, developers work with unified Dynamo-NTS parameter objects that handle the underlying complexity.
|
|
34
|
-
|
|
35
|
-
### Content-free process diagnostics
|
|
36
|
-
|
|
37
|
-
`DyNTS_App` projects bootstrap failures, unhandled promise rejections, database connection/runtime failures,
|
|
38
|
-
HTTP/HTTPS server errors, routing failures and Express fallbacks through the versioned
|
|
39
|
-
`dynts-safe-diagnostic/1` contract before framework-owned logging or error forwarding. The public allowlist is
|
|
40
|
-
limited to `contractVersion`, `code`, `stage`, `causeType`, `fingerprint` and `status`. Raw error messages,
|
|
41
|
-
stacks, rejected promises, requests and database URIs are excluded. The fingerprint is derived only from the
|
|
42
|
-
allowlisted classification, never from raw failure content.
|
|
43
|
-
|
|
44
|
-
Consumers can use `DyNTS_SafeDiagnostic_ControlService.project()` when they need the same deterministic
|
|
45
|
-
projection without logging, `report()` for safe framework logging, and `toError()` when a content-free
|
|
46
|
-
`DyFM_Error` must cross an existing error-handler boundary. See
|
|
47
|
-
[`__documentations/2026-08-22-content-free-process-error-boundary.md`](./__documentations/2026-08-22-content-free-process-error-boundary.md)
|
|
48
|
-
for the normative boundary and verification matrix.
|
|
49
|
-
|
|
50
|
-
## Table of Contents
|
|
33
|
+
This parameterization approach eliminates boilerplate code and provides a consistent, type-safe interface for all backend operations. Instead of learning multiple library APIs and their configuration patterns, developers work with unified Dynamo-NTS parameter objects that handle the underlying complexity.
|
|
34
|
+
|
|
35
|
+
### Content-free process diagnostics
|
|
36
|
+
|
|
37
|
+
`DyNTS_App` projects bootstrap failures, unhandled promise rejections, database connection/runtime failures,
|
|
38
|
+
HTTP/HTTPS server errors, routing failures and Express fallbacks through the versioned
|
|
39
|
+
`dynts-safe-diagnostic/1` contract before framework-owned logging or error forwarding. The public allowlist is
|
|
40
|
+
limited to `contractVersion`, `code`, `stage`, `causeType`, `fingerprint` and `status`. Raw error messages,
|
|
41
|
+
stacks, rejected promises, requests and database URIs are excluded. The fingerprint is derived only from the
|
|
42
|
+
allowlisted classification, never from raw failure content.
|
|
43
|
+
|
|
44
|
+
Consumers can use `DyNTS_SafeDiagnostic_ControlService.project()` when they need the same deterministic
|
|
45
|
+
projection without logging, `report()` for safe framework logging, and `toError()` when a content-free
|
|
46
|
+
`DyFM_Error` must cross an existing error-handler boundary. See
|
|
47
|
+
[`__documentations/2026-08-22-content-free-process-error-boundary.md`](./__documentations/2026-08-22-content-free-process-error-boundary.md)
|
|
48
|
+
for the normative boundary and verification matrix.
|
|
49
|
+
|
|
50
|
+
## Table of Contents
|
|
51
51
|
|
|
52
52
|
- [Installation](#installation)
|
|
53
53
|
- [Quick Start](#quick-start)
|
|
@@ -98,9 +98,13 @@ These dependencies are only required when using specific modules:
|
|
|
98
98
|
|
|
99
99
|
- **Socket Module**: `socket.io` - Real-time communication (simplified through Dynamo-NTS socket services)
|
|
100
100
|
- **Email Service**: `nodemailer` - Email sending (simplified through Dynamo-NTS email services)
|
|
101
|
-
- **Usage Module**: `geoip-lite` and `@types/geoip-lite` - IP geolocation
|
|
102
|
-
- **Bot Module (Discord)**: `discord.js` - Discord bot development (simplified through Dynamo-NTS bot module)
|
|
103
|
-
- **AI Module (OpenAI)**: `openai` - OpenAI API integration (simplified through Dynamo-NTS AI module)
|
|
101
|
+
- **Usage Module**: `geoip-lite` and `@types/geoip-lite` - optional, local-only IP geolocation. The provider is loaded only when a lookup is requested. Without it, lookup methods return `null` and the rest of Dynamo-NTS remains usable. The supported secure `geoip-lite` line requires Node.js 24 or newer.
|
|
102
|
+
- **Bot Module (Discord)**: `discord.js` - Discord bot development (simplified through Dynamo-NTS bot module)
|
|
103
|
+
- **AI Module (OpenAI)**: `openai` - OpenAI API integration (simplified through Dynamo-NTS AI module)
|
|
104
|
+
|
|
105
|
+
The GeoIP lookup itself does not transmit or log an address. Calling the Usage module can persist the
|
|
106
|
+
request address and derived location in the consumer's own data store. Consumers enabling that capability
|
|
107
|
+
must define the applicable lawful basis, user-facing transparency, access controls, retention and deletion.
|
|
104
108
|
|
|
105
109
|
Install module-specific dependencies as needed:
|
|
106
110
|
|
|
@@ -111,8 +115,8 @@ pnpm add socket.io
|
|
|
111
115
|
# For Email service
|
|
112
116
|
pnpm add nodemailer
|
|
113
117
|
|
|
114
|
-
# For Usage module
|
|
115
|
-
pnpm add geoip-lite @types/geoip-lite
|
|
118
|
+
# For Usage module
|
|
119
|
+
pnpm add geoip-lite@^2.0.3 @types/geoip-lite@^1.4.4
|
|
116
120
|
|
|
117
121
|
# For Bot module (Discord)
|
|
118
122
|
pnpm add discord.js
|
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
# Content-free process error boundary
|
|
2
|
-
|
|
3
|
-
**Date:** 2026-08-22
|
|
4
|
-
**Status:** implemented; verification evidence is recorded below
|
|
5
|
-
**Contract:** `dynts-safe-diagnostic/1`
|
|
6
|
-
**Package surface:** `@futdevpro/nts-dynamo`, server module exports
|
|
7
|
-
|
|
8
|
-
## Purpose
|
|
9
|
-
|
|
10
|
-
Dynamo-NTS must remain debuggable without copying arbitrary application content into framework-owned logs or
|
|
11
|
-
error forwarding. Process failures can contain credentials, personal data, workbook values, HTTP request data,
|
|
12
|
-
provider responses or attacker-controlled strings in `message`, `stack`, rejected promises and nested error
|
|
13
|
-
objects. This boundary converts such failures to a fixed allowlist before they reach a Dynamo-NTS logger or the
|
|
14
|
-
global handler from `DyNTS_App`.
|
|
15
|
-
|
|
16
|
-
The capability is direct Dynamo Bedrock. Consuming applications must use it as supplied and may add their own
|
|
17
|
-
product metadata only through a separately reviewed, content-free contract.
|
|
18
|
-
|
|
19
|
-
## Normative public contract
|
|
20
|
-
|
|
21
|
-
`DyNTS_SafeDiagnostic_Interface` contains exactly these fields:
|
|
22
|
-
|
|
23
|
-
| Field | Meaning |
|
|
24
|
-
|---|---|
|
|
25
|
-
| `contractVersion` | Literal `dynts-safe-diagnostic/1`. |
|
|
26
|
-
| `code` | Stable uppercase error code; invalid caller input fails closed to a fixed fallback. |
|
|
27
|
-
| `stage` | Closed lifecycle-stage enum. |
|
|
28
|
-
| `causeType` | Coarse classification only: Dynamo error, native error, object, primitive or unknown. |
|
|
29
|
-
| `fingerprint` | SHA-256 correlation of contract version, code, stage, cause type and status only. |
|
|
30
|
-
| `status` | Valid HTTP-style integer from 100 through 599; otherwise 500. |
|
|
31
|
-
|
|
32
|
-
No raw failure content participates in the returned object or the fingerprint. In particular, `message`,
|
|
33
|
-
`stack`, request/response objects, rejected promises, MongoDB URIs, usernames, passwords, tokens, workbook data
|
|
34
|
-
and arbitrary nested properties are not public fields and are never read for fingerprint construction.
|
|
35
|
-
|
|
36
|
-
The projection is immutable. `project()` returns it without side effects, `report()` logs only that projection,
|
|
37
|
-
and `toError()` creates a `DyFM_Error` whose message and additional content are derived solely from the safe
|
|
38
|
-
projection.
|
|
39
|
-
|
|
40
|
-
## Framework integration
|
|
41
|
-
|
|
42
|
-
`DyNTS_App` applies the projection before framework-owned logging and forwarding at these boundaries:
|
|
43
|
-
|
|
44
|
-
- bootstrap rejection and `unhandledRejection`;
|
|
45
|
-
- post-process, memory guard, event-loop diagnostics and collection-growth monitor failures;
|
|
46
|
-
- readiness reporting;
|
|
47
|
-
- initial MongoDB connect failure, runtime connection error and reconnect-guard diagnostics;
|
|
48
|
-
- HTTP and HTTPS server error/uncaught-exception events;
|
|
49
|
-
- open/secure route configuration and duplicate-route failures;
|
|
50
|
-
- Express error fallback and secondary global-handler failures;
|
|
51
|
-
- retention installation diagnostics.
|
|
52
|
-
|
|
53
|
-
MongoDB connection success logs only the stable fact that MongoDB is connected. Malformed URI warnings,
|
|
54
|
-
initial connection failure and runtime connection failure do not interpolate the URI. The URI remains an input
|
|
55
|
-
to Mongoose because it is operationally required, but it is not a diagnostic value.
|
|
56
|
-
|
|
57
|
-
The default `DyNTS_GlobalService` handler also projects a raw failure before logging. A consumer-supplied global
|
|
58
|
-
handler remains a consumer boundary; failures forwarded by `DyNTS_App` reach it as a content-free `DyFM_Error`.
|
|
59
|
-
If that handler throws or rejects, Dynamo-NTS projects the secondary failure rather than recursively logging it.
|
|
60
|
-
|
|
61
|
-
## Security and privacy properties
|
|
62
|
-
|
|
63
|
-
- The output is an exact allowlist rather than a denylist-based redaction attempt.
|
|
64
|
-
- Hostile getters on error objects cannot make raw content appear in the projection.
|
|
65
|
-
- Correlation is deterministic for the same safe classification but cannot be used to dictionary-test an error
|
|
66
|
-
message, password or token because raw values are excluded from the hash input.
|
|
67
|
-
- Invalid codes and statuses fail closed to stable defaults.
|
|
68
|
-
- Client responses continue to use the existing client-safe error utility; this capability governs
|
|
69
|
-
framework-owned process diagnostics and forwarding.
|
|
70
|
-
- This boundary reduces disclosure risk but does not authorize logging sensitive values elsewhere in a
|
|
71
|
-
consuming application.
|
|
72
|
-
|
|
73
|
-
## Verification matrix
|
|
74
|
-
|
|
75
|
-
| Evidence | Required assertion |
|
|
76
|
-
|---|---|
|
|
77
|
-
| Safe-diagnostic unit tests | Exact frozen allowlist, stable fingerprint, cause classification and fail-closed hostile input. |
|
|
78
|
-
| Report/toError unit test | Logger and serialized `DyFM_Error` contain the safe contract and exclude a credential-bearing canary. |
|
|
79
|
-
| Process-boundary runtime test | Unhandled rejection is projected before both logging and global-handler forwarding. |
|
|
80
|
-
| Bootstrap runtime test | Rejected construction is projected before logging/forwarding and terminates with exit code 1. |
|
|
81
|
-
| Default-handler runtime test | Raw input is projected before default global logging. |
|
|
82
|
-
| App-params test | A malformed credential-bearing MongoDB URI triggers a warning without exposing the URI. |
|
|
83
|
-
| Static source scan | No Dynamo-NTS App log call receives raw error, stack, promise, construct-error collection or DB URI. |
|
|
84
|
-
| Full package regression | Build, complete Jasmine suite and project validators remain green. |
|
|
85
|
-
|
|
86
|
-
## Consumer adoption requirement
|
|
87
|
-
|
|
88
|
-
A consumer adopts the capability by pinning the first exact `@futdevpro/nts-dynamo` version that contains this
|
|
89
|
-
document and by proving the package-level runtime tests in its dependency tree. Reimplementing the boundary in
|
|
90
|
-
the product does not count as Bedrock adoption. Product-specific diagnostics may compose the safe fields, but
|
|
91
|
-
must not copy or reinterpret raw failure content.
|
|
1
|
+
# Content-free process error boundary
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-22
|
|
4
|
+
**Status:** implemented; verification evidence is recorded below
|
|
5
|
+
**Contract:** `dynts-safe-diagnostic/1`
|
|
6
|
+
**Package surface:** `@futdevpro/nts-dynamo`, server module exports
|
|
7
|
+
|
|
8
|
+
## Purpose
|
|
9
|
+
|
|
10
|
+
Dynamo-NTS must remain debuggable without copying arbitrary application content into framework-owned logs or
|
|
11
|
+
error forwarding. Process failures can contain credentials, personal data, workbook values, HTTP request data,
|
|
12
|
+
provider responses or attacker-controlled strings in `message`, `stack`, rejected promises and nested error
|
|
13
|
+
objects. This boundary converts such failures to a fixed allowlist before they reach a Dynamo-NTS logger or the
|
|
14
|
+
global handler from `DyNTS_App`.
|
|
15
|
+
|
|
16
|
+
The capability is direct Dynamo Bedrock. Consuming applications must use it as supplied and may add their own
|
|
17
|
+
product metadata only through a separately reviewed, content-free contract.
|
|
18
|
+
|
|
19
|
+
## Normative public contract
|
|
20
|
+
|
|
21
|
+
`DyNTS_SafeDiagnostic_Interface` contains exactly these fields:
|
|
22
|
+
|
|
23
|
+
| Field | Meaning |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `contractVersion` | Literal `dynts-safe-diagnostic/1`. |
|
|
26
|
+
| `code` | Stable uppercase error code; invalid caller input fails closed to a fixed fallback. |
|
|
27
|
+
| `stage` | Closed lifecycle-stage enum. |
|
|
28
|
+
| `causeType` | Coarse classification only: Dynamo error, native error, object, primitive or unknown. |
|
|
29
|
+
| `fingerprint` | SHA-256 correlation of contract version, code, stage, cause type and status only. |
|
|
30
|
+
| `status` | Valid HTTP-style integer from 100 through 599; otherwise 500. |
|
|
31
|
+
|
|
32
|
+
No raw failure content participates in the returned object or the fingerprint. In particular, `message`,
|
|
33
|
+
`stack`, request/response objects, rejected promises, MongoDB URIs, usernames, passwords, tokens, workbook data
|
|
34
|
+
and arbitrary nested properties are not public fields and are never read for fingerprint construction.
|
|
35
|
+
|
|
36
|
+
The projection is immutable. `project()` returns it without side effects, `report()` logs only that projection,
|
|
37
|
+
and `toError()` creates a `DyFM_Error` whose message and additional content are derived solely from the safe
|
|
38
|
+
projection.
|
|
39
|
+
|
|
40
|
+
## Framework integration
|
|
41
|
+
|
|
42
|
+
`DyNTS_App` applies the projection before framework-owned logging and forwarding at these boundaries:
|
|
43
|
+
|
|
44
|
+
- bootstrap rejection and `unhandledRejection`;
|
|
45
|
+
- post-process, memory guard, event-loop diagnostics and collection-growth monitor failures;
|
|
46
|
+
- readiness reporting;
|
|
47
|
+
- initial MongoDB connect failure, runtime connection error and reconnect-guard diagnostics;
|
|
48
|
+
- HTTP and HTTPS server error/uncaught-exception events;
|
|
49
|
+
- open/secure route configuration and duplicate-route failures;
|
|
50
|
+
- Express error fallback and secondary global-handler failures;
|
|
51
|
+
- retention installation diagnostics.
|
|
52
|
+
|
|
53
|
+
MongoDB connection success logs only the stable fact that MongoDB is connected. Malformed URI warnings,
|
|
54
|
+
initial connection failure and runtime connection failure do not interpolate the URI. The URI remains an input
|
|
55
|
+
to Mongoose because it is operationally required, but it is not a diagnostic value.
|
|
56
|
+
|
|
57
|
+
The default `DyNTS_GlobalService` handler also projects a raw failure before logging. A consumer-supplied global
|
|
58
|
+
handler remains a consumer boundary; failures forwarded by `DyNTS_App` reach it as a content-free `DyFM_Error`.
|
|
59
|
+
If that handler throws or rejects, Dynamo-NTS projects the secondary failure rather than recursively logging it.
|
|
60
|
+
|
|
61
|
+
## Security and privacy properties
|
|
62
|
+
|
|
63
|
+
- The output is an exact allowlist rather than a denylist-based redaction attempt.
|
|
64
|
+
- Hostile getters on error objects cannot make raw content appear in the projection.
|
|
65
|
+
- Correlation is deterministic for the same safe classification but cannot be used to dictionary-test an error
|
|
66
|
+
message, password or token because raw values are excluded from the hash input.
|
|
67
|
+
- Invalid codes and statuses fail closed to stable defaults.
|
|
68
|
+
- Client responses continue to use the existing client-safe error utility; this capability governs
|
|
69
|
+
framework-owned process diagnostics and forwarding.
|
|
70
|
+
- This boundary reduces disclosure risk but does not authorize logging sensitive values elsewhere in a
|
|
71
|
+
consuming application.
|
|
72
|
+
|
|
73
|
+
## Verification matrix
|
|
74
|
+
|
|
75
|
+
| Evidence | Required assertion |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Safe-diagnostic unit tests | Exact frozen allowlist, stable fingerprint, cause classification and fail-closed hostile input. |
|
|
78
|
+
| Report/toError unit test | Logger and serialized `DyFM_Error` contain the safe contract and exclude a credential-bearing canary. |
|
|
79
|
+
| Process-boundary runtime test | Unhandled rejection is projected before both logging and global-handler forwarding. |
|
|
80
|
+
| Bootstrap runtime test | Rejected construction is projected before logging/forwarding and terminates with exit code 1. |
|
|
81
|
+
| Default-handler runtime test | Raw input is projected before default global logging. |
|
|
82
|
+
| App-params test | A malformed credential-bearing MongoDB URI triggers a warning without exposing the URI. |
|
|
83
|
+
| Static source scan | No Dynamo-NTS App log call receives raw error, stack, promise, construct-error collection or DB URI. |
|
|
84
|
+
| Full package regression | Build, complete Jasmine suite and project validators remain green. |
|
|
85
|
+
|
|
86
|
+
## Consumer adoption requirement
|
|
87
|
+
|
|
88
|
+
A consumer adopts the capability by pinning the first exact `@futdevpro/nts-dynamo` version that contains this
|
|
89
|
+
document and by proving the package-level runtime tests in its dependency tree. Reimplementing the boundary in
|
|
90
|
+
the product does not count as Bedrock adoption. Product-specific diagnostics may compose the safe fields, but
|
|
91
|
+
must not copy or reinterpret raw failure content.
|
|
@@ -16,16 +16,23 @@ export declare class DyNTS_Shared extends DyFM_Object {
|
|
|
16
16
|
* Lookup the Geo location of a request based on its IP address.
|
|
17
17
|
*
|
|
18
18
|
* @param request Incoming request
|
|
19
|
-
*
|
|
19
|
+
* The optional GeoIP provider is loaded only for this capability. When it is not installed,
|
|
20
|
+
* the method returns `null` and does not transmit or log the address.
|
|
21
|
+
*
|
|
22
|
+
* @returns Resolved geo location information, or `null` when unavailable
|
|
20
23
|
*/
|
|
21
|
-
static getLocationDataByRequest(request: Request): DyFM_GeoIpLocation;
|
|
24
|
+
static getLocationDataByRequest(request: Request): DyFM_GeoIpLocation | null;
|
|
22
25
|
/**
|
|
23
26
|
* Lookup the Geo location of a raw IP address.
|
|
24
27
|
*
|
|
25
28
|
* @param ip IP address string
|
|
26
|
-
*
|
|
29
|
+
* The lookup is local-only: the IP address is never sent to an external service. The optional
|
|
30
|
+
* provider may be omitted by consumers that do not use geolocation.
|
|
31
|
+
*
|
|
32
|
+
* @returns Geo location information, or `null` when unavailable
|
|
27
33
|
*/
|
|
28
|
-
static getLocationByIp(ip: string): DyFM_GeoIpLocation;
|
|
34
|
+
static getLocationByIp(ip: string): DyFM_GeoIpLocation | null;
|
|
35
|
+
private static getGeoIpProvider;
|
|
29
36
|
/**
|
|
30
37
|
* Simple CLI helper to prompt the user for input.
|
|
31
38
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.static-service.d.ts","sourceRoot":"","sources":["../../src/_services/shared.static-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.static-service.d.ts","sourceRoot":"","sources":["../../src/_services/shared.static-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAQpE;;GAEG;AACH,qBAAa,YAAa,SAAQ,WAAW;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAcjD;;;;;;;;OAQG;IACH,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI;IAI5E;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAM7D,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAgB/B;;;;;OAKG;WACU,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAiBvD"}
|
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DyNTS_Shared = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const ReadLine = tslib_1.__importStar(require("readline"));
|
|
6
|
-
const
|
|
6
|
+
const module_1 = require("module");
|
|
7
7
|
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
8
|
+
const DyNTS_optionalRequire = (0, module_1.createRequire)(__filename);
|
|
8
9
|
/**
|
|
9
10
|
* Collection of static helper utilities shared across modules.
|
|
10
11
|
*/
|
|
@@ -19,7 +20,6 @@ class DyNTS_Shared extends fsm_dynamo_1.DyFM_Object {
|
|
|
19
20
|
let ip;
|
|
20
21
|
if (request?.headers?.['x-forwarded-for']) {
|
|
21
22
|
const route = request.headers['x-forwarded-for'].split(', ');
|
|
22
|
-
console.log('TESTTTT route:', route);
|
|
23
23
|
ip = route[route.length - 1];
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
@@ -31,19 +31,39 @@ class DyNTS_Shared extends fsm_dynamo_1.DyFM_Object {
|
|
|
31
31
|
* Lookup the Geo location of a request based on its IP address.
|
|
32
32
|
*
|
|
33
33
|
* @param request Incoming request
|
|
34
|
-
*
|
|
34
|
+
* The optional GeoIP provider is loaded only for this capability. When it is not installed,
|
|
35
|
+
* the method returns `null` and does not transmit or log the address.
|
|
36
|
+
*
|
|
37
|
+
* @returns Resolved geo location information, or `null` when unavailable
|
|
35
38
|
*/
|
|
36
39
|
static getLocationDataByRequest(request) {
|
|
37
|
-
return
|
|
40
|
+
return this.getLocationByIp(this.getIpFromRequest(request));
|
|
38
41
|
}
|
|
39
42
|
/**
|
|
40
43
|
* Lookup the Geo location of a raw IP address.
|
|
41
44
|
*
|
|
42
45
|
* @param ip IP address string
|
|
43
|
-
*
|
|
46
|
+
* The lookup is local-only: the IP address is never sent to an external service. The optional
|
|
47
|
+
* provider may be omitted by consumers that do not use geolocation.
|
|
48
|
+
*
|
|
49
|
+
* @returns Geo location information, or `null` when unavailable
|
|
44
50
|
*/
|
|
45
51
|
static getLocationByIp(ip) {
|
|
46
|
-
|
|
52
|
+
const geoIpProvider = this.getGeoIpProvider();
|
|
53
|
+
return geoIpProvider?.lookup(ip) ?? null;
|
|
54
|
+
}
|
|
55
|
+
static getGeoIpProvider() {
|
|
56
|
+
let geoIpModulePath;
|
|
57
|
+
try {
|
|
58
|
+
geoIpModulePath = DyNTS_optionalRequire.resolve('geoip-lite');
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof Error && 'code' in error && error.code === 'MODULE_NOT_FOUND') {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
return DyNTS_optionalRequire(geoIpModulePath);
|
|
47
67
|
}
|
|
48
68
|
/**
|
|
49
69
|
* Simple CLI helper to prompt the user for input.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.static-service.js","sourceRoot":"","sources":["../../src/_services/shared.static-service.ts"],"names":[],"mappings":";;;;AACA,2DAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"shared.static-service.js","sourceRoot":"","sources":["../../src/_services/shared.static-service.ts"],"names":[],"mappings":";;;;AACA,2DAAqC;AACrC,mCAAuC;AAGvC,sDAAoD;AAOpD,MAAM,qBAAqB,GAAmB,IAAA,sBAAa,EAAC,UAAU,CAAC,CAAC;AAExE;;GAEG;AACH,MAAa,YAAa,SAAQ,wBAAW;IAE3C;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAgB;QACtC,IAAI,EAAU,CAAC;QAEf,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAc,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEnF,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;QACpC,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,wBAAwB,CAAC,OAAgB;QAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,EAAU;QAC/B,MAAM,aAAa,GAA+B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE1E,OAAO,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;IAC3C,CAAC;IAEO,MAAM,CAAC,gBAAgB;QAC7B,IAAI,eAAuB,CAAC;QAE5B,IAAI,CAAC;YACH,eAAe,GAAG,qBAAqB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBACnF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;QAED,OAAO,qBAAqB,CAAC,eAAe,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAgB;QAClC,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC;YACxC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAc,EAAE,EAAE;oBAC7C,OAAO,CAAC,MAAM,CAAC,CAAC;oBAChB,QAAQ,CAAC,KAAK,EAAE,CAAC;gBACnB,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAzFD,oCAyFC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/nts-dynamo",
|
|
3
|
-
"version": "01.15.
|
|
3
|
+
"version": "01.15.155",
|
|
4
4
|
"description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "server-package",
|
|
@@ -411,16 +411,16 @@
|
|
|
411
411
|
"better-sqlite3": "~12.4.1",
|
|
412
412
|
"@futdevpro/fsm-dynamo": "1.16.40",
|
|
413
413
|
"@types/express": "4.17.21",
|
|
414
|
-
"@types/geoip-lite": "~1.4.
|
|
414
|
+
"@types/geoip-lite": "~1.4.4",
|
|
415
415
|
"@types/node": "~24.1.0",
|
|
416
|
-
"axios": ">=1.
|
|
417
|
-
"body-parser": "
|
|
416
|
+
"axios": ">=1.19.0 <2",
|
|
417
|
+
"body-parser": ">=1.20.6 <2",
|
|
418
418
|
"discord.js": "~14.24.2",
|
|
419
|
-
"dotenv": "
|
|
420
|
-
"express": "4.
|
|
421
|
-
"geoip-lite": "
|
|
422
|
-
"mongoose": "
|
|
423
|
-
"nodemailer": ">=
|
|
419
|
+
"dotenv": ">=16.6.1 <17",
|
|
420
|
+
"express": ">=4.22.1 <5",
|
|
421
|
+
"geoip-lite": ">=2.0.3 <3",
|
|
422
|
+
"mongoose": ">=8.24.1 <9",
|
|
423
|
+
"nodemailer": ">=9.0.5 <10",
|
|
424
424
|
"openai": "~5.23.2",
|
|
425
425
|
"rxjs": "7.8.1",
|
|
426
426
|
"ts-node": "~10.9.2"
|
|
@@ -438,6 +438,12 @@
|
|
|
438
438
|
"discord.js": {
|
|
439
439
|
"optional": true
|
|
440
440
|
},
|
|
441
|
+
"@types/geoip-lite": {
|
|
442
|
+
"optional": true
|
|
443
|
+
},
|
|
444
|
+
"geoip-lite": {
|
|
445
|
+
"optional": true
|
|
446
|
+
},
|
|
441
447
|
"openai": {
|
|
442
448
|
"optional": true
|
|
443
449
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
import { DyFM_EnvironmentFlag, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
3
|
-
|
|
4
|
-
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
5
|
-
|
|
6
|
-
import { DyNTS_App_Params } from './app-params.control-model';
|
|
2
|
+
import { DyFM_EnvironmentFlag, DyFM_Log } from '@futdevpro/fsm-dynamo';
|
|
3
|
+
|
|
4
|
+
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
5
|
+
|
|
6
|
+
import { DyNTS_App_Params } from './app-params.control-model';
|
|
7
7
|
|
|
8
8
|
describe('| DyNTS_App_Params', () => {
|
|
9
9
|
let originalEnv: any;
|
|
@@ -209,21 +209,21 @@ describe('| DyNTS_App_Params', () => {
|
|
|
209
209
|
expect(logSpy).toHaveBeenCalled();
|
|
210
210
|
});
|
|
211
211
|
|
|
212
|
-
it('| should warn without logging a malformed credential-bearing dbUri', () => {
|
|
213
|
-
const logSpy = spyOn(DyFM_Log, 'warn');
|
|
214
|
-
const canary: string = 'mongodb://canary-user:canary-secret@localhost:27017//testdb';
|
|
215
|
-
|
|
216
|
-
const params: DyNTS_App_Params = {
|
|
217
|
-
name: 'TestApp',
|
|
218
|
-
version: '1.0.0',
|
|
219
|
-
dbName: 'testdb',
|
|
220
|
-
dbUri: canary,
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
new DyNTS_App_Params(params);
|
|
224
|
-
|
|
225
|
-
expect(logSpy).toHaveBeenCalled();
|
|
226
|
-
expect(JSON.stringify(logSpy.calls.allArgs())).not.toContain(canary);
|
|
227
|
-
expect(JSON.stringify(logSpy.calls.allArgs())).not.toContain('canary-secret');
|
|
228
|
-
});
|
|
229
|
-
});
|
|
212
|
+
it('| should warn without logging a malformed credential-bearing dbUri', () => {
|
|
213
|
+
const logSpy = spyOn(DyFM_Log, 'warn');
|
|
214
|
+
const canary: string = 'mongodb://canary-user:canary-secret@localhost:27017//testdb';
|
|
215
|
+
|
|
216
|
+
const params: DyNTS_App_Params = {
|
|
217
|
+
name: 'TestApp',
|
|
218
|
+
version: '1.0.0',
|
|
219
|
+
dbName: 'testdb',
|
|
220
|
+
dbUri: canary,
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
new DyNTS_App_Params(params);
|
|
224
|
+
|
|
225
|
+
expect(logSpy).toHaveBeenCalled();
|
|
226
|
+
expect(JSON.stringify(logSpy.calls.allArgs())).not.toContain(canary);
|
|
227
|
+
expect(JSON.stringify(logSpy.calls.allArgs())).not.toContain('canary-secret');
|
|
228
|
+
});
|
|
229
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ConnectOptions } from 'mongoose';
|
|
2
|
-
|
|
3
|
-
import { DyFM_Log, DyFM_String } from '@futdevpro/fsm-dynamo';
|
|
4
|
-
|
|
5
|
-
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
1
|
+
import { ConnectOptions } from 'mongoose';
|
|
2
|
+
|
|
3
|
+
import { DyFM_Log, DyFM_String } from '@futdevpro/fsm-dynamo';
|
|
4
|
+
|
|
5
|
+
import { DyNTS_global_settings } from '../../_collections/global-settings.const';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* This will hold and set the basic settings of an application
|
|
@@ -84,11 +84,11 @@ export class DyNTS_App_Params {
|
|
|
84
84
|
this.dbUri = set.dbUri;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (this.dbUri.split('//').length > 2) {
|
|
88
|
-
DyFM_Log.warn(
|
|
89
|
-
'DyNTS_App_Params.constructor: dbUri should not contain more than one "//".'
|
|
90
|
-
);
|
|
91
|
-
}
|
|
87
|
+
if (this.dbUri.split('//').length > 2) {
|
|
88
|
+
DyFM_Log.warn(
|
|
89
|
+
'DyNTS_App_Params.constructor: dbUri should not contain more than one "//".'
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
92
|
|
|
93
93
|
this.dbOptions = set.dbOptions ?? {
|
|
94
94
|
directConnection: true,
|
|
@@ -20,7 +20,7 @@ export * from './errors/errors.controller';
|
|
|
20
20
|
export * from './errors/errors.control-service';
|
|
21
21
|
export * from './errors/errors.data-service';
|
|
22
22
|
|
|
23
|
-
// SERVER-STATUS
|
|
23
|
+
// SERVER-STATUS
|
|
24
24
|
export * from './server-status/db-readiness-probe-code.type-enum';
|
|
25
25
|
export * from './server-status/db-readiness-probe-stage.type-enum';
|
|
26
26
|
export * from './server-status/db-readiness-probe.interface';
|
|
@@ -28,13 +28,13 @@ export * from './server-status/db-readiness-probe.control-service';
|
|
|
28
28
|
export * from './server-status/server-status-snapshot.data-service';
|
|
29
29
|
export * from './server-status/server-status-snapshot.control-service';
|
|
30
30
|
export * from './server-status/server-status.control-service';
|
|
31
|
-
export * from './server-status/server-status.controller';
|
|
32
|
-
|
|
33
|
-
// SAFE-DIAGNOSTIC
|
|
34
|
-
export * from './safe-diagnostic/safe-diagnostic-cause.type-enum';
|
|
35
|
-
export * from './safe-diagnostic/safe-diagnostic-stage.type-enum';
|
|
36
|
-
export * from './safe-diagnostic/safe-diagnostic.interface';
|
|
37
|
-
export * from './safe-diagnostic/safe-diagnostic.control-service';
|
|
31
|
+
export * from './server-status/server-status.controller';
|
|
32
|
+
|
|
33
|
+
// SAFE-DIAGNOSTIC
|
|
34
|
+
export * from './safe-diagnostic/safe-diagnostic-cause.type-enum';
|
|
35
|
+
export * from './safe-diagnostic/safe-diagnostic-stage.type-enum';
|
|
36
|
+
export * from './safe-diagnostic/safe-diagnostic.interface';
|
|
37
|
+
export * from './safe-diagnostic/safe-diagnostic.control-service';
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/** Stable, content-free classifications for framework-owned failures. */
|
|
2
|
-
export enum DyNTS_SafeDiagnosticCause_Type {
|
|
3
|
-
dynamoError = 'dynamo-error',
|
|
4
|
-
nativeError = 'native-error',
|
|
5
|
-
object = 'object',
|
|
6
|
-
primitive = 'primitive',
|
|
7
|
-
unknown = 'unknown',
|
|
8
|
-
}
|
|
1
|
+
/** Stable, content-free classifications for framework-owned failures. */
|
|
2
|
+
export enum DyNTS_SafeDiagnosticCause_Type {
|
|
3
|
+
dynamoError = 'dynamo-error',
|
|
4
|
+
nativeError = 'native-error',
|
|
5
|
+
object = 'object',
|
|
6
|
+
primitive = 'primitive',
|
|
7
|
+
unknown = 'unknown',
|
|
8
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/** Framework stages that may emit a content-free diagnostic. */
|
|
2
|
-
export enum DyNTS_SafeDiagnosticStage_Type {
|
|
3
|
-
bootstrap = 'bootstrap',
|
|
4
|
-
collectionGrowthMonitor = 'collection-growth-monitor',
|
|
5
|
-
databaseConnect = 'database-connect',
|
|
6
|
-
databaseRuntime = 'database-runtime',
|
|
7
|
-
eventLoopDiagnostic = 'event-loop-diagnostic',
|
|
8
|
-
expressFallback = 'express-fallback',
|
|
9
|
-
globalErrorHandler = 'global-error-handler',
|
|
10
|
-
httpServer = 'http-server',
|
|
11
|
-
httpsServer = 'https-server',
|
|
12
|
-
memoryGuard = 'memory-guard',
|
|
13
|
-
mongoReconnectGuard = 'mongo-reconnect-guard',
|
|
14
|
-
postProcess = 'post-process',
|
|
15
|
-
readiness = 'readiness',
|
|
16
|
-
retention = 'retention',
|
|
17
|
-
routing = 'routing',
|
|
18
|
-
unhandledRejection = 'unhandled-rejection',
|
|
19
|
-
}
|
|
1
|
+
/** Framework stages that may emit a content-free diagnostic. */
|
|
2
|
+
export enum DyNTS_SafeDiagnosticStage_Type {
|
|
3
|
+
bootstrap = 'bootstrap',
|
|
4
|
+
collectionGrowthMonitor = 'collection-growth-monitor',
|
|
5
|
+
databaseConnect = 'database-connect',
|
|
6
|
+
databaseRuntime = 'database-runtime',
|
|
7
|
+
eventLoopDiagnostic = 'event-loop-diagnostic',
|
|
8
|
+
expressFallback = 'express-fallback',
|
|
9
|
+
globalErrorHandler = 'global-error-handler',
|
|
10
|
+
httpServer = 'http-server',
|
|
11
|
+
httpsServer = 'https-server',
|
|
12
|
+
memoryGuard = 'memory-guard',
|
|
13
|
+
mongoReconnectGuard = 'mongo-reconnect-guard',
|
|
14
|
+
postProcess = 'post-process',
|
|
15
|
+
readiness = 'readiness',
|
|
16
|
+
retention = 'retention',
|
|
17
|
+
routing = 'routing',
|
|
18
|
+
unhandledRejection = 'unhandled-rejection',
|
|
19
|
+
}
|