@futdevpro/nts-dynamo 1.15.154 → 1.15.156
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 +26 -22
- package/__documentations/2026-08-22-bfr-ctm-018-content-free-endpoint-errors.md +54 -0
- package/__documentations/2026-08-22-content-free-process-error-boundary.md +105 -85
- package/build/_collections/app-version-header.util.d.ts +41 -41
- package/build/_collections/app-version-header.util.js +66 -66
- package/build/_collections/archive-service-registry.const.d.ts +15 -15
- package/build/_collections/archive-service-registry.const.js +14 -14
- package/build/_collections/archive.util.d.ts +12 -12
- package/build/_collections/archive.util.js +18 -18
- package/build/_collections/atlas-default-db-options.const.d.ts +2 -2
- package/build/_collections/atlas-default-db-options.const.js +9 -9
- package/build/_collections/client-safe-error.util.d.ts +38 -38
- package/build/_collections/client-safe-error.util.js +96 -96
- package/build/_collections/default-fallback-cache-max-age.const.d.ts +2 -2
- package/build/_collections/default-fallback-cache-max-age.const.js +5 -5
- package/build/_collections/default-not-found-page.const.d.ts +5 -5
- package/build/_collections/default-not-found-page.const.js +24 -24
- package/build/_collections/default-socket-path.const.d.ts +2 -2
- package/build/_collections/default-socket-path.const.js +5 -5
- package/build/_collections/field-encryption.util.d.ts +85 -85
- package/build/_collections/field-encryption.util.js +192 -192
- package/build/_collections/get-environment-settings.util.d.ts +2 -2
- package/build/_collections/get-environment-settings.util.js +43 -43
- package/build/_collections/global-settings.const.d.ts +6 -6
- package/build/_collections/global-settings.const.js +104 -104
- package/build/_collections/load-shed.util.d.ts +15 -15
- package/build/_collections/load-shed.util.js +42 -42
- package/build/_collections/mongo-reconnect-guard.util.d.ts +73 -73
- package/build/_collections/mongo-reconnect-guard.util.js +110 -110
- package/build/_collections/npm-token-check.util.d.ts +138 -138
- package/build/_collections/npm-token-check.util.js +301 -301
- package/build/_collections/security-headers.util.d.ts +16 -16
- package/build/_collections/security-headers.util.js +77 -77
- package/build/_collections/signed-url.util.d.ts +84 -84
- package/build/_collections/signed-url.util.js +145 -145
- package/build/_collections/star.controller.d.ts +7 -7
- package/build/_collections/star.controller.js +97 -97
- package/build/_collections/static-cache-control.util.d.ts +17 -17
- package/build/_collections/static-cache-control.util.js +23 -23
- package/build/_enums/data-model-type.enum.d.ts +13 -13
- package/build/_enums/data-model-type.enum.js +17 -17
- package/build/_enums/data-service-function.enum.d.ts +18 -18
- package/build/_enums/data-service-function.enum.js +24 -24
- package/build/_enums/predefined-data-types.enum.d.ts +15 -15
- package/build/_enums/predefined-data-types.enum.js +19 -19
- package/build/_enums/route-security.enum.d.ts +11 -11
- package/build/_enums/route-security.enum.js +15 -15
- package/build/_models/control-models/api-call-params.control-model.d.ts +79 -79
- package/build/_models/control-models/api-call-params.control-model.js +101 -101
- package/build/_models/control-models/app-ext-system-controls.control-model.d.ts +6 -6
- package/build/_models/control-models/app-ext-system-controls.control-model.js +10 -10
- package/build/_models/control-models/app-params.control-model.d.ts +51 -51
- package/build/_models/control-models/app-params.control-model.js +118 -118
- package/build/_models/control-models/app-system-controls.control-model.d.ts +7 -7
- package/build/_models/control-models/app-system-controls.control-model.js +11 -11
- package/build/_models/control-models/endpoint-params.control-model.d.ts +125 -119
- package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
- package/build/_models/control-models/endpoint-params.control-model.js +409 -484
- package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
- package/build/_models/control-models/http-settings.control-model.d.ts +17 -17
- package/build/_models/control-models/http-settings.control-model.js +34 -34
- package/build/_models/control-models/system-control.control-model.d.ts +5 -5
- package/build/_models/control-models/system-control.control-model.js +11 -11
- package/build/_models/data-models/schema-migration.data-model.d.ts +28 -28
- package/build/_models/data-models/schema-migration.data-model.js +46 -46
- package/build/_models/interfaces/app-version-header-settings.interface.d.ts +16 -16
- package/build/_models/interfaces/app-version-header-settings.interface.js +2 -2
- package/build/_models/interfaces/certification-settings.interface.d.ts +5 -5
- package/build/_models/interfaces/certification-settings.interface.js +2 -2
- package/build/_models/interfaces/compare-data-options.interface.d.ts +26 -26
- package/build/_models/interfaces/compare-data-options.interface.js +2 -2
- package/build/_models/interfaces/compare-data-result.interface.d.ts +12 -12
- package/build/_models/interfaces/compare-data-result.interface.js +2 -2
- package/build/_models/interfaces/cors-settings.interface.d.ts +51 -51
- package/build/_models/interfaces/cors-settings.interface.js +2 -2
- package/build/_models/interfaces/db-query-options.interface.d.ts +32 -32
- package/build/_models/interfaces/db-query-options.interface.js +2 -2
- package/build/_models/interfaces/environment-settings.interface.d.ts +34 -34
- package/build/_models/interfaces/environment-settings.interface.js +2 -2
- package/build/_models/interfaces/global-log-settings.interface.d.ts +145 -145
- package/build/_models/interfaces/global-log-settings.interface.js +2 -2
- package/build/_models/interfaces/global-service-settings.interface.d.ts +30 -30
- package/build/_models/interfaces/global-service-settings.interface.js +2 -2
- package/build/_models/interfaces/global-settings.interface.d.ts +265 -265
- package/build/_models/interfaces/global-settings.interface.js +2 -2
- package/build/_models/interfaces/migration-entry.interface.d.ts +19 -19
- package/build/_models/interfaces/migration-entry.interface.js +2 -2
- package/build/_models/interfaces/mongo-transaction-settings.interface.d.ts +8 -8
- package/build/_models/interfaces/mongo-transaction-settings.interface.js +2 -2
- package/build/_models/interfaces/routing-module-settings.interface.d.ts +19 -19
- package/build/_models/interfaces/routing-module-settings.interface.js +2 -2
- package/build/_models/interfaces/security-headers-settings.interface.d.ts +41 -41
- package/build/_models/interfaces/security-headers-settings.interface.js +2 -2
- package/build/_models/interfaces/signed-url-verify-result.interface.d.ts +13 -13
- package/build/_models/interfaces/signed-url-verify-result.interface.js +2 -2
- package/build/_models/interfaces/static-client-settings.interface.d.ts +36 -36
- package/build/_models/interfaces/static-client-settings.interface.js +2 -2
- package/build/_models/types/db-update.type.d.ts +129 -129
- package/build/_models/types/db-update.type.js +2 -2
- package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.d.ts +5 -5
- package/build/_modules/account-security/_enums/account-challenge-purpose.type-enum.js +9 -9
- package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.d.ts +6 -6
- package/build/_modules/account-security/_enums/account-refresh-token-state.type-enum.js +10 -10
- package/build/_modules/account-security/_enums/account-session-state.type-enum.d.ts +6 -6
- package/build/_modules/account-security/_enums/account-session-state.type-enum.js +10 -10
- package/build/_modules/account-security/_models/account-challenge-adapter.interface.d.ts +8 -8
- package/build/_modules/account-security/_models/account-challenge-adapter.interface.js +2 -2
- package/build/_modules/account-security/_models/account-challenge-issued.interface.d.ts +6 -6
- package/build/_modules/account-security/_models/account-challenge-issued.interface.js +2 -2
- package/build/_modules/account-security/_models/account-challenge-record.interface.d.ts +12 -12
- package/build/_modules/account-security/_models/account-challenge-record.interface.js +2 -2
- package/build/_modules/account-security/_models/account-challenge-result.interface.d.ts +7 -7
- package/build/_modules/account-security/_models/account-challenge-result.interface.js +2 -2
- package/build/_modules/account-security/_models/account-challenge-settings.interface.d.ts +8 -8
- package/build/_modules/account-security/_models/account-challenge-settings.interface.js +2 -2
- package/build/_modules/account-security/_models/account-password-policy.interface.d.ts +11 -11
- package/build/_modules/account-security/_models/account-password-policy.interface.js +2 -2
- package/build/_modules/account-security/_models/account-password-verification.interface.d.ts +5 -5
- package/build/_modules/account-security/_models/account-password-verification.interface.js +2 -2
- package/build/_modules/account-security/_models/account-refresh-token-record.interface.d.ts +12 -12
- package/build/_modules/account-security/_models/account-refresh-token-record.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-adapter.interface.d.ts +18 -18
- package/build/_modules/account-security/_models/account-session-adapter.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-claims.interface.d.ts +7 -7
- package/build/_modules/account-security/_models/account-session-claims.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-context.interface.d.ts +6 -6
- package/build/_modules/account-security/_models/account-session-context.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-create.interface.d.ts +7 -7
- package/build/_modules/account-security/_models/account-session-create.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-record.interface.d.ts +20 -20
- package/build/_modules/account-security/_models/account-session-record.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-rotate.interface.d.ts +10 -10
- package/build/_modules/account-security/_models/account-session-rotate.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-settings.interface.d.ts +10 -10
- package/build/_modules/account-security/_models/account-session-settings.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-token-pair.interface.d.ts +8 -8
- package/build/_modules/account-security/_models/account-session-token-pair.interface.js +2 -2
- package/build/_modules/account-security/_models/account-session-view.interface.d.ts +12 -12
- package/build/_modules/account-security/_models/account-session-view.interface.js +2 -2
- package/build/_modules/account-security/account-challenge.control-service.d.ts +23 -23
- package/build/_modules/account-security/account-challenge.control-service.js +116 -116
- package/build/_modules/account-security/account-password.control-service.d.ts +23 -23
- package/build/_modules/account-security/account-password.control-service.js +213 -213
- package/build/_modules/account-security/account-session.control-service.d.ts +38 -38
- package/build/_modules/account-security/account-session.control-service.js +276 -276
- package/build/_modules/account-security/index.d.ts +23 -23
- package/build/_modules/account-security/index.js +15 -15
- package/build/_modules/admin-auth/_models/admin-api-key-config.interface.d.ts +31 -31
- package/build/_modules/admin-auth/_models/admin-api-key-config.interface.js +2 -2
- package/build/_modules/admin-auth/admin-api-key.auth-service.d.ts +89 -89
- package/build/_modules/admin-auth/admin-api-key.auth-service.js +194 -194
- package/build/_modules/admin-auth/index.d.ts +2 -2
- package/build/_modules/admin-auth/index.js +5 -5
- package/build/_modules/ai/_collections/ai-model-config-validator.util.d.ts +31 -31
- package/build/_modules/ai/_collections/ai-model-config-validator.util.js +94 -94
- package/build/_modules/ai/_collections/ai-provider-error.util.d.ts +43 -43
- package/build/_modules/ai/_collections/ai-provider-error.util.js +120 -120
- package/build/_modules/ai/_models/ai-input-interfaces.d.ts +53 -53
- package/build/_modules/ai/_models/ai-input-interfaces.js +5 -5
- package/build/_modules/ai/_models/ai-test-generation-result.interface.d.ts +16 -16
- package/build/_modules/ai/_models/ai-test-generation-result.interface.js +2 -2
- package/build/_modules/ai/_models/interfaces/dynts-ai-cost-event-callback.interface.d.ts +13 -13
- package/build/_modules/ai/_models/interfaces/dynts-ai-cost-event-callback.interface.js +2 -2
- package/build/_modules/ai/_models/interfaces/dynts-ai-cost-event.interface.d.ts +49 -49
- package/build/_modules/ai/_models/interfaces/dynts-ai-cost-event.interface.js +2 -2
- package/build/_modules/ai/_models/interfaces/dynts-ai-provider-error.interface.d.ts +16 -16
- package/build/_modules/ai/_models/interfaces/dynts-ai-provider-error.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-default-collection.util.d.ts +22 -22
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-default-collection.util.js +51 -51
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-match.util.d.ts +33 -33
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-match.util.js +55 -55
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.d.ts +40 -40
- package/build/_modules/ai/_modules/ai-mock/_collections/aim-fixture-serializer.util.js +89 -89
- package/build/_modules/ai/_modules/ai-mock/_enums/aim-modality.enum.d.ts +27 -27
- package/build/_modules/ai/_modules/ai-mock/_enums/aim-modality.enum.js +28 -28
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-call-input.interface.d.ts +14 -14
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-call-input.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-error.interface.d.ts +10 -10
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-error.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-fixture.interface.d.ts +29 -29
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-fixture.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-request.interface.d.ts +18 -18
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-request.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-service-collection.interface.d.ts +18 -18
- package/build/_modules/ai/_modules/ai-mock/_models/interfaces/aim-service-collection.interface.js +2 -2
- package/build/_modules/ai/_modules/ai-mock/_services/ai-embedding-mock.service.d.ts +80 -80
- package/build/_modules/ai/_modules/ai-mock/_services/ai-embedding-mock.service.js +166 -166
- package/build/_modules/ai/_modules/ai-mock/_services/aim-fixture-harness.service.d.ts +47 -47
- package/build/_modules/ai/_modules/ai-mock/_services/aim-fixture-harness.service.js +103 -103
- package/build/_modules/ai/_modules/ai-mock/_services/aim-fixture-store.service.d.ts +34 -34
- package/build/_modules/ai/_modules/ai-mock/_services/aim-fixture-store.service.js +59 -59
- package/build/_modules/ai/_modules/ai-mock/_services/aim-mock.service.d.ts +73 -73
- package/build/_modules/ai/_modules/ai-mock/_services/aim-mock.service.js +133 -133
- package/build/_modules/ai/_modules/ai-mock/fixtures/aim-text.fixtures.d.ts +8 -8
- package/build/_modules/ai/_modules/ai-mock/fixtures/aim-text.fixtures.js +650 -650
- package/build/_modules/ai/_modules/ai-mock/index.d.ts +14 -14
- package/build/_modules/ai/_modules/ai-mock/index.js +42 -42
- package/build/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.d.ts +35 -35
- package/build/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.js +117 -117
- package/build/_modules/ai/_modules/anthropic/index.d.ts +2 -2
- package/build/_modules/ai/_modules/anthropic/index.js +7 -7
- package/build/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.d.ts +84 -84
- package/build/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.js +467 -467
- package/build/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.d.ts +109 -109
- package/build/_modules/ai/_modules/document-ai/_collections/dai-code-chunking.util.js +418 -418
- package/build/_modules/ai/_modules/document-ai/_collections/dai-document.util.d.ts +28 -28
- package/build/_modules/ai/_modules/document-ai/_collections/dai-document.util.js +73 -73
- package/build/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.d.ts +6 -6
- package/build/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.js +10 -10
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.d.ts +51 -51
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.js +132 -132
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.d.ts +47 -47
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.js +136 -136
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.d.ts +17 -17
- package/build/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.js +76 -76
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-code-chunk.interface.d.ts +49 -49
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-code-chunk.interface.js +2 -2
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.d.ts +8 -8
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.js +2 -2
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.d.ts +11 -11
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.js +2 -2
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.d.ts +12 -12
- package/build/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.js +2 -2
- package/build/_modules/ai/_modules/document-ai/index.d.ts +12 -12
- package/build/_modules/ai/_modules/document-ai/index.js +27 -27
- package/build/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.d.ts +34 -34
- package/build/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.js +128 -128
- package/build/_modules/ai/_modules/fdp-ai/index.d.ts +2 -2
- package/build/_modules/ai/_modules/fdp-ai/index.js +7 -7
- package/build/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.d.ts +2 -2
- package/build/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.js +8 -8
- package/build/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.d.ts +2 -2
- package/build/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.js +74 -74
- package/build/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.d.ts +2 -2
- package/build/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.js +67 -67
- package/build/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.js +42 -42
- package/build/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.d.ts +5 -5
- package/build/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.js +2 -2
- package/build/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.js +6 -6
- package/build/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.d.ts +51 -51
- package/build/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.js +2 -2
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.d.ts +21 -21
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.js +187 -187
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-page.data-service.d.ts +26 -26
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-page.data-service.js +278 -278
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.d.ts +22 -22
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.js +322 -322
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.d.ts +119 -119
- package/build/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.js +480 -480
- package/build/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.d.ts +25 -25
- package/build/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.js +103 -103
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.d.ts +169 -169
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.js +479 -479
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.d.ts +229 -229
- package/build/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.js +617 -617
- package/build/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.d.ts +39 -39
- package/build/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.js +110 -110
- package/build/_modules/ai/_modules/open-ai/index.d.ts +14 -14
- package/build/_modules/ai/_modules/open-ai/index.js +55 -55
- package/build/_modules/ai/_services/ai-embedding-provider.registry.d.ts +51 -51
- package/build/_modules/ai/_services/ai-embedding-provider.registry.js +78 -78
- package/build/_modules/ai/_services/ai-embedding.service-base.d.ts +41 -41
- package/build/_modules/ai/_services/ai-embedding.service-base.js +11 -11
- package/build/_modules/ai/_services/ai-llm-chat.service-base.d.ts +39 -39
- package/build/_modules/ai/_services/ai-llm-chat.service-base.js +11 -11
- package/build/_modules/ai/_services/ai-llm.service-base.d.ts +148 -148
- package/build/_modules/ai/_services/ai-llm.service-base.js +378 -378
- package/build/_modules/ai/_services/ai-provider.service-base.d.ts +46 -46
- package/build/_modules/ai/_services/ai-provider.service-base.js +43 -43
- package/build/_modules/ai/_services/ai-user-key.service-base.d.ts +44 -44
- package/build/_modules/ai/_services/ai-user-key.service-base.js +14 -14
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.d.ts +110 -110
- package/build/_modules/ai/_services/lmstudio-embedding.control-service.js +297 -297
- package/build/_modules/ai/index.d.ts +16 -16
- package/build/_modules/ai/index.js +30 -30
- package/build/_modules/artifact-compiler/_enums/artifact-compile-outcome.type-enum.d.ts +5 -5
- package/build/_modules/artifact-compiler/_enums/artifact-compile-outcome.type-enum.js +9 -9
- package/build/_modules/artifact-compiler/_enums/artifact-compile-stage.type-enum.d.ts +8 -8
- package/build/_modules/artifact-compiler/_enums/artifact-compile-stage.type-enum.js +12 -12
- package/build/_modules/artifact-compiler/_enums/artifact-retry-class.type-enum.d.ts +6 -6
- package/build/_modules/artifact-compiler/_enums/artifact-retry-class.type-enum.js +10 -10
- package/build/_modules/artifact-compiler/_models/artifact-compile.interface.d.ts +32 -32
- package/build/_modules/artifact-compiler/_models/artifact-compile.interface.js +2 -2
- package/build/_modules/artifact-compiler/artifact-compiler.control-service.d.ts +36 -36
- package/build/_modules/artifact-compiler/artifact-compiler.control-service.js +273 -273
- package/build/_modules/artifact-compiler/index.d.ts +5 -5
- package/build/_modules/artifact-compiler/index.js +11 -11
- package/build/_modules/assistant/_collections/ass-global-settings.const.d.ts +2 -2
- package/build/_modules/assistant/_collections/ass-global-settings.const.js +14 -14
- package/build/_modules/assistant/_collections/ass.util.d.ts +15 -15
- package/build/_modules/assistant/_collections/ass.util.js +42 -42
- package/build/_modules/assistant/_models/ass-global-settings.interface.d.ts +13 -13
- package/build/_modules/assistant/_models/ass-global-settings.interface.js +2 -2
- package/build/_modules/assistant/_services/ass-io.control-service.d.ts +19 -19
- package/build/_modules/assistant/_services/ass-io.control-service.js +57 -57
- package/build/_modules/assistant/_services/ass-main.control-service.d.ts +32 -32
- package/build/_modules/assistant/_services/ass-main.control-service.js +65 -65
- package/build/_modules/assistant/index.d.ts +6 -6
- package/build/_modules/assistant/index.js +18 -18
- package/build/_modules/bot/_collections/bot-default-commands.const.d.ts +2 -2
- package/build/_modules/bot/_collections/bot-default-commands.const.js +13 -13
- package/build/_modules/bot/_collections/bot-global-settings.const.d.ts +2 -2
- package/build/_modules/bot/_collections/bot-global-settings.const.js +31 -31
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.d.ts +25 -25
- package/build/_modules/bot/_models/bot-channel-wrapper.interface.js +38 -38
- package/build/_modules/bot/_models/bot-command.interface.d.ts +7 -7
- package/build/_modules/bot/_models/bot-command.interface.js +2 -2
- package/build/_modules/bot/_models/bot-global-settings.interface.d.ts +85 -85
- package/build/_modules/bot/_models/bot-global-settings.interface.js +2 -2
- package/build/_modules/bot/_models/bot-last-mention-date.interface.d.ts +6 -6
- package/build/_modules/bot/_models/bot-last-mention-date.interface.js +2 -2
- package/build/_modules/bot/_models/bot-last-message-date.interface.d.ts +5 -5
- package/build/_modules/bot/_models/bot-last-message-date.interface.js +2 -2
- package/build/_modules/bot/_models/bot-message-wrapper.interface.d.ts +37 -37
- package/build/_modules/bot/_models/bot-message-wrapper.interface.js +54 -54
- package/build/_modules/bot/_models/bot-user-wrapper.interface.d.ts +23 -23
- package/build/_modules/bot/_models/bot-user-wrapper.interface.js +28 -28
- package/build/_modules/bot/_modules/discord-bot/_models/dib-platform.types.js +10 -10
- package/build/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.d.ts +69 -69
- package/build/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.js +497 -497
- package/build/_modules/bot/_modules/discord-bot/index.d.ts +1 -1
- package/build/_modules/bot/_modules/discord-bot/index.js +12 -12
- package/build/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.d.ts +16 -16
- package/build/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.js +42 -42
- package/build/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.d.ts +9 -9
- package/build/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.js +2 -2
- package/build/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.d.ts +59 -59
- package/build/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.js +349 -349
- package/build/_modules/bot/_modules/dynamo-bot/index.d.ts +3 -3
- package/build/_modules/bot/_modules/dynamo-bot/index.js +15 -15
- package/build/_modules/bot/_modules/slack-bot/_models/slb-platform.types.d.ts +6 -6
- package/build/_modules/bot/_modules/slack-bot/_models/slb-platform.types.js +2 -2
- package/build/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.d.ts +56 -56
- package/build/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.js +137 -137
- package/build/_modules/bot/_modules/slack-bot/index.d.ts +2 -2
- package/build/_modules/bot/_modules/slack-bot/index.js +12 -12
- package/build/_modules/bot/_modules/teams-bot/_models/teb-platform.types.d.ts +6 -6
- package/build/_modules/bot/_modules/teams-bot/_models/teb-platform.types.js +2 -2
- package/build/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.d.ts +56 -56
- package/build/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.js +137 -137
- package/build/_modules/bot/_modules/teams-bot/index.d.ts +2 -2
- package/build/_modules/bot/_modules/teams-bot/index.js +12 -12
- package/build/_modules/bot/_services/bot-commands.control-service.d.ts +12 -12
- package/build/_modules/bot/_services/bot-commands.control-service.js +117 -117
- package/build/_modules/bot/_services/bot-io.control-service.d.ts +23 -23
- package/build/_modules/bot/_services/bot-io.control-service.js +226 -226
- package/build/_modules/bot/_services/bot-main.control-service.d.ts +35 -35
- package/build/_modules/bot/_services/bot-main.control-service.js +195 -195
- package/build/_modules/bot/_services/bot-messaging-provider.service-base.d.ts +71 -71
- package/build/_modules/bot/_services/bot-messaging-provider.service-base.js +15 -15
- package/build/_modules/bot/_services/bot-routines.control-service.d.ts +13 -13
- package/build/_modules/bot/_services/bot-routines.control-service.js +59 -59
- package/build/_modules/bot/index.d.ts +17 -17
- package/build/_modules/bot/index.js +36 -36
- package/build/_modules/custom-data/custom-data.controller.d.ts +5 -5
- package/build/_modules/custom-data/custom-data.controller.js +56 -56
- package/build/_modules/custom-data/custom-data.data-service.d.ts +5 -5
- package/build/_modules/custom-data/custom-data.data-service.js +11 -11
- package/build/_modules/custom-data/get-custom-data-routing-module.util.d.ts +3 -3
- package/build/_modules/custom-data/get-custom-data-routing-module.util.js +16 -16
- package/build/_modules/custom-data/index.d.ts +4 -4
- package/build/_modules/custom-data/index.js +9 -9
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.d.ts +58 -58
- package/build/_modules/data-readers/_collections/dynts-sqlite-reader.util.js +168 -168
- package/build/_modules/data-readers/_models/interfaces/dynts-sqlite-reader.interface.d.ts +31 -31
- package/build/_modules/data-readers/_models/interfaces/dynts-sqlite-reader.interface.js +7 -7
- package/build/_modules/data-readers/index.d.ts +2 -2
- package/build/_modules/data-readers/index.js +10 -10
- package/build/_modules/defaults/_collections/default-endpoints.util.d.ts +248 -248
- package/build/_modules/defaults/_collections/default-endpoints.util.js +386 -386
- package/build/_modules/defaults/_models/default-user.data-model.d.ts +19 -19
- package/build/_modules/defaults/_models/default-user.data-model.js +72 -72
- package/build/_modules/defaults/_services/default-auth.service.d.ts +50 -50
- package/build/_modules/defaults/_services/default-auth.service.js +158 -158
- package/build/_modules/defaults/_services/default-socket-events.service.d.ts +23 -23
- package/build/_modules/defaults/_services/default-socket-events.service.js +60 -60
- package/build/_modules/defaults/_services/default-user.data-service.d.ts +24 -24
- package/build/_modules/defaults/_services/default-user.data-service.js +87 -87
- package/build/_modules/defaults/index.d.ts +5 -5
- package/build/_modules/defaults/index.js +17 -17
- package/build/_modules/discord-assistant/_collections/dias-global-settings.const.d.ts +2 -2
- package/build/_modules/discord-assistant/_collections/dias-global-settings.const.js +16 -16
- package/build/_modules/discord-assistant/_collections/dias.util.d.ts +31 -31
- package/build/_modules/discord-assistant/_collections/dias.util.js +85 -85
- package/build/_modules/discord-assistant/_models/dias-global-settings.interface.d.ts +17 -17
- package/build/_modules/discord-assistant/_models/dias-global-settings.interface.js +2 -2
- package/build/_modules/discord-assistant/_models/dias-knowledge.data-model.d.ts +8 -8
- package/build/_modules/discord-assistant/_models/dias-knowledge.data-model.js +46 -46
- package/build/_modules/discord-assistant/_services/dias-chunk.data-service.d.ts +17 -17
- package/build/_modules/discord-assistant/_services/dias-chunk.data-service.js +123 -123
- package/build/_modules/discord-assistant/_services/dias-io.control-service.d.ts +10 -10
- package/build/_modules/discord-assistant/_services/dias-io.control-service.js +49 -49
- package/build/_modules/discord-assistant/_services/dias-main.control-service.d.ts +3 -3
- package/build/_modules/discord-assistant/_services/dias-main.control-service.js +7 -7
- package/build/_modules/discord-assistant/_services/dias.service-base.d.ts +18 -18
- package/build/_modules/discord-assistant/_services/dias.service-base.js +46 -46
- package/build/_modules/discord-assistant/index.d.ts +11 -11
- package/build/_modules/discord-assistant/index.js +24 -24
- package/build/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.d.ts +3 -3
- package/build/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.js +7 -7
- package/build/_modules/discord-assistant-voiced/index.d.ts +2 -2
- package/build/_modules/discord-assistant-voiced/index.js +28 -28
- package/build/_modules/discord-bot/_collections/dibo-default-commands.const.d.ts +2 -2
- package/build/_modules/discord-bot/_collections/dibo-default-commands.const.js +12 -12
- package/build/_modules/discord-bot/_collections/dibo-global-settings.conts.d.ts +2 -2
- package/build/_modules/discord-bot/_collections/dibo-global-settings.conts.js +43 -43
- package/build/_modules/discord-bot/_collections/dibo-operations.util.d.ts +22 -22
- package/build/_modules/discord-bot/_collections/dibo-operations.util.js +275 -275
- package/build/_modules/discord-bot/_models/dibo-command.interface.d.ts +7 -7
- package/build/_modules/discord-bot/_models/dibo-command.interface.js +2 -2
- package/build/_modules/discord-bot/_models/dibo-global-settings.interface.d.ts +87 -87
- package/build/_modules/discord-bot/_models/dibo-global-settings.interface.js +2 -2
- package/build/_modules/discord-bot/_models/dibo-last-mention-date.inteface.d.ts +6 -6
- package/build/_modules/discord-bot/_models/dibo-last-mention-date.inteface.js +2 -2
- package/build/_modules/discord-bot/_models/dibo-last-message-date.interface.d.ts +5 -5
- package/build/_modules/discord-bot/_models/dibo-last-message-date.interface.js +2 -2
- package/build/_modules/discord-bot/_services/dibo-commands.control-service.d.ts +11 -11
- package/build/_modules/discord-bot/_services/dibo-commands.control-service.js +109 -109
- package/build/_modules/discord-bot/_services/dibo-io.control-service.d.ts +21 -21
- package/build/_modules/discord-bot/_services/dibo-io.control-service.js +218 -218
- package/build/_modules/discord-bot/_services/dibo-main.control-service.d.ts +89 -89
- package/build/_modules/discord-bot/_services/dibo-main.control-service.js +363 -363
- package/build/_modules/discord-bot/_services/dibo-routines.control-service.d.ts +13 -13
- package/build/_modules/discord-bot/_services/dibo-routines.control-service.js +73 -73
- package/build/_modules/discord-bot/index.d.ts +11 -11
- package/build/_modules/discord-bot/index.js +30 -30
- package/build/_modules/local-vector-search/_enums/lvs-search-mode.enum.d.ts +34 -34
- package/build/_modules/local-vector-search/_enums/lvs-search-mode.enum.js +38 -38
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.d.ts +35 -35
- package/build/_modules/local-vector-search/_models/data-models/lvs-vector-persist.data-model.js +53 -53
- package/build/_modules/local-vector-search/_models/lvs-search-result.interface.d.ts +16 -16
- package/build/_modules/local-vector-search/_models/lvs-search-result.interface.js +2 -2
- package/build/_modules/local-vector-search/_services/lvs-bm25.util.d.ts +88 -88
- package/build/_modules/local-vector-search/_services/lvs-bm25.util.js +189 -189
- package/build/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.d.ts +26 -26
- package/build/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.js +197 -197
- package/build/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.d.ts +145 -145
- package/build/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.js +294 -294
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.d.ts +74 -74
- package/build/_modules/local-vector-search/_services/lvs-persistent-vector-pool.control-service.js +152 -152
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.d.ts +51 -51
- package/build/_modules/local-vector-search/_services/lvs-vector-persist.data-service.js +83 -83
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.d.ts +99 -99
- package/build/_modules/local-vector-search/_services/lvs-vector-pool.control-service.js +276 -276
- package/build/_modules/local-vector-search/index.d.ts +8 -8
- package/build/_modules/local-vector-search/index.js +15 -15
- package/build/_modules/logs/_models/file-log-entry.interface.d.ts +13 -13
- package/build/_modules/logs/_models/file-log-entry.interface.js +2 -2
- package/build/_modules/logs/_models/file-log-read-result.interface.d.ts +35 -35
- package/build/_modules/logs/_models/file-log-read-result.interface.js +2 -2
- package/build/_modules/logs/file-log.service.d.ts +132 -132
- package/build/_modules/logs/file-log.service.js +444 -444
- package/build/_modules/logs/file-logs.controller.d.ts +40 -40
- package/build/_modules/logs/file-logs.controller.js +138 -138
- package/build/_modules/logs/get-file-logs-routing-module.util.d.ts +31 -31
- package/build/_modules/logs/get-file-logs-routing-module.util.js +37 -37
- package/build/_modules/logs/get-logs-routing-module.util.d.ts +18 -18
- package/build/_modules/logs/get-logs-routing-module.util.js +31 -31
- package/build/_modules/logs/index.d.ts +8 -8
- package/build/_modules/logs/index.js +15 -15
- package/build/_modules/logs/log-buffer.service.d.ts +37 -37
- package/build/_modules/logs/log-buffer.service.js +96 -96
- package/build/_modules/logs/logs.controller.d.ts +26 -26
- package/build/_modules/logs/logs.controller.js +89 -89
- package/build/_modules/logs/logs.service.d.ts +39 -39
- package/build/_modules/logs/logs.service.js +96 -96
- package/build/_modules/mcp/_models/interfaces/dynts-mcp.interface.d.ts +108 -108
- package/build/_modules/mcp/_models/interfaces/dynts-mcp.interface.js +13 -13
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.d.ts +70 -70
- package/build/_modules/mcp/_services/dynts-mcp-server.service-base.js +98 -98
- package/build/_modules/mcp/_services/dynts-mcp.adapter.d.ts +56 -56
- package/build/_modules/mcp/_services/dynts-mcp.adapter.js +138 -138
- package/build/_modules/mcp/index.d.ts +3 -3
- package/build/_modules/mcp/index.js +12 -12
- package/build/_modules/messaging/_collections/get-messaging-routing-module.util.d.ts +7 -7
- package/build/_modules/messaging/_collections/get-messaging-routing-module.util.js +20 -20
- package/build/_modules/messaging/_collections/msg-global-settings.const.d.ts +5 -5
- package/build/_modules/messaging/_collections/msg-global-settings.const.js +22 -22
- package/build/_modules/messaging/_collections/msg.util.d.ts +24 -24
- package/build/_modules/messaging/_collections/msg.util.js +62 -62
- package/build/_modules/messaging/_models/msg-global-settings.interface.d.ts +28 -28
- package/build/_modules/messaging/_models/msg-global-settings.interface.js +2 -2
- package/build/_modules/messaging/_services/msg-conversation.data-service.d.ts +28 -28
- package/build/_modules/messaging/_services/msg-conversation.data-service.js +109 -109
- package/build/_modules/messaging/_services/msg-events.service.d.ts +61 -61
- package/build/_modules/messaging/_services/msg-events.service.js +203 -203
- package/build/_modules/messaging/_services/msg-integration.control-service.js +180 -180
- package/build/_modules/messaging/_services/msg-main.control-service.d.ts +62 -62
- package/build/_modules/messaging/_services/msg-main.control-service.js +428 -428
- package/build/_modules/messaging/_services/msg-message.data-service.d.ts +28 -28
- package/build/_modules/messaging/_services/msg-message.data-service.js +103 -103
- package/build/_modules/messaging/_services/msg.controller.d.ts +12 -12
- package/build/_modules/messaging/_services/msg.controller.js +256 -256
- package/build/_modules/messaging/index.d.ts +10 -10
- package/build/_modules/messaging/index.js +27 -27
- package/build/_modules/mock/app-extended-server.mock.d.ts +41 -41
- package/build/_modules/mock/app-extended-server.mock.js +169 -169
- package/build/_modules/mock/app-integration-test.mock.d.ts +19 -19
- package/build/_modules/mock/app-integration-test.mock.js +45 -45
- package/build/_modules/mock/app-params.mock.d.ts +2 -2
- package/build/_modules/mock/app-params.mock.js +9 -9
- package/build/_modules/mock/app-server.mock.d.ts +41 -41
- package/build/_modules/mock/app-server.mock.js +148 -148
- package/build/_modules/mock/auth-service.mock.d.ts +10 -10
- package/build/_modules/mock/auth-service.mock.js +19 -19
- package/build/_modules/mock/controller.mock.d.ts +5 -5
- package/build/_modules/mock/controller.mock.js +14 -14
- package/build/_modules/mock/data-model.mock.d.ts +26 -26
- package/build/_modules/mock/data-model.mock.js +72 -72
- package/build/_modules/mock/email-service-collection.mock.d.ts +7 -7
- package/build/_modules/mock/email-service-collection.mock.js +12 -12
- package/build/_modules/mock/email-service.mock.d.ts +4 -4
- package/build/_modules/mock/email-service.mock.js +20 -20
- package/build/_modules/mock/endpoint.mock.d.ts +8 -8
- package/build/_modules/mock/endpoint.mock.js +79 -79
- package/build/_modules/mock/socket-client.mock.d.ts +9 -9
- package/build/_modules/mock/socket-client.mock.js +38 -38
- package/build/_modules/mock/socket-server.mock.d.ts +15 -15
- package/build/_modules/mock/socket-server.mock.js +32 -32
- package/build/_modules/oauth2/_routes/oauth2.controller.d.ts +16 -16
- package/build/_modules/oauth2/_routes/oauth2.controller.js +96 -96
- package/build/_modules/oauth2/_services/oauth2.auth-service.d.ts +30 -30
- package/build/_modules/oauth2/_services/oauth2.auth-service.js +215 -215
- package/build/_modules/oauth2/_services/oauth2.control-service.d.ts +132 -132
- package/build/_modules/oauth2/_services/oauth2.control-service.js +576 -576
- package/build/_modules/oauth2/index.d.ts +3 -3
- package/build/_modules/oauth2/index.js +14 -14
- package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.d.ts +5 -5
- package/build/_modules/privacy-lifecycle/_enums/privacy-consent-decision.type-enum.js +9 -9
- package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.d.ts +10 -10
- package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-action.type-enum.js +14 -14
- package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.d.ts +7 -7
- package/build/_modules/privacy-lifecycle/_enums/privacy-contributor-outcome.type-enum.js +11 -11
- package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.d.ts +15 -15
- package/build/_modules/privacy-lifecycle/_enums/privacy-request-state.type-enum.js +19 -19
- package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.d.ts +9 -9
- package/build/_modules/privacy-lifecycle/_enums/privacy-request.type-enum.js +13 -13
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.d.ts +11 -11
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-input.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-persistence-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.d.ts +14 -14
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-record.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.d.ts +12 -12
- package/build/_modules/privacy-lifecycle/_models/privacy-consent-view.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.d.ts +8 -8
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-context.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.d.ts +13 -13
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-outcome.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.d.ts +7 -7
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor-plan.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.d.ts +10 -10
- package/build/_modules/privacy-lifecycle/_models/privacy-contributor.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.d.ts +12 -12
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-adapter.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.d.ts +8 -8
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-ledger-settings.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.d.ts +10 -10
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-input.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-persistence-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.d.ts +11 -11
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance-view.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.d.ts +13 -13
- package/build/_modules/privacy-lifecycle/_models/privacy-legal-acceptance.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.d.ts +14 -14
- package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-adapter.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.d.ts +8 -8
- package/build/_modules/privacy-lifecycle/_models/privacy-lifecycle-settings.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-request-create-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.d.ts +9 -9
- package/build/_modules/privacy-lifecycle/_models/privacy-request-open.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.d.ts +6 -6
- package/build/_modules/privacy-lifecycle/_models/privacy-request-persistence-create-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.d.ts +20 -20
- package/build/_modules/privacy-lifecycle/_models/privacy-request-record.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.d.ts +7 -7
- package/build/_modules/privacy-lifecycle/_models/privacy-request-result.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.d.ts +19 -19
- package/build/_modules/privacy-lifecycle/_models/privacy-request-view.interface.js +2 -2
- package/build/_modules/privacy-lifecycle/index.d.ts +32 -32
- package/build/_modules/privacy-lifecycle/index.js +17 -17
- package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.d.ts +27 -27
- package/build/_modules/privacy-lifecycle/privacy-ledger.control-service.js +167 -167
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.d.ts +41 -41
- package/build/_modules/privacy-lifecycle/privacy-lifecycle.control-service.js +363 -363
- package/build/_modules/rate-limit/_enums/rate-limit-store-kind.type-enum.d.ts +5 -5
- package/build/_modules/rate-limit/_enums/rate-limit-store-kind.type-enum.js +9 -9
- package/build/_modules/rate-limit/_models/rate-limit-config.interface.d.ts +70 -70
- package/build/_modules/rate-limit/_models/rate-limit-config.interface.js +2 -2
- package/build/_modules/rate-limit/_models/rate-limit-consume-request.interface.d.ts +8 -8
- package/build/_modules/rate-limit/_models/rate-limit-consume-request.interface.js +2 -2
- package/build/_modules/rate-limit/_models/rate-limit-consume-result.interface.d.ts +6 -6
- package/build/_modules/rate-limit/_models/rate-limit-consume-result.interface.js +2 -2
- package/build/_modules/rate-limit/_models/rate-limit-policy.interface.d.ts +15 -15
- package/build/_modules/rate-limit/_models/rate-limit-policy.interface.js +2 -2
- package/build/_modules/rate-limit/_models/rate-limit-store.interface.d.ts +8 -8
- package/build/_modules/rate-limit/_models/rate-limit-store.interface.js +2 -2
- package/build/_modules/rate-limit/index.d.ts +8 -8
- package/build/_modules/rate-limit/index.js +9 -9
- package/build/_modules/rate-limit/rate-limit-in-memory.store.d.ts +18 -18
- package/build/_modules/rate-limit/rate-limit-in-memory.store.js +70 -70
- package/build/_modules/rate-limit/rate-limit.middleware.d.ts +68 -68
- package/build/_modules/rate-limit/rate-limit.middleware.js +378 -378
- package/build/_modules/scheduler/_models/scheduler-job.interface.d.ts +33 -33
- package/build/_modules/scheduler/_models/scheduler-job.interface.js +2 -2
- package/build/_modules/scheduler/get-scheduler-routing-module.util.d.ts +17 -17
- package/build/_modules/scheduler/get-scheduler-routing-module.util.js +30 -30
- package/build/_modules/scheduler/index.d.ts +4 -4
- package/build/_modules/scheduler/index.js +9 -9
- package/build/_modules/scheduler/scheduler.controller.d.ts +24 -24
- package/build/_modules/scheduler/scheduler.controller.js +53 -53
- package/build/_modules/scheduler/scheduler.service.d.ts +53 -53
- package/build/_modules/scheduler/scheduler.service.js +163 -163
- package/build/_modules/scoped-config/_enums/dynts-scoped-config-level.enum.d.ts +18 -18
- package/build/_modules/scoped-config/_enums/dynts-scoped-config-level.enum.js +22 -22
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.d.ts +43 -43
- package/build/_modules/scoped-config/_models/data-models/dynts-scoped-config.data-model.js +67 -67
- package/build/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.d.ts +88 -88
- package/build/_modules/scoped-config/_models/interfaces/dynts-scoped-config.interface.js +11 -11
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.d.ts +83 -83
- package/build/_modules/scoped-config/_services/dynts-scoped-config.control-service.js +219 -219
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.d.ts +53 -53
- package/build/_modules/scoped-config/_services/dynts-scoped-config.data-service.js +75 -75
- package/build/_modules/scoped-config/index.d.ts +5 -5
- package/build/_modules/scoped-config/index.js +14 -14
- package/build/_modules/server/errors/errors.control-service.d.ts +21 -21
- package/build/_modules/server/errors/errors.control-service.js +10 -10
- package/build/_modules/server/errors/errors.controller.d.ts +144 -144
- package/build/_modules/server/errors/errors.controller.js +404 -404
- package/build/_modules/server/errors/errors.data-service.d.ts +70 -70
- package/build/_modules/server/errors/errors.data-service.js +677 -677
- package/build/_modules/server/index.d.ts +15 -15
- package/build/_modules/server/index.js +35 -35
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.d.ts +8 -8
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-cause.type-enum.js +12 -12
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts +20 -19
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.d.ts.map +1 -1
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js +24 -23
- package/build/_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum.js.map +1 -1
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.d.ts +18 -18
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.control-service.js +82 -82
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.d.ts +18 -18
- package/build/_modules/server/safe-diagnostic/safe-diagnostic.interface.js +2 -2
- package/build/_modules/server/server-status/db-readiness-probe-code.type-enum.d.ts +13 -13
- package/build/_modules/server/server-status/db-readiness-probe-code.type-enum.js +17 -17
- package/build/_modules/server/server-status/db-readiness-probe-stage.type-enum.d.ts +7 -7
- package/build/_modules/server/server-status/db-readiness-probe-stage.type-enum.js +11 -11
- package/build/_modules/server/server-status/db-readiness-probe.control-service.d.ts +13 -13
- package/build/_modules/server/server-status/db-readiness-probe.control-service.js +125 -125
- package/build/_modules/server/server-status/db-readiness-probe.interface.d.ts +17 -17
- package/build/_modules/server/server-status/db-readiness-probe.interface.js +2 -2
- package/build/_modules/server/server-status/server-status-snapshot.control-service.d.ts +4 -4
- package/build/_modules/server/server-status/server-status-snapshot.control-service.js +7 -7
- package/build/_modules/server/server-status/server-status-snapshot.data-service.d.ts +6 -6
- package/build/_modules/server/server-status/server-status-snapshot.data-service.js +22 -22
- package/build/_modules/server/server-status/server-status.control-service.d.ts +111 -111
- package/build/_modules/server/server-status/server-status.control-service.js +302 -302
- package/build/_modules/server/server-status/server-status.controller.d.ts +92 -92
- package/build/_modules/server/server-status/server-status.controller.js +253 -253
- package/build/_modules/socket/_enums/socket-security.enum.d.ts +10 -10
- package/build/_modules/socket/_enums/socket-security.enum.js +14 -14
- package/build/_modules/socket/_models/socket-client-service-params.control-model.d.ts +8 -8
- package/build/_modules/socket/_models/socket-client-service-params.control-model.js +16 -16
- package/build/_modules/socket/_models/socket-presence.control-model.d.ts +25 -25
- package/build/_modules/socket/_models/socket-presence.control-model.js +140 -140
- package/build/_modules/socket/_models/socket-server-service-params.control-model.d.ts +22 -22
- package/build/_modules/socket/_models/socket-server-service-params.control-model.js +31 -31
- package/build/_modules/socket/_services/socket-client.service.d.ts +37 -37
- package/build/_modules/socket/_services/socket-client.service.js +196 -196
- package/build/_modules/socket/_services/socket-server.service.d.ts +98 -98
- package/build/_modules/socket/_services/socket-server.service.js +673 -673
- package/build/_modules/socket/app-extended.server.d.ts +145 -145
- package/build/_modules/socket/app-extended.server.js +521 -521
- package/build/_modules/socket/index.d.ts +8 -8
- package/build/_modules/socket/index.js +35 -35
- package/build/_modules/test/get-test-routing-module.util.d.ts +3 -3
- package/build/_modules/test/get-test-routing-module.util.js +16 -16
- package/build/_modules/test/index.d.ts +3 -3
- package/build/_modules/test/index.js +11 -11
- package/build/_modules/test/test.controller.d.ts +5 -5
- package/build/_modules/test/test.controller.js +103 -103
- package/build/_modules/test-email-sink/_collections/test-email-pattern.const.d.ts +10 -10
- package/build/_modules/test-email-sink/_collections/test-email-pattern.const.js +13 -13
- package/build/_modules/test-email-sink/_models/data-models/dynts-sent-test-mail.data-model.d.ts +21 -21
- package/build/_modules/test-email-sink/_models/data-models/dynts-sent-test-mail.data-model.js +38 -38
- package/build/_modules/test-email-sink/_services/dynts-test-email-sink.service.d.ts +49 -49
- package/build/_modules/test-email-sink/_services/dynts-test-email-sink.service.js +117 -117
- package/build/_modules/test-email-sink/get-sent-mail-routing-module.util.d.ts +14 -14
- package/build/_modules/test-email-sink/get-sent-mail-routing-module.util.js +26 -26
- package/build/_modules/test-email-sink/index.d.ts +11 -11
- package/build/_modules/test-email-sink/index.js +14 -14
- package/build/_modules/test-email-sink/test-email-sink.controller.d.ts +23 -23
- package/build/_modules/test-email-sink/test-email-sink.controller.js +66 -66
- package/build/_modules/usage/get-usage-routing-module.util.d.ts +3 -3
- package/build/_modules/usage/get-usage-routing-module.util.js +16 -16
- package/build/_modules/usage/index.d.ts +4 -4
- package/build/_modules/usage/index.js +13 -13
- package/build/_modules/usage/usage.controller.d.ts +6 -6
- package/build/_modules/usage/usage.controller.js +105 -105
- package/build/_modules/usage/usage.data-service.d.ts +17 -17
- package/build/_modules/usage/usage.data-service.js +135 -135
- package/build/_services/base/api.service-base.d.ts +9 -9
- package/build/_services/base/api.service-base.js +46 -46
- package/build/_services/base/archive-data.service.d.ts +25 -25
- package/build/_services/base/archive-data.service.js +151 -151
- package/build/_services/base/data.service.d.ts +402 -402
- package/build/_services/base/data.service.js +2131 -2131
- package/build/_services/base/db.service.d.ts +424 -424
- package/build/_services/base/db.service.js +1356 -1356
- package/build/_services/base/singleton.service-base.d.ts +8 -8
- package/build/_services/base/singleton.service-base.js +21 -21
- package/build/_services/base/singleton.service.d.ts +11 -11
- package/build/_services/base/singleton.service.js +31 -31
- package/build/_services/core/api.service.d.ts +45 -45
- package/build/_services/core/api.service.js +456 -456
- package/build/_services/core/auth.service.d.ts +129 -129
- package/build/_services/core/auth.service.js +59 -59
- package/build/_services/core/collection-growth-monitor.service.d.ts +76 -76
- package/build/_services/core/collection-growth-monitor.service.js +165 -165
- package/build/_services/core/db-stats.service.d.ts +33 -33
- package/build/_services/core/db-stats.service.js +64 -64
- package/build/_services/core/diagnostics.service.d.ts +42 -42
- package/build/_services/core/diagnostics.service.js +121 -121
- package/build/_services/core/email.service.d.ts +77 -77
- package/build/_services/core/email.service.js +503 -503
- package/build/_services/core/event-loop-diag.service.d.ts +49 -49
- package/build/_services/core/event-loop-diag.service.js +106 -106
- package/build/_services/core/global.service.d.ts +83 -83
- package/build/_services/core/global.service.js +386 -386
- package/build/_services/core/memory-guard.service.d.ts +166 -166
- package/build/_services/core/memory-guard.service.js +369 -369
- package/build/_services/core/migration-runner.service.d.ts +39 -39
- package/build/_services/core/migration-runner.service.js +74 -74
- package/build/_services/core/mongo-transaction.control-service.d.ts +18 -18
- package/build/_services/core/mongo-transaction.control-service.js +94 -94
- package/build/_services/core/request-hunter.service.d.ts +73 -73
- package/build/_services/core/request-hunter.service.js +122 -122
- package/build/_services/core/service-collection.service.d.ts +4 -4
- package/build/_services/core/service-collection.service.js +7 -7
- package/build/_services/route/controller.service.d.ts +124 -124
- package/build/_services/route/controller.service.js +95 -95
- package/build/_services/route/routing-module.service.d.ts +80 -80
- package/build/_services/route/routing-module.service.js +250 -250
- package/build/_services/server/app.server.d.ts +429 -429
- package/build/_services/server/app.server.js +1226 -1226
- package/build/_services/shared.static-service.d.ts +43 -36
- package/build/_services/shared.static-service.d.ts.map +1 -1
- package/build/_services/shared.static-service.js +92 -72
- package/build/_services/shared.static-service.js.map +1 -1
- package/build/index.d.ts +63 -63
- package/build/index.js +101 -101
- 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/_models/control-models/endpoint-params.control-model.spec.ts +102 -17
- package/src/_models/control-models/endpoint-params.control-model.ts +131 -220
- 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 +18 -17
- 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 +43 -9
- package/src/_services/shared.static-service.ts +37 -8
|
@@ -1,1227 +1,1227 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DyNTS_App = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const Mongoose = require("mongoose");
|
|
6
|
-
const Express = require("express");
|
|
7
|
-
/* import Mongoose from 'mongoose';
|
|
8
|
-
import Express from 'express'; */
|
|
9
|
-
const BodyParser = tslib_1.__importStar(require("body-parser"));
|
|
10
|
-
const FileSystem = tslib_1.__importStar(require("fs"));
|
|
11
|
-
const Https = tslib_1.__importStar(require("https"));
|
|
12
|
-
const Path = tslib_1.__importStar(require("path"));
|
|
13
|
-
/* import { version } from '../../../package.json'; */
|
|
14
|
-
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
15
|
-
const default_fallback_cache_max_age_const_1 = require("../../_collections/default-fallback-cache-max-age.const");
|
|
16
|
-
const default_not_found_page_const_1 = require("../../_collections/default-not-found-page.const");
|
|
17
|
-
const global_settings_const_1 = require("../../_collections/global-settings.const");
|
|
18
|
-
const client_safe_error_util_1 = require("../../_collections/client-safe-error.util");
|
|
19
|
-
const get_environment_settings_util_1 = require("../../_collections/get-environment-settings.util");
|
|
20
|
-
const security_headers_util_1 = require("../../_collections/security-headers.util");
|
|
21
|
-
const load_shed_util_1 = require("../../_collections/load-shed.util");
|
|
22
|
-
const app_version_header_util_1 = require("../../_collections/app-version-header.util");
|
|
23
|
-
const mongo_reconnect_guard_util_1 = require("../../_collections/mongo-reconnect-guard.util");
|
|
24
|
-
const static_cache_control_util_1 = require("../../_collections/static-cache-control.util");
|
|
25
|
-
const route_security_enum_1 = require("../../_enums/route-security.enum");
|
|
26
|
-
const app_system_controls_control_model_1 = require("../../_models/control-models/app-system-controls.control-model");
|
|
27
|
-
const http_settings_control_model_1 = require("../../_models/control-models/http-settings.control-model");
|
|
28
|
-
const singleton_service_1 = require("../base/singleton.service");
|
|
29
|
-
const global_service_1 = require("../core/global.service");
|
|
30
|
-
const collection_growth_monitor_service_1 = require("../core/collection-growth-monitor.service");
|
|
31
|
-
const memory_guard_service_1 = require("../core/memory-guard.service");
|
|
32
|
-
const event_loop_diag_service_1 = require("../core/event-loop-diag.service");
|
|
33
|
-
const safe_diagnostic_stage_type_enum_1 = require("../../_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum");
|
|
34
|
-
const safe_diagnostic_control_service_1 = require("../../_modules/server/safe-diagnostic/safe-diagnostic.control-service");
|
|
35
|
-
class DyNTS_App extends singleton_service_1.DyNTS_SingletonService {
|
|
36
|
-
systemControls = new app_system_controls_control_model_1.DyNTS_AppSystemControls();
|
|
37
|
-
get started() {
|
|
38
|
-
return this.systemControls.app.started;
|
|
39
|
-
}
|
|
40
|
-
get superStarted() {
|
|
41
|
-
return this.systemControls.app.started;
|
|
42
|
-
}
|
|
43
|
-
constructErrors = [];
|
|
44
|
-
/* removed since cant use version from package.json
|
|
45
|
-
private readonly _ntsVersion: string = 'v01.07.18';
|
|
46
|
-
protected get ntsVersion(): string {
|
|
47
|
-
return this._ntsVersion;
|
|
48
|
-
} */
|
|
49
|
-
get serverName() {
|
|
50
|
-
return this.params.name;
|
|
51
|
-
}
|
|
52
|
-
_params;
|
|
53
|
-
get params() {
|
|
54
|
-
return this._params;
|
|
55
|
-
}
|
|
56
|
-
mongoose = Mongoose;
|
|
57
|
-
_security;
|
|
58
|
-
get security() {
|
|
59
|
-
return this._security;
|
|
60
|
-
}
|
|
61
|
-
_portSettings = new http_settings_control_model_1.DyNTS_Http_Settings();
|
|
62
|
-
get portSettings() {
|
|
63
|
-
return this._portSettings;
|
|
64
|
-
}
|
|
65
|
-
_cert;
|
|
66
|
-
get cert() {
|
|
67
|
-
return this._cert;
|
|
68
|
-
}
|
|
69
|
-
openExpress;
|
|
70
|
-
secureExpress;
|
|
71
|
-
httpsServer;
|
|
72
|
-
httpServer;
|
|
73
|
-
globalService;
|
|
74
|
-
_rootServices = [];
|
|
75
|
-
_routingModules = [];
|
|
76
|
-
defaultReadyTimeout = 30 * fsm_dynamo_1.second;
|
|
77
|
-
defaultErrorUserMsg = `We encountered an unhandled Server Error, ` +
|
|
78
|
-
`\nplease contact the responsible development team.` +
|
|
79
|
-
`\n(Internal Server error)`;
|
|
80
|
-
get logSetup() {
|
|
81
|
-
return global_settings_const_1.DyNTS_global_settings.log_settings.setup;
|
|
82
|
-
}
|
|
83
|
-
get deepLog() {
|
|
84
|
-
return global_settings_const_1.DyNTS_global_settings.log_settings.deep;
|
|
85
|
-
}
|
|
86
|
-
get fnLogs() {
|
|
87
|
-
return global_settings_const_1.DyNTS_global_settings.log_settings.functions;
|
|
88
|
-
}
|
|
89
|
-
debugLog = global_settings_const_1.DyNTS_global_settings.log_settings.server_debug;
|
|
90
|
-
reportSafeDiagnostic(code, stage, error, status = 500) {
|
|
91
|
-
const configuredPrefix = global_settings_const_1.DyNTS_global_settings.systemShortCodeName;
|
|
92
|
-
const prefix = configuredPrefix && /^[A-Z][A-Z0-9_-]{1,31}$/.test(configuredPrefix)
|
|
93
|
-
? configuredPrefix
|
|
94
|
-
: 'DYNTS';
|
|
95
|
-
return safe_diagnostic_control_service_1.DyNTS_SafeDiagnostic_ControlService.report({
|
|
96
|
-
code: `${prefix}|${code}`,
|
|
97
|
-
stage: stage,
|
|
98
|
-
error: error,
|
|
99
|
-
status: status,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
forwardSafeDiagnostic(diagnostic) {
|
|
103
|
-
try {
|
|
104
|
-
const pending = global_service_1.DyNTS_GlobalService.globalErrorHandler?.(safe_diagnostic_control_service_1.DyNTS_SafeDiagnostic_ControlService.toError(diagnostic));
|
|
105
|
-
void pending?.catch((error) => {
|
|
106
|
-
this.reportSafeDiagnostic('DYNTS-AS0-GLOBAL-HANDLER-REJECTED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.globalErrorHandler, error);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch (error) {
|
|
110
|
-
this.reportSafeDiagnostic('DYNTS-AS0-GLOBAL-HANDLER-THREW', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.globalErrorHandler, error);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
constructor( /* extended?: boolean */) {
|
|
114
|
-
super();
|
|
115
|
-
/* dotenv.config() */
|
|
116
|
-
process.on('unhandledRejection', (reason) => {
|
|
117
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-BASE-UR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.unhandledRejection, reason);
|
|
118
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
119
|
-
});
|
|
120
|
-
this.asyncConstruct( /* extended */).catch((error) => {
|
|
121
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-BOOTSTRAP-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.bootstrap, error);
|
|
122
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
123
|
-
process.exit(1);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
async asyncConstruct(extended) {
|
|
127
|
-
if (this.fnLogs && this.deepLog)
|
|
128
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. asyncConstruct');
|
|
129
|
-
try {
|
|
130
|
-
this.systemControls.app.init = true;
|
|
131
|
-
this._params = this.getAppParams();
|
|
132
|
-
fsm_dynamo_1.DyFM_Log.log(`\n\n\n\n\n\n\n\n\n\n` +
|
|
133
|
-
`Starting ${this._params?.name}... ` +
|
|
134
|
-
/* `v${version}` + */
|
|
135
|
-
`\n\n\n\n\n\n\n\n\n\n`);
|
|
136
|
-
if (!this._params) {
|
|
137
|
-
throw new Error('getAppParams() must return a DyNTS_AppParams object!');
|
|
138
|
-
}
|
|
139
|
-
if (this.params.systemShortCodeName) {
|
|
140
|
-
global_settings_const_1.DyNTS_global_settings.systemShortCodeName = this.params.systemShortCodeName;
|
|
141
|
-
}
|
|
142
|
-
if (this.params.systemName) {
|
|
143
|
-
global_settings_const_1.DyNTS_global_settings.systemName = this.params.systemName;
|
|
144
|
-
fsm_dynamo_1.DyFM_error_defaults.issuerSystem = this.params.systemName;
|
|
145
|
-
}
|
|
146
|
-
if (this.params.version) {
|
|
147
|
-
global_settings_const_1.DyNTS_global_settings.systemVersion = this.params.version;
|
|
148
|
-
fsm_dynamo_1.DyFM_error_defaults.systemVersion = this.params.version;
|
|
149
|
-
}
|
|
150
|
-
process.stdout.write(String.fromCharCode(27) + ']0;' +
|
|
151
|
-
this._params?.name +
|
|
152
|
-
String.fromCharCode(7));
|
|
153
|
-
fsm_dynamo_1.DyFM_error_defaults.issuerSystem = this._params.systemName;
|
|
154
|
-
this.overrideDynamoNTSGlobalSettings?.();
|
|
155
|
-
if (global_settings_const_1.DyNTS_global_settings.log_settings.setup) {
|
|
156
|
-
fsm_dynamo_1.DyFM_Log.S_info(`env settings;\n`, {
|
|
157
|
-
systemName: global_settings_const_1.DyNTS_global_settings.systemName,
|
|
158
|
-
systemShortCodeName: global_settings_const_1.DyNTS_global_settings.systemShortCodeName,
|
|
159
|
-
systemVersion: global_settings_const_1.DyNTS_global_settings.systemVersion,
|
|
160
|
-
environment: global_settings_const_1.DyNTS_global_settings.env_settings.environment,
|
|
161
|
-
/* log_settings: DyNTS_global_settings.log_settings,
|
|
162
|
-
env_settings: DyNTS_global_settings.env_settings, */
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
this.globalService = global_service_1.DyNTS_GlobalService.getInstance();
|
|
166
|
-
await global_service_1.DyNTS_GlobalService.setServices(this.getGlobalServiceCollection());
|
|
167
|
-
global_service_1.DyNTS_GlobalService.setParams(this.params);
|
|
168
|
-
if (this.getPortSettings) {
|
|
169
|
-
this._portSettings = this.getPortSettings();
|
|
170
|
-
}
|
|
171
|
-
if (this.getCertificationSettings) {
|
|
172
|
-
this._cert = this.getCertificationSettings();
|
|
173
|
-
}
|
|
174
|
-
if (this.getApiBasePath) {
|
|
175
|
-
global_settings_const_1.DyNTS_global_settings.baseUrl = this.getApiBasePath();
|
|
176
|
-
}
|
|
177
|
-
if (this.getRoutingModules) {
|
|
178
|
-
this._routingModules = this.getRoutingModules();
|
|
179
|
-
// ezt egyelőre csak tesztelem, nem kerül be
|
|
180
|
-
/* if (
|
|
181
|
-
!DyNTS_global_settings.dontCreateDefaultRoute &&
|
|
182
|
-
!this._routingModules.some((routingModule: DyNTS_RoutingModule): boolean => routingModule.route === '/*')
|
|
183
|
-
) {
|
|
184
|
-
this._routingModules.push(
|
|
185
|
-
DyNTS_getStarRoute()
|
|
186
|
-
);
|
|
187
|
-
} */
|
|
188
|
-
}
|
|
189
|
-
if (this._params.dbUri) {
|
|
190
|
-
await this.startDB();
|
|
191
|
-
// createEntries csak akkor fut, ha a DB tényleg fel-jött.
|
|
192
|
-
// Ha a startDB jelezte a hibát, de továbbment, akkor a started flag false marad,
|
|
193
|
-
// és nem próbálunk meg írni egy nem létező kapcsolatra.
|
|
194
|
-
if (this.createEntries && this.systemControls.mongoose.started) {
|
|
195
|
-
await this.createEntries();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
fsm_dynamo_1.DyFM_Log.log(`\nNo database connection created.`);
|
|
200
|
-
}
|
|
201
|
-
if (this._routingModules?.length) {
|
|
202
|
-
if (this.logSetup)
|
|
203
|
-
fsm_dynamo_1.DyFM_Log.log('\nsetting up express routes...');
|
|
204
|
-
this.setSecurity();
|
|
205
|
-
await this.initExpresses();
|
|
206
|
-
await this.startExpresses();
|
|
207
|
-
if (this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
208
|
-
await this.mountOpenRoutes();
|
|
209
|
-
}
|
|
210
|
-
if (this._security !== route_security_enum_1.DyNTS_RouteSecurity.open && this._cert) {
|
|
211
|
-
await this.mountSecureRoutes();
|
|
212
|
-
}
|
|
213
|
-
// Generikus, auth-agnosztikus extension-point: custom middleware az API
|
|
214
|
-
// route-ok UTÁN, de a SPA static catch-all (mountStaticClient) ELŐTT.
|
|
215
|
-
await this.mountCustomMiddleware();
|
|
216
|
-
await this.mountStaticClient();
|
|
217
|
-
if (this.logSetup) {
|
|
218
|
-
fsm_dynamo_1.DyFM_Log.log(`\nRoutes mounted.... server using security: ${this._security}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
fsm_dynamo_1.DyFM_Log.warn(`\nNo routes mounted!`);
|
|
223
|
-
}
|
|
224
|
-
if (this.getRootServices) {
|
|
225
|
-
this._rootServices = await this.getRootServices();
|
|
226
|
-
}
|
|
227
|
-
if (this.postProcess) {
|
|
228
|
-
await this.postProcess().catch((error) => {
|
|
229
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-POST-PROCESS-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.postProcess, error);
|
|
230
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
// FR-193 — bedrock OOM korai-figyelmeztetés: feltelepítjük a heap-watchdogot, ha
|
|
234
|
-
// engedélyezve (DyNTS_global_settings.memoryGuard.enabled, default true). Biztonságos:
|
|
235
|
-
// a guard egy könnyű setInterval, ami SOHA nem dob; csak near-OOM küszöböknél hagy
|
|
236
|
-
// tartós nyomot az error-sinkbe, mielőtt a fatal heap-OOM megölné a process-t.
|
|
237
|
-
try {
|
|
238
|
-
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.enabled) {
|
|
239
|
-
memory_guard_service_1.DyNTS_MemoryGuard.getInstance().install();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
catch (memoryGuardError) {
|
|
243
|
-
this.reportSafeDiagnostic('DYNTS-AS0-MEMORY-GUARD-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.memoryGuard, memoryGuardError);
|
|
244
|
-
}
|
|
245
|
-
// BFR-OVERSEER-007 — event-loop-lag diag a MemoryGuard MELLÉ: a „process él, HTTP néma" wedge
|
|
246
|
-
// belső mérése (natív histogram, olcsó). Observation-only, sosem dob; a /server/diag olvas belőle.
|
|
247
|
-
try {
|
|
248
|
-
event_loop_diag_service_1.DyNTS_EventLoopDiag.getInstance().install();
|
|
249
|
-
}
|
|
250
|
-
catch (eventLoopDiagError) {
|
|
251
|
-
this.reportSafeDiagnostic('DYNTS-AS0-EVENT-LOOP-DIAG-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.eventLoopDiagnostic, eventLoopDiagError);
|
|
252
|
-
}
|
|
253
|
-
// FR-258 / SR-4 — proactive collection-growth monitor (companion to the MemoryGuard). Warns
|
|
254
|
-
// into the Errors-sink when a collection grows unbounded, BEFORE it can be loaded into heap and
|
|
255
|
-
// OOM. Default-on, observation-only, never throws.
|
|
256
|
-
try {
|
|
257
|
-
if (global_settings_const_1.DyNTS_global_settings.collectionGrowthMonitor?.enabled) {
|
|
258
|
-
collection_growth_monitor_service_1.DyNTS_CollectionGrowthMonitor.getInstance().install();
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
catch (cgmError) {
|
|
262
|
-
this.reportSafeDiagnostic('DYNTS-AS0-COLLECTION-GROWTH-MONITOR-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.collectionGrowthMonitor, cgmError);
|
|
263
|
-
}
|
|
264
|
-
if (!extended) {
|
|
265
|
-
await this.ready();
|
|
266
|
-
if (this.params.title) {
|
|
267
|
-
fsm_dynamo_1.DyFM_Log.success(this.params.title);
|
|
268
|
-
}
|
|
269
|
-
fsm_dynamo_1.DyFM_Log.info(`Version: ${this.params.version}`);
|
|
270
|
-
/* DyFM_Log.info(`NTS Version: ${this.ntsVersion}`); */
|
|
271
|
-
fsm_dynamo_1.DyFM_Log.H_success(`${this.params.name} started successfully.`);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
catch (error) {
|
|
275
|
-
this.constructErrors.push(error);
|
|
276
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
277
|
-
...this._getDefaultErrorSettings('asyncConstruct', error),
|
|
278
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-001`,
|
|
279
|
-
additionalContent: {
|
|
280
|
-
constructErrors: this.constructErrors,
|
|
281
|
-
systemControls: this.systemControls,
|
|
282
|
-
systemReadies: {
|
|
283
|
-
app: this.systemControls.app.getIsReady(),
|
|
284
|
-
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
285
|
-
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
286
|
-
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
287
|
-
},
|
|
288
|
-
},
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
async ready(timeout = this.defaultReadyTimeout) {
|
|
293
|
-
try {
|
|
294
|
-
if (this.fnLogs)
|
|
295
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. ready');
|
|
296
|
-
await fsm_dynamo_1.DyFM_Async.delay(100);
|
|
297
|
-
let ready = false;
|
|
298
|
-
const start = +new Date();
|
|
299
|
-
if (this.constructErrors.length) {
|
|
300
|
-
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-CONSTRUCT-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0]);
|
|
301
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
302
|
-
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed.`)),
|
|
303
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R01`,
|
|
304
|
-
additionalContent: this.constructErrors.length === 1 ?
|
|
305
|
-
{ error: this.constructErrors[0] } :
|
|
306
|
-
{ errors: this.constructErrors },
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
while (!ready && +new Date() - start < timeout) {
|
|
310
|
-
if (this.systemControls.app.init) {
|
|
311
|
-
ready = (this.systemControls.mongoose.getIsReady() &&
|
|
312
|
-
this.systemControls.httpServer.getIsReady() &&
|
|
313
|
-
this.systemControls.httpsServer.getIsReady());
|
|
314
|
-
}
|
|
315
|
-
if (!ready) {
|
|
316
|
-
await fsm_dynamo_1.DyFM_Async.wait(100);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (timeout < +new Date() - start) {
|
|
320
|
-
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-TIMEOUT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0] ?? new Error('readiness-timeout'));
|
|
321
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
322
|
-
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed. TIMEOUT`)),
|
|
323
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R02`,
|
|
324
|
-
additionalContent: {
|
|
325
|
-
constructErrors: this.constructErrors,
|
|
326
|
-
systemControls: this.systemControls,
|
|
327
|
-
systemReadies: {
|
|
328
|
-
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
329
|
-
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
330
|
-
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
if (this.constructErrors.length) {
|
|
336
|
-
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-LATE-CONSTRUCT-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0]);
|
|
337
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
338
|
-
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed.`)),
|
|
339
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R03`,
|
|
340
|
-
additionalContent: this.constructErrors,
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
if (ready) {
|
|
344
|
-
this.systemControls.app.started = true;
|
|
345
|
-
if (this.fnLogs && this.deepLog)
|
|
346
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. ready: return');
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
this.systemControls.app.started = false;
|
|
350
|
-
let msg = `"${this._params.name}" start failed. UNKNOWN`;
|
|
351
|
-
if (this.systemControls.mongoose.init && !this.systemControls.mongoose.started) {
|
|
352
|
-
msg += `\nMongoose start failed.`;
|
|
353
|
-
}
|
|
354
|
-
if (this.systemControls.httpServer.init && !this.systemControls.httpServer.started) {
|
|
355
|
-
msg += `\nHTTP Server start failed.`;
|
|
356
|
-
}
|
|
357
|
-
if (this.systemControls.httpsServer.init && !this.systemControls.httpsServer.started) {
|
|
358
|
-
msg += `\nHTTPS Server start failed.`;
|
|
359
|
-
}
|
|
360
|
-
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-UNKNOWN', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0] ?? new Error('readiness-unknown'));
|
|
361
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
362
|
-
...this._getDefaultErrorSettings('ready', new Error(msg)),
|
|
363
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R04`,
|
|
364
|
-
additionalContent: {
|
|
365
|
-
constructErrors: this.constructErrors,
|
|
366
|
-
systemControls: this.systemControls,
|
|
367
|
-
systemReadies: {
|
|
368
|
-
app: this.systemControls.app.getIsReady(),
|
|
369
|
-
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
370
|
-
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
371
|
-
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
372
|
-
},
|
|
373
|
-
},
|
|
374
|
-
error: this.constructErrors?.[0] ?? new Error(),
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
catch (error) {
|
|
378
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
379
|
-
...this._getDefaultErrorSettings('ready', error),
|
|
380
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-READY0`,
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
getSimplifiedConstructErrors() {
|
|
385
|
-
return this.constructErrors.map((error) => {
|
|
386
|
-
if (error instanceof fsm_dynamo_1.DyFM_Error) {
|
|
387
|
-
return error.getErrorSimplified();
|
|
388
|
-
}
|
|
389
|
-
else {
|
|
390
|
-
return error;
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
async stop(dontLog) {
|
|
395
|
-
try {
|
|
396
|
-
fsm_dynamo_1.DyFM_Log.info('\nstopping server...\n');
|
|
397
|
-
await this.ready();
|
|
398
|
-
if (this.started) {
|
|
399
|
-
if (this.systemControls.mongoose.init) {
|
|
400
|
-
fsm_dynamo_1.DyFM_Log.info(`\nstopping Mongoose....`);
|
|
401
|
-
let tryCount = 0;
|
|
402
|
-
while (!this.systemControls.mongoose.started &&
|
|
403
|
-
!this.constructErrors.length &&
|
|
404
|
-
tryCount++ < 10) {
|
|
405
|
-
fsm_dynamo_1.DyFM_Log.warn(`Mongoose not even started yet....`);
|
|
406
|
-
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
407
|
-
}
|
|
408
|
-
this.systemControls.mongoose.started = false;
|
|
409
|
-
if (this.mongoose) {
|
|
410
|
-
await fsm_dynamo_1.DyFM_Array.asyncForEach(Object.keys(this.mongoose.models), async (modelName) => {
|
|
411
|
-
this.mongoose.deleteModel(modelName);
|
|
412
|
-
});
|
|
413
|
-
const disconnect = new Promise((resolve) => {
|
|
414
|
-
this.mongoose.connection.on('disconnecting', () => {
|
|
415
|
-
resolve();
|
|
416
|
-
});
|
|
417
|
-
});
|
|
418
|
-
await this.mongoose.disconnect();
|
|
419
|
-
await this.mongoose.connection.close();
|
|
420
|
-
await disconnect;
|
|
421
|
-
this.mongoose.connection.removeAllListeners();
|
|
422
|
-
while (this.mongoose.connection.readyState !== 0 &&
|
|
423
|
-
!this.constructErrors.length) {
|
|
424
|
-
fsm_dynamo_1.DyFM_Log.warn(`\nMongoose still not disconnected....`);
|
|
425
|
-
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
fsm_dynamo_1.DyFM_Log.error(`\nMongoose not found.`);
|
|
430
|
-
}
|
|
431
|
-
this.systemControls.mongoose.init = false;
|
|
432
|
-
}
|
|
433
|
-
if (this.systemControls.httpServer.init) {
|
|
434
|
-
this.systemControls.httpServer.started = false;
|
|
435
|
-
if (this.httpServer) {
|
|
436
|
-
await new Promise((resolve) => {
|
|
437
|
-
this.httpServer.close(resolve);
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
fsm_dynamo_1.DyFM_Log.error(`\nHTTP Server not found.`);
|
|
442
|
-
}
|
|
443
|
-
this.systemControls.httpServer.init = false;
|
|
444
|
-
}
|
|
445
|
-
if (this.systemControls.httpsServer.init) {
|
|
446
|
-
this.systemControls.httpsServer.started = false;
|
|
447
|
-
if (this.httpsServer) {
|
|
448
|
-
await new Promise((resolve) => {
|
|
449
|
-
this.httpsServer.close(resolve);
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
fsm_dynamo_1.DyFM_Log.error(`\nHTTPS Server not found.`);
|
|
454
|
-
}
|
|
455
|
-
this.systemControls.httpsServer.init = false;
|
|
456
|
-
}
|
|
457
|
-
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
458
|
-
if (!dontLog) {
|
|
459
|
-
fsm_dynamo_1.DyFM_Log.H_log(`"${this._params.name}" stopped successfully.`);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
catch (error) {
|
|
464
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
465
|
-
...this._getDefaultErrorSettings('stop', error),
|
|
466
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-STOP0`,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
*
|
|
472
|
-
*/
|
|
473
|
-
async startDB() {
|
|
474
|
-
if (this.fnLogs && this.deepLog)
|
|
475
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. startDB');
|
|
476
|
-
else if (this.logSetup)
|
|
477
|
-
fsm_dynamo_1.DyFM_Log.log('\nstarting DB connection...');
|
|
478
|
-
if (!this._params.dbUri) {
|
|
479
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
480
|
-
...this._getDefaultErrorSettings('startDB', new Error('DB URI is not set.')),
|
|
481
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
if (!this._params.dbOptions) {
|
|
485
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
486
|
-
...this._getDefaultErrorSettings('startDB', new Error('DB OPTIONS are not set.')),
|
|
487
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
if (this.systemControls.mongoose.init || this.systemControls.mongoose.started) {
|
|
491
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
492
|
-
...this._getDefaultErrorSettings('startDB', new Error('Mongoose is already initialized.')),
|
|
493
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
try {
|
|
497
|
-
await new Promise((resolve, reject) => {
|
|
498
|
-
this.systemControls.mongoose.init = true;
|
|
499
|
-
this.mongoose.connection
|
|
500
|
-
.once('open', () => {
|
|
501
|
-
this.systemControls.mongoose.started = true;
|
|
502
|
-
fsm_dynamo_1.DyFM_Log.success('\nConnected to MongoDB.\n');
|
|
503
|
-
resolve();
|
|
504
|
-
// FR-258 / SR-2 — install declared-retention TTL indexes. DEFERRED + fire-and-forget +
|
|
505
|
-
// fully non-fatal: a create-if-missing index op (and the `indexes()` probes) must NOT
|
|
506
|
-
// compete with boot-readiness. We delay it well past the deploy health-probe window so a
|
|
507
|
-
// cold boot is never slowed by it, then run it detached. `.unref()` keeps it from holding
|
|
508
|
-
// the event loop open. Any failure is logged but never crashes the app. (`'differs'` never
|
|
509
|
-
// rebuilds a live index — see ensureRetentionTtlIndex.)
|
|
510
|
-
const ttlInstallTimer = setTimeout(() => {
|
|
511
|
-
void this.installRetentionTtlIndexes();
|
|
512
|
-
}, 30000);
|
|
513
|
-
if (typeof ttlInstallTimer.unref === 'function') {
|
|
514
|
-
ttlInstallTimer.unref();
|
|
515
|
-
}
|
|
516
|
-
})
|
|
517
|
-
.on('error', (error) => {
|
|
518
|
-
if (!this.systemControls.mongoose.started) {
|
|
519
|
-
// Initial DB-csatlakozás sikertelen:
|
|
520
|
-
// jelezzük a hibát (log + globalErrorHandler), de NEM szakítjuk meg az
|
|
521
|
-
// App startup-ot (nincs constructErrors push, nincs reject).
|
|
522
|
-
// A mongoose.init-et resetteljük, hogy a ready() ne várjon a DB-re.
|
|
523
|
-
// Ha a mongoose később mégis tudna csatlakozni, az 'open' event
|
|
524
|
-
// beállítja a started flag-et, így a runtime DB-műveletek elindulnak.
|
|
525
|
-
this.systemControls.mongoose.init = false;
|
|
526
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-SDB1', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.databaseConnect, error, 503);
|
|
527
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
528
|
-
resolve();
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-SDB2', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.databaseRuntime, error, 503);
|
|
532
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
try {
|
|
536
|
-
this.mongoose.connect(this._params.dbUri, this._params.dbOptions
|
|
537
|
-
/* {
|
|
538
|
-
directConnection: true,
|
|
539
|
-
} */
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
|
-
catch (error) {
|
|
543
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
544
|
-
...this._getDefaultErrorSettings('startDB', error),
|
|
545
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB3`,
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
catch (error) {
|
|
551
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
552
|
-
...this._getDefaultErrorSettings('startDB', error),
|
|
553
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
// 2026-06-20 — Mongo reconnect-guard. A MongoDB-driver a hostnevet connect-kor EGYSZER
|
|
557
|
-
// resolválja + cache-eli az IP-t; ha a Mongo-konténert recreate-elik (új docker-network IP),
|
|
558
|
-
// a driver a HALOTT IP-n ragad → ECONNREFUSED + buffering-timeout, és a service magától SOHA
|
|
559
|
-
// nem áll vissza. A guard sustained-disconnect (readyState !== 1) esetén — a driver saját
|
|
560
|
-
// grace-e UTÁN — TELJES disconnect()+connect()-et csinál → ÚJ MongoClient → ÚJ DNS-resolve →
|
|
561
|
-
// új IP → reconnect. Best-effort, always-on, healthy connection-t (===1) SOHA nem bánt; csak
|
|
562
|
-
// konténer-IP-frissítés, nem ír adatot. Lásd: mongo-reconnect-guard.util.ts.
|
|
563
|
-
try {
|
|
564
|
-
(0, mongo_reconnect_guard_util_1.startMongoReconnectGuard)({
|
|
565
|
-
getReadyState: () => this.mongoose.connection.readyState,
|
|
566
|
-
reconnect: async () => {
|
|
567
|
-
await this.mongoose.disconnect().catch(() => undefined);
|
|
568
|
-
await this.mongoose.connect(this._params.dbUri, this._params.dbOptions);
|
|
569
|
-
},
|
|
570
|
-
log: (msg) => {
|
|
571
|
-
this.reportSafeDiagnostic('DYNTS-AS0-MONGO-RECONNECT-EVENT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard, msg, 503);
|
|
572
|
-
},
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
catch (guardErr) {
|
|
576
|
-
this.reportSafeDiagnostic('DYNTS-AS0-MONGO-RECONNECT-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard, guardErr, 503);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* FR-258 / SR-2 — install MongoDB TTL indexes for every data-model that declared `retention`.
|
|
581
|
-
*
|
|
582
|
-
* Runs ONCE right after the DB connection opens. For each registered DB service (including the
|
|
583
|
-
* auto-created `_archived` siblings, which inherit the parent model's `retention`), it ensures a
|
|
584
|
-
* TTL index on the `__created` Date field with the resolved `expireAfterSeconds` — so MongoDB
|
|
585
|
-
* NATIVELY auto-deletes documents older than the configured age. This is the fleet-wide defense
|
|
586
|
-
* against the unbounded-collection-growth → in-memory-load → GC-thrash/OOM class.
|
|
587
|
-
*
|
|
588
|
-
* Guarantees:
|
|
589
|
-
* - **Non-fatal** — any error is logged but NEVER blocks startup (called fire-and-forget).
|
|
590
|
-
* - **Idempotent** — an existing index with the same TTL is a no-op; a CHANGED retention (different
|
|
591
|
-
* `expireAfterSeconds`, or an existing non-TTL `__created` index) is reconciled by drop+recreate
|
|
592
|
-
* (the field index is restored immediately, so query coverage is preserved).
|
|
593
|
-
*/
|
|
594
|
-
async installRetentionTtlIndexes() {
|
|
595
|
-
try {
|
|
596
|
-
const services = global_service_1.DyNTS_GlobalService.getAllDBServices();
|
|
597
|
-
let ensured = 0;
|
|
598
|
-
for (const service of services) {
|
|
599
|
-
const ttlSeconds = (0, fsm_dynamo_1.DyFM_resolveRetentionTtlSeconds)(service?.dataParams?.retention);
|
|
600
|
-
if (!ttlSeconds) {
|
|
601
|
-
continue;
|
|
602
|
-
}
|
|
603
|
-
const dataName = service.dataParams.dataName;
|
|
604
|
-
// The mongoose Model exposes the native driver collection (.indexes / .createIndex / .dropIndex).
|
|
605
|
-
const collection = service?.dataModel?.collection;
|
|
606
|
-
if (!collection || typeof collection.createIndex !== 'function') {
|
|
607
|
-
continue;
|
|
608
|
-
}
|
|
609
|
-
try {
|
|
610
|
-
const action = await DyNTS_App.ensureRetentionTtlIndex(collection, ttlSeconds);
|
|
611
|
-
if (action === 'created') {
|
|
612
|
-
ensured++;
|
|
613
|
-
if (this.logSetup) {
|
|
614
|
-
fsm_dynamo_1.DyFM_Log.success(`[FR-258 retention] TTL index created on "${dataName}" — ` +
|
|
615
|
-
`${Math.round(ttlSeconds / 86400)}d (${ttlSeconds}s)`);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
else if (action === 'differs') {
|
|
619
|
-
// Live index has a different TTL — left untouched at boot (see ensureRetentionTtlIndex doc).
|
|
620
|
-
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INDEX-DIFFERS', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, new Error('retention-index-differs'));
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
catch (idxErr) {
|
|
624
|
-
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INDEX-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, idxErr);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
if (ensured > 0) {
|
|
628
|
-
fsm_dynamo_1.DyFM_Log.success(`[FR-258 retention] ${ensured} TTL index(es) ensured (auto-retention active).`);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
catch (err) {
|
|
632
|
-
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INSTALLER-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, err);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* FR-258 / SR-2 — ensure a single `{ __created: 1 }` TTL index with the given `expireAfterSeconds`.
|
|
637
|
-
* Extracted as a pure-ish static so it is unit-testable with a mock collection. Idempotent + BOOT-SAFE:
|
|
638
|
-
* - no existing `__created` index → create it → `'created'`
|
|
639
|
-
* - existing with the SAME TTL → no-op → `'noop'`
|
|
640
|
-
* - existing with a DIFFERENT TTL / non-TTL → leave it as-is → `'differs'` (warn only — NO drop+recreate)
|
|
641
|
-
*
|
|
642
|
-
* The `'differs'` case intentionally does NOT mutate the live index. Dropping + recreating a TTL index on a
|
|
643
|
-
* large (multi-GB) production collection is a heavy server-side operation; doing it automatically inside the
|
|
644
|
-
* startup path can starve the concurrent boot queries (including the deploy health-probe) and trigger a
|
|
645
|
-
* fail-safe revert. Create-if-missing is the essential growth-prevention behaviour; a deliberate retention
|
|
646
|
-
* CHANGE on an already-indexed collection is a maintenance action, not a silent every-boot rebuild.
|
|
647
|
-
*/
|
|
648
|
-
static async ensureRetentionTtlIndex(collection, ttlSeconds) {
|
|
649
|
-
const existingList = typeof collection.indexes === 'function'
|
|
650
|
-
? await collection.indexes().catch(() => [])
|
|
651
|
-
: [];
|
|
652
|
-
const existing = existingList.find((ix) => !!ix?.key && ix.key.__created === 1);
|
|
653
|
-
if (!existing) {
|
|
654
|
-
await collection.createIndex({ __created: 1 }, { expireAfterSeconds: ttlSeconds });
|
|
655
|
-
return 'created';
|
|
656
|
-
}
|
|
657
|
-
if (existing.expireAfterSeconds === ttlSeconds) {
|
|
658
|
-
return 'noop';
|
|
659
|
-
}
|
|
660
|
-
// Retention differs from the live index (or it is a non-TTL `__created` index). Leave it UNTOUCHED at
|
|
661
|
-
// boot — only report it. Avoids a heavy drop+recreate competing with boot-readiness on a large collection.
|
|
662
|
-
return 'differs';
|
|
663
|
-
}
|
|
664
|
-
/**
|
|
665
|
-
*
|
|
666
|
-
*/
|
|
667
|
-
async initExpresses() {
|
|
668
|
-
if (this.fnLogs && this.deepLog)
|
|
669
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. initExpresses');
|
|
670
|
-
try {
|
|
671
|
-
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
672
|
-
if (this._portSettings.httpPort === undefined || this._portSettings.httpPort === null) {
|
|
673
|
-
let errorMsg = `\nYou have open routes, but httpPort is not set!` +
|
|
674
|
-
`\nThere are ${this._routingModules.filter(m => m.security != route_security_enum_1.DyNTS_RouteSecurity.secure).length} open/both routes` +
|
|
675
|
-
`\nroot security: ${this._security}` +
|
|
676
|
-
`\nset httpPort in DynamoBEServer - setupRoutingModules() to enable secure routes.`;
|
|
677
|
-
errorMsg += '\n\nThe routes setted to use open server:';
|
|
678
|
-
this._routingModules.forEach((module) => {
|
|
679
|
-
if (module.security != route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
680
|
-
errorMsg += `\n ${module.route} (security: ${module.security})`;
|
|
681
|
-
errorMsg += `\n subroutes using open sever:`;
|
|
682
|
-
module.endpoints.forEach((endpoint) => {
|
|
683
|
-
if (endpoint.security != route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
684
|
-
errorMsg += `\n ${endpoint.endpoint} (security: ${endpoint.security})`;
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
});
|
|
689
|
-
const error = new Error(`Open routes cannot be established!\n${errorMsg}`);
|
|
690
|
-
const errorStack = error.stack.split('\n');
|
|
691
|
-
errorStack.splice(1, 2);
|
|
692
|
-
error.stack = errorStack.join('\n');
|
|
693
|
-
this.reportSafeDiagnostic('DYNTS-AS0-OPEN-ROUTE-CONFIGURATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
694
|
-
throw error;
|
|
695
|
-
}
|
|
696
|
-
await this.initOpenExpress();
|
|
697
|
-
}
|
|
698
|
-
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
699
|
-
if (!this._cert || !this._portSettings.httpsPort) {
|
|
700
|
-
let errorMsg = `\nYou have secure routes, but the certification paths or httpsPort are not set!` +
|
|
701
|
-
`\nThere are ${this._routingModules.filter(m => m.security && m.security !== route_security_enum_1.DyNTS_RouteSecurity.open).length} secure routes` +
|
|
702
|
-
`\nroot security: ${this._security}` +
|
|
703
|
-
`\nset...` +
|
|
704
|
-
`\n(missing exact howto...)` +
|
|
705
|
-
/* `\n httpsPort and` +
|
|
706
|
-
`\n cert: {` +
|
|
707
|
-
`\n keyPath: FileSystem.PathLike,` +
|
|
708
|
-
`\n certPath: FileSystem.PathLike,` +
|
|
709
|
-
`\n }` + */
|
|
710
|
-
`\nin DynamoBEServer - getRoutingModules() to enable secure routes.`;
|
|
711
|
-
errorMsg += '\n\nThe routes setted to use secure server:';
|
|
712
|
-
this._routingModules.forEach((module) => {
|
|
713
|
-
if (module.security && module.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
714
|
-
errorMsg += `\n ${module.route} (security: ${module.security})`;
|
|
715
|
-
errorMsg += `\n location: ${module.stackLocation}`;
|
|
716
|
-
errorMsg += `\n subroutes using secure sever:`;
|
|
717
|
-
module.endpoints.forEach((endpoint) => {
|
|
718
|
-
if (endpoint.security && endpoint.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
719
|
-
errorMsg += `\n ${endpoint.endpoint} (security: ${endpoint.security})`;
|
|
720
|
-
errorMsg += `\n location: ${endpoint.stackLocation}`;
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
});
|
|
725
|
-
const error = new Error(`Secure routes cannot be established!\n${errorMsg}`);
|
|
726
|
-
const errorStack = error.stack.split('\n');
|
|
727
|
-
errorStack.splice(1, 2);
|
|
728
|
-
error.stack = errorStack.join('\n');
|
|
729
|
-
this.reportSafeDiagnostic('DYNTS-AS0-SECURE-ROUTE-CONFIGURATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
730
|
-
throw error;
|
|
731
|
-
}
|
|
732
|
-
await this.initSecureExpress();
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
catch (error) {
|
|
736
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
737
|
-
...this._getDefaultErrorSettings('initExpresses', error),
|
|
738
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-IE0`,
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
|
-
*
|
|
744
|
-
*/
|
|
745
|
-
async initOpenExpress() {
|
|
746
|
-
if (this.fnLogs)
|
|
747
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. initOpenExpress');
|
|
748
|
-
this.openExpress = Express();
|
|
749
|
-
this.openExpress.set('maxHeaderSize', 10 * fsm_dynamo_1.megabyte); // 1024 * 1024 * 10, // 10MB
|
|
750
|
-
this.openExpress.use(BodyParser.urlencoded(this._portSettings.httpUrlencoded));
|
|
751
|
-
this.openExpress.use(BodyParser.json(this._portSettings.httpJson));
|
|
752
|
-
// BFR-011 / SEC-R2-8 — security headerek a CORS ELŐTT (az OPTIONS preflight-válaszok is kapják).
|
|
753
|
-
this.mountSecurityHeaders(this.openExpress);
|
|
754
|
-
// FR-041 — CORS allowlist enforcement. No-op if getCorsSettings() is not overridden.
|
|
755
|
-
this.mountCors(this.openExpress);
|
|
756
|
-
// FR-292 — a deployolt app-verzio minden valaszon. A CORS UTAN kell, mert az
|
|
757
|
-
// `Access-Control-Expose-Headers`-hoz HOZZAFUZ (kulonben a CORS felulirna).
|
|
758
|
-
this.mountAppVersionHeader(this.openExpress);
|
|
759
|
-
// BFR-OVERSEER-009 — opt-in auto-load-shed 503 CRITICAL memória-nyomásnál (esszenciális utak kivételével).
|
|
760
|
-
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.loadShedEnabled) {
|
|
761
|
-
this.openExpress.use((0, load_shed_util_1.DyNTS_createLoadShedMiddleware)());
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
*
|
|
766
|
-
*/
|
|
767
|
-
async initSecureExpress() {
|
|
768
|
-
if (this.fnLogs)
|
|
769
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. initSecureExpress');
|
|
770
|
-
this.secureExpress = Express();
|
|
771
|
-
this.secureExpress.use(BodyParser.urlencoded(this._portSettings.httpsUrlencoded));
|
|
772
|
-
this.secureExpress.use(BodyParser.json(this._portSettings.httpsJson));
|
|
773
|
-
// BFR-011 / SEC-R2-8 — security headerek a CORS ELŐTT (mint az open expressen).
|
|
774
|
-
this.mountSecurityHeaders(this.secureExpress);
|
|
775
|
-
// FR-041 — CORS allowlist enforcement (same as open express).
|
|
776
|
-
this.mountCors(this.secureExpress);
|
|
777
|
-
// FR-292 — a deployolt app-verzio minden valaszon (mint az open expressen).
|
|
778
|
-
this.mountAppVersionHeader(this.secureExpress);
|
|
779
|
-
// BFR-OVERSEER-009 — opt-in auto-load-shed 503 (mint az open expressen).
|
|
780
|
-
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.loadShedEnabled) {
|
|
781
|
-
this.secureExpress.use((0, load_shed_util_1.DyNTS_createLoadShedMiddleware)());
|
|
782
|
-
}
|
|
783
|
-
const options = {
|
|
784
|
-
key: FileSystem.readFileSync(this._cert.keyPath),
|
|
785
|
-
cert: FileSystem.readFileSync(this._cert.certPath),
|
|
786
|
-
maxHeaderSize: 10 * fsm_dynamo_1.megabyte, // 1024 * 1024 * 10, // 10MB
|
|
787
|
-
};
|
|
788
|
-
this.httpsServer = Https.createServer(options, this.secureExpress);
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
*
|
|
792
|
-
*/
|
|
793
|
-
async startExpresses() {
|
|
794
|
-
if (this.fnLogs && this.deepLog)
|
|
795
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. startExpresses');
|
|
796
|
-
try {
|
|
797
|
-
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
798
|
-
await new Promise((resolve, reject) => {
|
|
799
|
-
this.systemControls.httpsServer.init = true;
|
|
800
|
-
this.httpsServer
|
|
801
|
-
.listen(this._portSettings.httpsPort, this.params.secureHost, this.params.expressBacklog, () => {
|
|
802
|
-
this.systemControls.httpsServer.started = true;
|
|
803
|
-
fsm_dynamo_1.DyFM_Log.success(`\nHTTPS (secure) server is listening on port: ` +
|
|
804
|
-
`${this.params.secureHost}:${this._portSettings.httpsPort}`);
|
|
805
|
-
resolve();
|
|
806
|
-
})
|
|
807
|
-
.on('error', (error) => {
|
|
808
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTPS-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpsServer, error, 503);
|
|
809
|
-
if (!this.systemControls.httpsServer.started) {
|
|
810
|
-
const d_error = new fsm_dynamo_1.DyFM_Error({
|
|
811
|
-
...this._getDefaultErrorSettings('startExpresses', error),
|
|
812
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE1`,
|
|
813
|
-
message: `HTTPS (secure) start server ERROR`,
|
|
814
|
-
});
|
|
815
|
-
this.constructErrors.push(d_error);
|
|
816
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
817
|
-
reject(d_error);
|
|
818
|
-
}
|
|
819
|
-
else {
|
|
820
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
821
|
-
}
|
|
822
|
-
})
|
|
823
|
-
.on('uncaughtException', (exception) => {
|
|
824
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTPS-UNCAUGHT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpsServer, exception);
|
|
825
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
826
|
-
});
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
830
|
-
this.systemControls.httpServer.init = true;
|
|
831
|
-
await new Promise((resolve, reject) => {
|
|
832
|
-
this.httpServer = this.openExpress
|
|
833
|
-
.listen(this._portSettings.httpPort, this.params.openHost, this.params.expressBacklog, () => {
|
|
834
|
-
this.systemControls.httpServer.started = true;
|
|
835
|
-
const resolvedPort = this.httpServer?.address?.()?.['port'] ?? this._portSettings.httpPort;
|
|
836
|
-
if (this._portSettings.httpPort === 0) {
|
|
837
|
-
fsm_dynamo_1.DyFM_Log.H_warn(`\nHTTP (open) server is using a randomly selected port by the OS: ${resolvedPort}` +
|
|
838
|
-
`\n (httpPort was set to 0 — this is intended for testing only)`);
|
|
839
|
-
}
|
|
840
|
-
fsm_dynamo_1.DyFM_Log.success(`\nHTTP (open) server is listening on port: ` +
|
|
841
|
-
`${this.params.openHost}:${resolvedPort}`);
|
|
842
|
-
resolve();
|
|
843
|
-
})
|
|
844
|
-
.on('error', (error) => {
|
|
845
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTP-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpServer, error, 503);
|
|
846
|
-
if (!this.systemControls.httpServer.started) {
|
|
847
|
-
const d_error = new fsm_dynamo_1.DyFM_Error({
|
|
848
|
-
...this._getDefaultErrorSettings('startExpresses', error),
|
|
849
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE3`,
|
|
850
|
-
message: `HTTP (open) start server ERROR`,
|
|
851
|
-
});
|
|
852
|
-
this.constructErrors.push(d_error);
|
|
853
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
854
|
-
reject(d_error);
|
|
855
|
-
}
|
|
856
|
-
else {
|
|
857
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
858
|
-
}
|
|
859
|
-
})
|
|
860
|
-
.on('uncaughtException', (exception) => {
|
|
861
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTP-UNCAUGHT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpServer, exception);
|
|
862
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
863
|
-
});
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
catch (error) {
|
|
868
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
869
|
-
...this._getDefaultErrorSettings('startExpresses', error),
|
|
870
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE0`,
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
*
|
|
876
|
-
*/
|
|
877
|
-
async expressErrorHandling(error, req, res, next) {
|
|
878
|
-
try {
|
|
879
|
-
if (error) {
|
|
880
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback, error);
|
|
881
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
882
|
-
// Kliens-safe strip (BFR-FDPAUTHSERVICE-002): az express-error út eddig NYERS error-t küldött
|
|
883
|
-
// (0 strip) — DyFM-nél belső stack/verzió/issuer, axios-jellegű error-nál akár auth-header is
|
|
884
|
-
// kimehetett. A strip-szabályok SSOT-ja a DyNTS_ClientSafeError_Util.
|
|
885
|
-
res.send(client_safe_error_util_1.DyNTS_ClientSafeError_Util.toClientSafe(error));
|
|
886
|
-
}
|
|
887
|
-
else {
|
|
888
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-MISSING-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback);
|
|
889
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
catch (error) {
|
|
893
|
-
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-MULTILEVEL', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback, error);
|
|
894
|
-
this.forwardSafeDiagnostic(diagnostic);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
/**
|
|
898
|
-
*
|
|
899
|
-
*/
|
|
900
|
-
async mountSecureRoutes() {
|
|
901
|
-
try {
|
|
902
|
-
if (this.fnLogs && this.deepLog)
|
|
903
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. mountSecureRoutes');
|
|
904
|
-
if (!this.secureExpress) {
|
|
905
|
-
throw new Error('secureExpress was not initialized. ' +
|
|
906
|
-
'Secure routes require getCertificationSettings and httpsPort, and cert files must exist.' +
|
|
907
|
-
'\n\nYou need to set security to secure or both in any route and set httpsPort in getPortSettings.' +
|
|
908
|
-
'\n\nYou need to set cert files in getCertificationSettings.');
|
|
909
|
-
}
|
|
910
|
-
this.secureExpress.use((error, req, res, next) => this.expressErrorHandling(error, req, res, next));
|
|
911
|
-
await fsm_dynamo_1.DyFM_Array.asyncForEach(this._routingModules, async (module) => {
|
|
912
|
-
if (module.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
913
|
-
if (this.logSetup) {
|
|
914
|
-
fsm_dynamo_1.DyFM_Log.log(`route mount (secure): ${module.route}`);
|
|
915
|
-
}
|
|
916
|
-
const existingRoutes = this._routingModules.filter((mod) => mod.route === module.route);
|
|
917
|
-
if (1 < existingRoutes.length) {
|
|
918
|
-
const error = new Error(`ROUTE DUPLICATION: ${module.route}`);
|
|
919
|
-
/* const errorStack: string[] = error.stack.split('\n');
|
|
920
|
-
|
|
921
|
-
errorStack.splice(1, 4);
|
|
922
|
-
error.stack = errorStack.join('\n'); */
|
|
923
|
-
error.stack = module.stackLocation;
|
|
924
|
-
this.reportSafeDiagnostic('DYNTS-AS0-SECURE-ROUTE-DUPLICATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
925
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
926
|
-
...this._getDefaultErrorSettings('mountSecureRoutes', error),
|
|
927
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MSR1`,
|
|
928
|
-
message: `ROUTE DUPLICATION: ${module.route}`,
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
this.secureExpress.use(module.route, module.secureRouter);
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
catch (error) {
|
|
936
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
937
|
-
...this._getDefaultErrorSettings('mountSecureRoutes', error),
|
|
938
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MSR0`,
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
*
|
|
944
|
-
*/
|
|
945
|
-
async mountOpenRoutes() {
|
|
946
|
-
try {
|
|
947
|
-
if (this.fnLogs && this.deepLog)
|
|
948
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. mountOpenRoutes');
|
|
949
|
-
if (!this.openExpress) {
|
|
950
|
-
throw new Error('openExpress was not initialized. Open routes require getOpenExpress and httpPort.' +
|
|
951
|
-
'\n\nYou need to set security to open or both in any route and set httpPort in getPortSettings.');
|
|
952
|
-
}
|
|
953
|
-
this.openExpress.use((error, req, res, next) => this.expressErrorHandling(error, req, res, next));
|
|
954
|
-
await fsm_dynamo_1.DyFM_Array.asyncForEach(this._routingModules, async (module) => {
|
|
955
|
-
if (module.security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
956
|
-
if (this.logSetup) {
|
|
957
|
-
fsm_dynamo_1.DyFM_Log.log(`route mount (open): ${module.route}`);
|
|
958
|
-
}
|
|
959
|
-
const existingRoutes = this._routingModules.filter((mod) => mod.route === module.route);
|
|
960
|
-
if (1 < existingRoutes.length) {
|
|
961
|
-
const error = new Error(`ROUTE DUPLICATION: ${module.route}`);
|
|
962
|
-
/* const errorStack: string[] = error.stack.split('\n');
|
|
963
|
-
|
|
964
|
-
errorStack.splice(1, 4);
|
|
965
|
-
error.stack = errorStack.join('\n'); */
|
|
966
|
-
error.stack = module.stackLocation;
|
|
967
|
-
this.reportSafeDiagnostic('DYNTS-AS0-OPEN-ROUTE-DUPLICATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
968
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
969
|
-
...this._getDefaultErrorSettings('mountOpenRoutes', error),
|
|
970
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MOR1`,
|
|
971
|
-
message: `ROUTE DUPLICATION: ${module.route}`,
|
|
972
|
-
});
|
|
973
|
-
}
|
|
974
|
-
this.openExpress.use(module.route, module.openRouter);
|
|
975
|
-
}
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
catch (error) {
|
|
979
|
-
throw new fsm_dynamo_1.DyFM_Error({
|
|
980
|
-
...this._getDefaultErrorSettings('mountOpenRoutes', error),
|
|
981
|
-
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MOR0`,
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* FR-041 — CORS middleware. Echoes a matching `Access-Control-Allow-Origin`
|
|
987
|
-
* for any request whose Origin header is in `getCorsSettings().allowedOrigins`,
|
|
988
|
-
* adds the canonical `Access-Control-*` companion headers, and short-circuits
|
|
989
|
-
* the OPTIONS preflight with a 204.
|
|
990
|
-
*
|
|
991
|
-
* No-op when the subclass does NOT override `getCorsSettings()` — preserves
|
|
992
|
-
* back-compat for apps that have always been same-origin and never needed
|
|
993
|
-
* CORS (the typical pre-FR-041 case).
|
|
994
|
-
*
|
|
995
|
-
* Why hand-rolled instead of the `cors` npm package:
|
|
996
|
-
* - ~30 lines, zero new dependency.
|
|
997
|
-
* - Full control over Vary/credentials/preflight semantics.
|
|
998
|
-
* - Aligns with FDP "no unnecessary deps" philosophy.
|
|
999
|
-
*/
|
|
1000
|
-
/**
|
|
1001
|
-
* BFR-011 / SEC-R2-8 — security response-headerek mountolása (a `mountCors` tükörképe).
|
|
1002
|
-
* A `DyNTS_global_settings.securityHeaders` alapján (default-ON) minden válaszra ráteszi a
|
|
1003
|
-
* biztonsági headereket + eltávolítja az `x-powered-by`-t. A CORS-mount ELŐTT hívandó, hogy az
|
|
1004
|
-
* OPTIONS preflight-válaszok (amiket a mountCors 204-gyel rövidre zár) is megkapják.
|
|
1005
|
-
*/
|
|
1006
|
-
mountSecurityHeaders(express) {
|
|
1007
|
-
const settings = global_settings_const_1.DyNTS_global_settings.securityHeaders;
|
|
1008
|
-
if (!settings || !settings.enabled) {
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
if (settings.removePoweredBy !== false) {
|
|
1012
|
-
express.disable('x-powered-by');
|
|
1013
|
-
}
|
|
1014
|
-
express.use((0, security_headers_util_1.DyNTS_createSecurityHeadersMiddleware)(settings, (0, get_environment_settings_util_1.DyNTS_getEnvironment_settings)().environment));
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* FR-292 — a deployolt app-verziot minden valaszra rateszi (`X-App-Version`), hogy a
|
|
1018
|
-
* bongeszoben NYITVA HAGYOTT SPA eszrevegye, ha kozben ujabb kliens-build ment ki.
|
|
1019
|
-
*
|
|
1020
|
-
* Nem polling: a jelzes a MAR MENO API-hivasokon utazik. Az `enabled` default TRUE — egy
|
|
1021
|
-
* informativ response-header, ami se PII-t, se belso reszletet nem szivarogtat, viszont
|
|
1022
|
-
* enelkul minden app kulon-kulon epitene ugyanezt.
|
|
1023
|
-
*/
|
|
1024
|
-
mountAppVersionHeader(express) {
|
|
1025
|
-
const settings = global_settings_const_1.DyNTS_global_settings.appVersionHeader;
|
|
1026
|
-
if (settings?.enabled === false) {
|
|
1027
|
-
return;
|
|
1028
|
-
}
|
|
1029
|
-
express.use((0, app_version_header_util_1.DyNTS_createAppVersionHeaderMiddleware)(() => global_settings_const_1.DyNTS_global_settings.systemVersion, settings?.headerName));
|
|
1030
|
-
}
|
|
1031
|
-
mountCors(express) {
|
|
1032
|
-
const settings = this.getCorsSettings?.();
|
|
1033
|
-
if (!settings) {
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
const allowCreds = settings.allowCredentials !== false;
|
|
1037
|
-
const methods = settings.allowedMethods ?? [
|
|
1038
|
-
'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS',
|
|
1039
|
-
];
|
|
1040
|
-
const headers = settings.allowedHeaders ?? [
|
|
1041
|
-
'Authorization', 'Content-Type', 'X-Admin-Key', 'X-Requested-With',
|
|
1042
|
-
];
|
|
1043
|
-
const exposed = settings.exposedHeaders ?? [
|
|
1044
|
-
'Content-Length', 'Content-Type',
|
|
1045
|
-
];
|
|
1046
|
-
const maxAge = settings.maxAgeSeconds ?? 86400;
|
|
1047
|
-
const isAllowed = (origin) => {
|
|
1048
|
-
if (settings.allowedOrigins === '*')
|
|
1049
|
-
return true;
|
|
1050
|
-
if (typeof settings.allowedOrigins === 'function') {
|
|
1051
|
-
return settings.allowedOrigins(origin);
|
|
1052
|
-
}
|
|
1053
|
-
return settings.allowedOrigins.includes(origin);
|
|
1054
|
-
};
|
|
1055
|
-
express.use((req, res, next) => {
|
|
1056
|
-
const origin = req.headers.origin;
|
|
1057
|
-
if (origin && isAllowed(origin)) {
|
|
1058
|
-
// Echo the matching origin (NOT wildcard) because credentials require it.
|
|
1059
|
-
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
1060
|
-
if (allowCreds) {
|
|
1061
|
-
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
1062
|
-
}
|
|
1063
|
-
res.setHeader('Access-Control-Allow-Methods', methods.join(', '));
|
|
1064
|
-
res.setHeader('Access-Control-Allow-Headers', headers.join(', '));
|
|
1065
|
-
res.setHeader('Access-Control-Expose-Headers', exposed.join(', '));
|
|
1066
|
-
res.setHeader('Access-Control-Max-Age', String(maxAge));
|
|
1067
|
-
res.setHeader('Vary', 'Origin');
|
|
1068
|
-
}
|
|
1069
|
-
if (req.method === 'OPTIONS') {
|
|
1070
|
-
res.status(204).end();
|
|
1071
|
-
return;
|
|
1072
|
-
}
|
|
1073
|
-
next();
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Generikus, auth-agnosztikus extension-point orchestrator. A `registerCustomMiddleware`
|
|
1078
|
-
* hookot hívja (ha a subclass override-olja) minden AKTÍV Express instance-ra
|
|
1079
|
-
* (open + secure), az API route-ok UTÁN, de a SPA static catch-all (`app.get('*')`)
|
|
1080
|
-
* ELŐTT — ez az EGYETLEN korrekt pont egy sub-path middleware-hez (pl. reverse-proxy),
|
|
1081
|
-
* mert a catch-all minden utána mountolt route-ot elnyel. No-op ha nincs override (back-compat).
|
|
1082
|
-
*/
|
|
1083
|
-
async mountCustomMiddleware() {
|
|
1084
|
-
if (!this.registerCustomMiddleware) {
|
|
1085
|
-
return;
|
|
1086
|
-
}
|
|
1087
|
-
if (this.openExpress) {
|
|
1088
|
-
await this.registerCustomMiddleware(this.openExpress, route_security_enum_1.DyNTS_RouteSecurity.open);
|
|
1089
|
-
}
|
|
1090
|
-
if (this.secureExpress) {
|
|
1091
|
-
await this.registerCustomMiddleware(this.secureExpress, route_security_enum_1.DyNTS_RouteSecurity.secure);
|
|
1092
|
-
}
|
|
1093
|
-
if (this.logSetup) {
|
|
1094
|
-
fsm_dynamo_1.DyFM_Log.log('\nCustom middleware registered (pre-static).');
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Ha getStaticClientSettings() visszaad beállításokat, a client static fájlok a '/' alatt
|
|
1099
|
-
* lesznek kiszolgálva (API route-ok után). SPA fallback opcionális (fallbackPath).
|
|
1100
|
-
* Asset cache (assetCacheMaxAge, assetCacheImmutable) és fallback cache (fallbackCacheMaxAge)
|
|
1101
|
-
* opcionálisak; ha nincs megadva fallbackCacheMaxAge, DyNTS_defaultFallbackCacheMaxAge (0) marad.
|
|
1102
|
-
*/
|
|
1103
|
-
async mountStaticClient() {
|
|
1104
|
-
const settings = this.getStaticClientSettings?.();
|
|
1105
|
-
if (!settings) {
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
const absoluteRoot = Path.isAbsolute(settings.root)
|
|
1109
|
-
? settings.root
|
|
1110
|
-
: Path.resolve(process.cwd(), settings.root);
|
|
1111
|
-
const hasAssetCache = settings.assetCacheMaxAge !== undefined || settings.assetCacheImmutable === true;
|
|
1112
|
-
const staticOptions = hasAssetCache && settings.assetCacheMaxAge !== undefined
|
|
1113
|
-
? {
|
|
1114
|
-
setHeaders: (res, filePath) => {
|
|
1115
|
-
// A HTML entry-fájlok (index.html) no-cache-t kapnak, a hash-elt asset-ek
|
|
1116
|
-
// immutable long-cache-t — lásd DyNTS_resolveStaticCacheControlHeader (served-stale-index fix).
|
|
1117
|
-
res.setHeader('Cache-Control', (0, static_cache_control_util_1.DyNTS_resolveStaticCacheControlHeader)({
|
|
1118
|
-
filePath: filePath,
|
|
1119
|
-
assetCacheMaxAge: settings.assetCacheMaxAge,
|
|
1120
|
-
assetCacheImmutable: settings.assetCacheImmutable === true,
|
|
1121
|
-
}));
|
|
1122
|
-
},
|
|
1123
|
-
}
|
|
1124
|
-
: undefined;
|
|
1125
|
-
const staticMiddleware = staticOptions
|
|
1126
|
-
? Express.static(absoluteRoot, staticOptions)
|
|
1127
|
-
: Express.static(absoluteRoot);
|
|
1128
|
-
const fallbackMaxAge = settings.fallbackCacheMaxAge ?? default_fallback_cache_max_age_const_1.DyNTS_defaultFallbackCacheMaxAge;
|
|
1129
|
-
// API-namespace guard (BFR-DYNAMOBUILDER-001): a catch-all fallback NE fedje az API-prefixeket —
|
|
1130
|
-
// egy ismeretlen `GET /api/...` 404 JSON-t kapjon, ne megtévesztő `200 + index.html`-t.
|
|
1131
|
-
// Konfigurálható (fallbackExcludePrefixes); default a bevett FDP namespace-pár.
|
|
1132
|
-
const excludePrefixes = settings.fallbackExcludePrefixes ?? ['/api', '/auth-api'];
|
|
1133
|
-
const isApiNamespacePath = (path) => excludePrefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
|
|
1134
|
-
if (this.openExpress) {
|
|
1135
|
-
this.openExpress.use('/', staticMiddleware);
|
|
1136
|
-
if (settings.fallbackPath) {
|
|
1137
|
-
this.openExpress.get('*', (req, res) => {
|
|
1138
|
-
if (isApiNamespacePath(req.path)) {
|
|
1139
|
-
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1140
|
-
return;
|
|
1141
|
-
}
|
|
1142
|
-
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1143
|
-
res.sendFile(settings.fallbackPath, { root: absoluteRoot });
|
|
1144
|
-
});
|
|
1145
|
-
}
|
|
1146
|
-
else {
|
|
1147
|
-
this.openExpress.get('*', (req, res) => {
|
|
1148
|
-
if (isApiNamespacePath(req.path)) {
|
|
1149
|
-
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1150
|
-
return;
|
|
1151
|
-
}
|
|
1152
|
-
res.status(404).type('html').send(default_not_found_page_const_1.DyNTS_defaultNotFoundPageHtml);
|
|
1153
|
-
});
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
if (this.secureExpress) {
|
|
1157
|
-
this.secureExpress.use('/', staticMiddleware);
|
|
1158
|
-
if (settings.fallbackPath) {
|
|
1159
|
-
this.secureExpress.get('*', (req, res) => {
|
|
1160
|
-
if (isApiNamespacePath(req.path)) {
|
|
1161
|
-
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1165
|
-
res.sendFile(settings.fallbackPath, { root: absoluteRoot });
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
else {
|
|
1169
|
-
this.secureExpress.get('*', (req, res) => {
|
|
1170
|
-
if (isApiNamespacePath(req.path)) {
|
|
1171
|
-
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
|
-
res.status(404).type('html').send(default_not_found_page_const_1.DyNTS_defaultNotFoundPageHtml);
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
if (this.logSetup) {
|
|
1179
|
-
fsm_dynamo_1.DyFM_Log.log(`\nStatic client mounted at / (root: ${absoluteRoot})`);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
/**
|
|
1183
|
-
*
|
|
1184
|
-
*/
|
|
1185
|
-
setSecurity() {
|
|
1186
|
-
if (this.fnLogs && this.deepLog)
|
|
1187
|
-
fsm_dynamo_1.DyFM_Log.log('\nfn:. setSecurity');
|
|
1188
|
-
this._routingModules.forEach((module) => {
|
|
1189
|
-
if (!module.security) {
|
|
1190
|
-
fsm_dynamo_1.DyFM_Log.warn(`RoutingModule security is not set for ${module.route}\n`);
|
|
1191
|
-
}
|
|
1192
|
-
else if (!this._security) {
|
|
1193
|
-
this._security = module.security;
|
|
1194
|
-
}
|
|
1195
|
-
else if (this._security !== module.security) {
|
|
1196
|
-
this._security = route_security_enum_1.DyNTS_RouteSecurity.both;
|
|
1197
|
-
}
|
|
1198
|
-
});
|
|
1199
|
-
if (!this._security) {
|
|
1200
|
-
let msg = `Could not set security for the server! (${this.security})`;
|
|
1201
|
-
msg += '\n RoutingModules:';
|
|
1202
|
-
this._routingModules.forEach((module) => {
|
|
1203
|
-
msg += `\n ${module.route} (security: ${module.security})`;
|
|
1204
|
-
});
|
|
1205
|
-
if (this._routingModules.length === 0) {
|
|
1206
|
-
msg += '\n - no RoutingModule found -\n';
|
|
1207
|
-
}
|
|
1208
|
-
fsm_dynamo_1.DyFM_Log.warn(msg);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
_getDefaultErrorSettings(fnName, error) {
|
|
1212
|
-
return {
|
|
1213
|
-
status: error?.___status ?? 500,
|
|
1214
|
-
message: error?.message ??
|
|
1215
|
-
error?._message ??
|
|
1216
|
-
`${fnName} was UNSUCCESSFUL (NTS)`,
|
|
1217
|
-
userMessage: error?.__userMessage ?? this.defaultErrorUserMsg,
|
|
1218
|
-
addECToUserMsg: !error?.__userMessage,
|
|
1219
|
-
issuerService: `${this?.constructor?.name}-DyNTS_App`,
|
|
1220
|
-
level: fsm_dynamo_1.DyFM_ErrorLevel.fatal,
|
|
1221
|
-
error: error,
|
|
1222
|
-
systemVersion: global_settings_const_1.DyNTS_global_settings.systemVersion,
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
exports.DyNTS_App = DyNTS_App;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_App = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const Mongoose = require("mongoose");
|
|
6
|
+
const Express = require("express");
|
|
7
|
+
/* import Mongoose from 'mongoose';
|
|
8
|
+
import Express from 'express'; */
|
|
9
|
+
const BodyParser = tslib_1.__importStar(require("body-parser"));
|
|
10
|
+
const FileSystem = tslib_1.__importStar(require("fs"));
|
|
11
|
+
const Https = tslib_1.__importStar(require("https"));
|
|
12
|
+
const Path = tslib_1.__importStar(require("path"));
|
|
13
|
+
/* import { version } from '../../../package.json'; */
|
|
14
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
15
|
+
const default_fallback_cache_max_age_const_1 = require("../../_collections/default-fallback-cache-max-age.const");
|
|
16
|
+
const default_not_found_page_const_1 = require("../../_collections/default-not-found-page.const");
|
|
17
|
+
const global_settings_const_1 = require("../../_collections/global-settings.const");
|
|
18
|
+
const client_safe_error_util_1 = require("../../_collections/client-safe-error.util");
|
|
19
|
+
const get_environment_settings_util_1 = require("../../_collections/get-environment-settings.util");
|
|
20
|
+
const security_headers_util_1 = require("../../_collections/security-headers.util");
|
|
21
|
+
const load_shed_util_1 = require("../../_collections/load-shed.util");
|
|
22
|
+
const app_version_header_util_1 = require("../../_collections/app-version-header.util");
|
|
23
|
+
const mongo_reconnect_guard_util_1 = require("../../_collections/mongo-reconnect-guard.util");
|
|
24
|
+
const static_cache_control_util_1 = require("../../_collections/static-cache-control.util");
|
|
25
|
+
const route_security_enum_1 = require("../../_enums/route-security.enum");
|
|
26
|
+
const app_system_controls_control_model_1 = require("../../_models/control-models/app-system-controls.control-model");
|
|
27
|
+
const http_settings_control_model_1 = require("../../_models/control-models/http-settings.control-model");
|
|
28
|
+
const singleton_service_1 = require("../base/singleton.service");
|
|
29
|
+
const global_service_1 = require("../core/global.service");
|
|
30
|
+
const collection_growth_monitor_service_1 = require("../core/collection-growth-monitor.service");
|
|
31
|
+
const memory_guard_service_1 = require("../core/memory-guard.service");
|
|
32
|
+
const event_loop_diag_service_1 = require("../core/event-loop-diag.service");
|
|
33
|
+
const safe_diagnostic_stage_type_enum_1 = require("../../_modules/server/safe-diagnostic/safe-diagnostic-stage.type-enum");
|
|
34
|
+
const safe_diagnostic_control_service_1 = require("../../_modules/server/safe-diagnostic/safe-diagnostic.control-service");
|
|
35
|
+
class DyNTS_App extends singleton_service_1.DyNTS_SingletonService {
|
|
36
|
+
systemControls = new app_system_controls_control_model_1.DyNTS_AppSystemControls();
|
|
37
|
+
get started() {
|
|
38
|
+
return this.systemControls.app.started;
|
|
39
|
+
}
|
|
40
|
+
get superStarted() {
|
|
41
|
+
return this.systemControls.app.started;
|
|
42
|
+
}
|
|
43
|
+
constructErrors = [];
|
|
44
|
+
/* removed since cant use version from package.json
|
|
45
|
+
private readonly _ntsVersion: string = 'v01.07.18';
|
|
46
|
+
protected get ntsVersion(): string {
|
|
47
|
+
return this._ntsVersion;
|
|
48
|
+
} */
|
|
49
|
+
get serverName() {
|
|
50
|
+
return this.params.name;
|
|
51
|
+
}
|
|
52
|
+
_params;
|
|
53
|
+
get params() {
|
|
54
|
+
return this._params;
|
|
55
|
+
}
|
|
56
|
+
mongoose = Mongoose;
|
|
57
|
+
_security;
|
|
58
|
+
get security() {
|
|
59
|
+
return this._security;
|
|
60
|
+
}
|
|
61
|
+
_portSettings = new http_settings_control_model_1.DyNTS_Http_Settings();
|
|
62
|
+
get portSettings() {
|
|
63
|
+
return this._portSettings;
|
|
64
|
+
}
|
|
65
|
+
_cert;
|
|
66
|
+
get cert() {
|
|
67
|
+
return this._cert;
|
|
68
|
+
}
|
|
69
|
+
openExpress;
|
|
70
|
+
secureExpress;
|
|
71
|
+
httpsServer;
|
|
72
|
+
httpServer;
|
|
73
|
+
globalService;
|
|
74
|
+
_rootServices = [];
|
|
75
|
+
_routingModules = [];
|
|
76
|
+
defaultReadyTimeout = 30 * fsm_dynamo_1.second;
|
|
77
|
+
defaultErrorUserMsg = `We encountered an unhandled Server Error, ` +
|
|
78
|
+
`\nplease contact the responsible development team.` +
|
|
79
|
+
`\n(Internal Server error)`;
|
|
80
|
+
get logSetup() {
|
|
81
|
+
return global_settings_const_1.DyNTS_global_settings.log_settings.setup;
|
|
82
|
+
}
|
|
83
|
+
get deepLog() {
|
|
84
|
+
return global_settings_const_1.DyNTS_global_settings.log_settings.deep;
|
|
85
|
+
}
|
|
86
|
+
get fnLogs() {
|
|
87
|
+
return global_settings_const_1.DyNTS_global_settings.log_settings.functions;
|
|
88
|
+
}
|
|
89
|
+
debugLog = global_settings_const_1.DyNTS_global_settings.log_settings.server_debug;
|
|
90
|
+
reportSafeDiagnostic(code, stage, error, status = 500) {
|
|
91
|
+
const configuredPrefix = global_settings_const_1.DyNTS_global_settings.systemShortCodeName;
|
|
92
|
+
const prefix = configuredPrefix && /^[A-Z][A-Z0-9_-]{1,31}$/.test(configuredPrefix)
|
|
93
|
+
? configuredPrefix
|
|
94
|
+
: 'DYNTS';
|
|
95
|
+
return safe_diagnostic_control_service_1.DyNTS_SafeDiagnostic_ControlService.report({
|
|
96
|
+
code: `${prefix}|${code}`,
|
|
97
|
+
stage: stage,
|
|
98
|
+
error: error,
|
|
99
|
+
status: status,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
forwardSafeDiagnostic(diagnostic) {
|
|
103
|
+
try {
|
|
104
|
+
const pending = global_service_1.DyNTS_GlobalService.globalErrorHandler?.(safe_diagnostic_control_service_1.DyNTS_SafeDiagnostic_ControlService.toError(diagnostic));
|
|
105
|
+
void pending?.catch((error) => {
|
|
106
|
+
this.reportSafeDiagnostic('DYNTS-AS0-GLOBAL-HANDLER-REJECTED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.globalErrorHandler, error);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.reportSafeDiagnostic('DYNTS-AS0-GLOBAL-HANDLER-THREW', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.globalErrorHandler, error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
constructor( /* extended?: boolean */) {
|
|
114
|
+
super();
|
|
115
|
+
/* dotenv.config() */
|
|
116
|
+
process.on('unhandledRejection', (reason) => {
|
|
117
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-BASE-UR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.unhandledRejection, reason);
|
|
118
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
119
|
+
});
|
|
120
|
+
this.asyncConstruct( /* extended */).catch((error) => {
|
|
121
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-BOOTSTRAP-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.bootstrap, error);
|
|
122
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async asyncConstruct(extended) {
|
|
127
|
+
if (this.fnLogs && this.deepLog)
|
|
128
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. asyncConstruct');
|
|
129
|
+
try {
|
|
130
|
+
this.systemControls.app.init = true;
|
|
131
|
+
this._params = this.getAppParams();
|
|
132
|
+
fsm_dynamo_1.DyFM_Log.log(`\n\n\n\n\n\n\n\n\n\n` +
|
|
133
|
+
`Starting ${this._params?.name}... ` +
|
|
134
|
+
/* `v${version}` + */
|
|
135
|
+
`\n\n\n\n\n\n\n\n\n\n`);
|
|
136
|
+
if (!this._params) {
|
|
137
|
+
throw new Error('getAppParams() must return a DyNTS_AppParams object!');
|
|
138
|
+
}
|
|
139
|
+
if (this.params.systemShortCodeName) {
|
|
140
|
+
global_settings_const_1.DyNTS_global_settings.systemShortCodeName = this.params.systemShortCodeName;
|
|
141
|
+
}
|
|
142
|
+
if (this.params.systemName) {
|
|
143
|
+
global_settings_const_1.DyNTS_global_settings.systemName = this.params.systemName;
|
|
144
|
+
fsm_dynamo_1.DyFM_error_defaults.issuerSystem = this.params.systemName;
|
|
145
|
+
}
|
|
146
|
+
if (this.params.version) {
|
|
147
|
+
global_settings_const_1.DyNTS_global_settings.systemVersion = this.params.version;
|
|
148
|
+
fsm_dynamo_1.DyFM_error_defaults.systemVersion = this.params.version;
|
|
149
|
+
}
|
|
150
|
+
process.stdout.write(String.fromCharCode(27) + ']0;' +
|
|
151
|
+
this._params?.name +
|
|
152
|
+
String.fromCharCode(7));
|
|
153
|
+
fsm_dynamo_1.DyFM_error_defaults.issuerSystem = this._params.systemName;
|
|
154
|
+
this.overrideDynamoNTSGlobalSettings?.();
|
|
155
|
+
if (global_settings_const_1.DyNTS_global_settings.log_settings.setup) {
|
|
156
|
+
fsm_dynamo_1.DyFM_Log.S_info(`env settings;\n`, {
|
|
157
|
+
systemName: global_settings_const_1.DyNTS_global_settings.systemName,
|
|
158
|
+
systemShortCodeName: global_settings_const_1.DyNTS_global_settings.systemShortCodeName,
|
|
159
|
+
systemVersion: global_settings_const_1.DyNTS_global_settings.systemVersion,
|
|
160
|
+
environment: global_settings_const_1.DyNTS_global_settings.env_settings.environment,
|
|
161
|
+
/* log_settings: DyNTS_global_settings.log_settings,
|
|
162
|
+
env_settings: DyNTS_global_settings.env_settings, */
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
this.globalService = global_service_1.DyNTS_GlobalService.getInstance();
|
|
166
|
+
await global_service_1.DyNTS_GlobalService.setServices(this.getGlobalServiceCollection());
|
|
167
|
+
global_service_1.DyNTS_GlobalService.setParams(this.params);
|
|
168
|
+
if (this.getPortSettings) {
|
|
169
|
+
this._portSettings = this.getPortSettings();
|
|
170
|
+
}
|
|
171
|
+
if (this.getCertificationSettings) {
|
|
172
|
+
this._cert = this.getCertificationSettings();
|
|
173
|
+
}
|
|
174
|
+
if (this.getApiBasePath) {
|
|
175
|
+
global_settings_const_1.DyNTS_global_settings.baseUrl = this.getApiBasePath();
|
|
176
|
+
}
|
|
177
|
+
if (this.getRoutingModules) {
|
|
178
|
+
this._routingModules = this.getRoutingModules();
|
|
179
|
+
// ezt egyelőre csak tesztelem, nem kerül be
|
|
180
|
+
/* if (
|
|
181
|
+
!DyNTS_global_settings.dontCreateDefaultRoute &&
|
|
182
|
+
!this._routingModules.some((routingModule: DyNTS_RoutingModule): boolean => routingModule.route === '/*')
|
|
183
|
+
) {
|
|
184
|
+
this._routingModules.push(
|
|
185
|
+
DyNTS_getStarRoute()
|
|
186
|
+
);
|
|
187
|
+
} */
|
|
188
|
+
}
|
|
189
|
+
if (this._params.dbUri) {
|
|
190
|
+
await this.startDB();
|
|
191
|
+
// createEntries csak akkor fut, ha a DB tényleg fel-jött.
|
|
192
|
+
// Ha a startDB jelezte a hibát, de továbbment, akkor a started flag false marad,
|
|
193
|
+
// és nem próbálunk meg írni egy nem létező kapcsolatra.
|
|
194
|
+
if (this.createEntries && this.systemControls.mongoose.started) {
|
|
195
|
+
await this.createEntries();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
fsm_dynamo_1.DyFM_Log.log(`\nNo database connection created.`);
|
|
200
|
+
}
|
|
201
|
+
if (this._routingModules?.length) {
|
|
202
|
+
if (this.logSetup)
|
|
203
|
+
fsm_dynamo_1.DyFM_Log.log('\nsetting up express routes...');
|
|
204
|
+
this.setSecurity();
|
|
205
|
+
await this.initExpresses();
|
|
206
|
+
await this.startExpresses();
|
|
207
|
+
if (this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
208
|
+
await this.mountOpenRoutes();
|
|
209
|
+
}
|
|
210
|
+
if (this._security !== route_security_enum_1.DyNTS_RouteSecurity.open && this._cert) {
|
|
211
|
+
await this.mountSecureRoutes();
|
|
212
|
+
}
|
|
213
|
+
// Generikus, auth-agnosztikus extension-point: custom middleware az API
|
|
214
|
+
// route-ok UTÁN, de a SPA static catch-all (mountStaticClient) ELŐTT.
|
|
215
|
+
await this.mountCustomMiddleware();
|
|
216
|
+
await this.mountStaticClient();
|
|
217
|
+
if (this.logSetup) {
|
|
218
|
+
fsm_dynamo_1.DyFM_Log.log(`\nRoutes mounted.... server using security: ${this._security}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
fsm_dynamo_1.DyFM_Log.warn(`\nNo routes mounted!`);
|
|
223
|
+
}
|
|
224
|
+
if (this.getRootServices) {
|
|
225
|
+
this._rootServices = await this.getRootServices();
|
|
226
|
+
}
|
|
227
|
+
if (this.postProcess) {
|
|
228
|
+
await this.postProcess().catch((error) => {
|
|
229
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-POST-PROCESS-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.postProcess, error);
|
|
230
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// FR-193 — bedrock OOM korai-figyelmeztetés: feltelepítjük a heap-watchdogot, ha
|
|
234
|
+
// engedélyezve (DyNTS_global_settings.memoryGuard.enabled, default true). Biztonságos:
|
|
235
|
+
// a guard egy könnyű setInterval, ami SOHA nem dob; csak near-OOM küszöböknél hagy
|
|
236
|
+
// tartós nyomot az error-sinkbe, mielőtt a fatal heap-OOM megölné a process-t.
|
|
237
|
+
try {
|
|
238
|
+
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.enabled) {
|
|
239
|
+
memory_guard_service_1.DyNTS_MemoryGuard.getInstance().install();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (memoryGuardError) {
|
|
243
|
+
this.reportSafeDiagnostic('DYNTS-AS0-MEMORY-GUARD-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.memoryGuard, memoryGuardError);
|
|
244
|
+
}
|
|
245
|
+
// BFR-OVERSEER-007 — event-loop-lag diag a MemoryGuard MELLÉ: a „process él, HTTP néma" wedge
|
|
246
|
+
// belső mérése (natív histogram, olcsó). Observation-only, sosem dob; a /server/diag olvas belőle.
|
|
247
|
+
try {
|
|
248
|
+
event_loop_diag_service_1.DyNTS_EventLoopDiag.getInstance().install();
|
|
249
|
+
}
|
|
250
|
+
catch (eventLoopDiagError) {
|
|
251
|
+
this.reportSafeDiagnostic('DYNTS-AS0-EVENT-LOOP-DIAG-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.eventLoopDiagnostic, eventLoopDiagError);
|
|
252
|
+
}
|
|
253
|
+
// FR-258 / SR-4 — proactive collection-growth monitor (companion to the MemoryGuard). Warns
|
|
254
|
+
// into the Errors-sink when a collection grows unbounded, BEFORE it can be loaded into heap and
|
|
255
|
+
// OOM. Default-on, observation-only, never throws.
|
|
256
|
+
try {
|
|
257
|
+
if (global_settings_const_1.DyNTS_global_settings.collectionGrowthMonitor?.enabled) {
|
|
258
|
+
collection_growth_monitor_service_1.DyNTS_CollectionGrowthMonitor.getInstance().install();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch (cgmError) {
|
|
262
|
+
this.reportSafeDiagnostic('DYNTS-AS0-COLLECTION-GROWTH-MONITOR-SKIPPED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.collectionGrowthMonitor, cgmError);
|
|
263
|
+
}
|
|
264
|
+
if (!extended) {
|
|
265
|
+
await this.ready();
|
|
266
|
+
if (this.params.title) {
|
|
267
|
+
fsm_dynamo_1.DyFM_Log.success(this.params.title);
|
|
268
|
+
}
|
|
269
|
+
fsm_dynamo_1.DyFM_Log.info(`Version: ${this.params.version}`);
|
|
270
|
+
/* DyFM_Log.info(`NTS Version: ${this.ntsVersion}`); */
|
|
271
|
+
fsm_dynamo_1.DyFM_Log.H_success(`${this.params.name} started successfully.`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
this.constructErrors.push(error);
|
|
276
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
277
|
+
...this._getDefaultErrorSettings('asyncConstruct', error),
|
|
278
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-001`,
|
|
279
|
+
additionalContent: {
|
|
280
|
+
constructErrors: this.constructErrors,
|
|
281
|
+
systemControls: this.systemControls,
|
|
282
|
+
systemReadies: {
|
|
283
|
+
app: this.systemControls.app.getIsReady(),
|
|
284
|
+
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
285
|
+
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
286
|
+
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
async ready(timeout = this.defaultReadyTimeout) {
|
|
293
|
+
try {
|
|
294
|
+
if (this.fnLogs)
|
|
295
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. ready');
|
|
296
|
+
await fsm_dynamo_1.DyFM_Async.delay(100);
|
|
297
|
+
let ready = false;
|
|
298
|
+
const start = +new Date();
|
|
299
|
+
if (this.constructErrors.length) {
|
|
300
|
+
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-CONSTRUCT-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0]);
|
|
301
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
302
|
+
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed.`)),
|
|
303
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R01`,
|
|
304
|
+
additionalContent: this.constructErrors.length === 1 ?
|
|
305
|
+
{ error: this.constructErrors[0] } :
|
|
306
|
+
{ errors: this.constructErrors },
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
while (!ready && +new Date() - start < timeout) {
|
|
310
|
+
if (this.systemControls.app.init) {
|
|
311
|
+
ready = (this.systemControls.mongoose.getIsReady() &&
|
|
312
|
+
this.systemControls.httpServer.getIsReady() &&
|
|
313
|
+
this.systemControls.httpsServer.getIsReady());
|
|
314
|
+
}
|
|
315
|
+
if (!ready) {
|
|
316
|
+
await fsm_dynamo_1.DyFM_Async.wait(100);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (timeout < +new Date() - start) {
|
|
320
|
+
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-TIMEOUT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0] ?? new Error('readiness-timeout'));
|
|
321
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
322
|
+
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed. TIMEOUT`)),
|
|
323
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R02`,
|
|
324
|
+
additionalContent: {
|
|
325
|
+
constructErrors: this.constructErrors,
|
|
326
|
+
systemControls: this.systemControls,
|
|
327
|
+
systemReadies: {
|
|
328
|
+
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
329
|
+
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
330
|
+
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
if (this.constructErrors.length) {
|
|
336
|
+
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-LATE-CONSTRUCT-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0]);
|
|
337
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
338
|
+
...this._getDefaultErrorSettings('ready', new Error(`"${this._params.name}" start failed.`)),
|
|
339
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R03`,
|
|
340
|
+
additionalContent: this.constructErrors,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
if (ready) {
|
|
344
|
+
this.systemControls.app.started = true;
|
|
345
|
+
if (this.fnLogs && this.deepLog)
|
|
346
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. ready: return');
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
this.systemControls.app.started = false;
|
|
350
|
+
let msg = `"${this._params.name}" start failed. UNKNOWN`;
|
|
351
|
+
if (this.systemControls.mongoose.init && !this.systemControls.mongoose.started) {
|
|
352
|
+
msg += `\nMongoose start failed.`;
|
|
353
|
+
}
|
|
354
|
+
if (this.systemControls.httpServer.init && !this.systemControls.httpServer.started) {
|
|
355
|
+
msg += `\nHTTP Server start failed.`;
|
|
356
|
+
}
|
|
357
|
+
if (this.systemControls.httpsServer.init && !this.systemControls.httpsServer.started) {
|
|
358
|
+
msg += `\nHTTPS Server start failed.`;
|
|
359
|
+
}
|
|
360
|
+
this.reportSafeDiagnostic('DYNTS-AS0-READINESS-UNKNOWN', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.readiness, this.constructErrors[0] ?? new Error('readiness-unknown'));
|
|
361
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
362
|
+
...this._getDefaultErrorSettings('ready', new Error(msg)),
|
|
363
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-R04`,
|
|
364
|
+
additionalContent: {
|
|
365
|
+
constructErrors: this.constructErrors,
|
|
366
|
+
systemControls: this.systemControls,
|
|
367
|
+
systemReadies: {
|
|
368
|
+
app: this.systemControls.app.getIsReady(),
|
|
369
|
+
mongoose: this.systemControls.mongoose.getIsReady(),
|
|
370
|
+
httpServer: this.systemControls.httpServer.getIsReady(),
|
|
371
|
+
httpsServer: this.systemControls.httpsServer.getIsReady(),
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
error: this.constructErrors?.[0] ?? new Error(),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
379
|
+
...this._getDefaultErrorSettings('ready', error),
|
|
380
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-READY0`,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
getSimplifiedConstructErrors() {
|
|
385
|
+
return this.constructErrors.map((error) => {
|
|
386
|
+
if (error instanceof fsm_dynamo_1.DyFM_Error) {
|
|
387
|
+
return error.getErrorSimplified();
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
return error;
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
async stop(dontLog) {
|
|
395
|
+
try {
|
|
396
|
+
fsm_dynamo_1.DyFM_Log.info('\nstopping server...\n');
|
|
397
|
+
await this.ready();
|
|
398
|
+
if (this.started) {
|
|
399
|
+
if (this.systemControls.mongoose.init) {
|
|
400
|
+
fsm_dynamo_1.DyFM_Log.info(`\nstopping Mongoose....`);
|
|
401
|
+
let tryCount = 0;
|
|
402
|
+
while (!this.systemControls.mongoose.started &&
|
|
403
|
+
!this.constructErrors.length &&
|
|
404
|
+
tryCount++ < 10) {
|
|
405
|
+
fsm_dynamo_1.DyFM_Log.warn(`Mongoose not even started yet....`);
|
|
406
|
+
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
407
|
+
}
|
|
408
|
+
this.systemControls.mongoose.started = false;
|
|
409
|
+
if (this.mongoose) {
|
|
410
|
+
await fsm_dynamo_1.DyFM_Array.asyncForEach(Object.keys(this.mongoose.models), async (modelName) => {
|
|
411
|
+
this.mongoose.deleteModel(modelName);
|
|
412
|
+
});
|
|
413
|
+
const disconnect = new Promise((resolve) => {
|
|
414
|
+
this.mongoose.connection.on('disconnecting', () => {
|
|
415
|
+
resolve();
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
await this.mongoose.disconnect();
|
|
419
|
+
await this.mongoose.connection.close();
|
|
420
|
+
await disconnect;
|
|
421
|
+
this.mongoose.connection.removeAllListeners();
|
|
422
|
+
while (this.mongoose.connection.readyState !== 0 &&
|
|
423
|
+
!this.constructErrors.length) {
|
|
424
|
+
fsm_dynamo_1.DyFM_Log.warn(`\nMongoose still not disconnected....`);
|
|
425
|
+
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
fsm_dynamo_1.DyFM_Log.error(`\nMongoose not found.`);
|
|
430
|
+
}
|
|
431
|
+
this.systemControls.mongoose.init = false;
|
|
432
|
+
}
|
|
433
|
+
if (this.systemControls.httpServer.init) {
|
|
434
|
+
this.systemControls.httpServer.started = false;
|
|
435
|
+
if (this.httpServer) {
|
|
436
|
+
await new Promise((resolve) => {
|
|
437
|
+
this.httpServer.close(resolve);
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
fsm_dynamo_1.DyFM_Log.error(`\nHTTP Server not found.`);
|
|
442
|
+
}
|
|
443
|
+
this.systemControls.httpServer.init = false;
|
|
444
|
+
}
|
|
445
|
+
if (this.systemControls.httpsServer.init) {
|
|
446
|
+
this.systemControls.httpsServer.started = false;
|
|
447
|
+
if (this.httpsServer) {
|
|
448
|
+
await new Promise((resolve) => {
|
|
449
|
+
this.httpsServer.close(resolve);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
fsm_dynamo_1.DyFM_Log.error(`\nHTTPS Server not found.`);
|
|
454
|
+
}
|
|
455
|
+
this.systemControls.httpsServer.init = false;
|
|
456
|
+
}
|
|
457
|
+
await fsm_dynamo_1.DyFM_Async.wait(fsm_dynamo_1.second);
|
|
458
|
+
if (!dontLog) {
|
|
459
|
+
fsm_dynamo_1.DyFM_Log.H_log(`"${this._params.name}" stopped successfully.`);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
465
|
+
...this._getDefaultErrorSettings('stop', error),
|
|
466
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-STOP0`,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
*
|
|
472
|
+
*/
|
|
473
|
+
async startDB() {
|
|
474
|
+
if (this.fnLogs && this.deepLog)
|
|
475
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. startDB');
|
|
476
|
+
else if (this.logSetup)
|
|
477
|
+
fsm_dynamo_1.DyFM_Log.log('\nstarting DB connection...');
|
|
478
|
+
if (!this._params.dbUri) {
|
|
479
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
480
|
+
...this._getDefaultErrorSettings('startDB', new Error('DB URI is not set.')),
|
|
481
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
if (!this._params.dbOptions) {
|
|
485
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
486
|
+
...this._getDefaultErrorSettings('startDB', new Error('DB OPTIONS are not set.')),
|
|
487
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
if (this.systemControls.mongoose.init || this.systemControls.mongoose.started) {
|
|
491
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
492
|
+
...this._getDefaultErrorSettings('startDB', new Error('Mongoose is already initialized.')),
|
|
493
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
try {
|
|
497
|
+
await new Promise((resolve, reject) => {
|
|
498
|
+
this.systemControls.mongoose.init = true;
|
|
499
|
+
this.mongoose.connection
|
|
500
|
+
.once('open', () => {
|
|
501
|
+
this.systemControls.mongoose.started = true;
|
|
502
|
+
fsm_dynamo_1.DyFM_Log.success('\nConnected to MongoDB.\n');
|
|
503
|
+
resolve();
|
|
504
|
+
// FR-258 / SR-2 — install declared-retention TTL indexes. DEFERRED + fire-and-forget +
|
|
505
|
+
// fully non-fatal: a create-if-missing index op (and the `indexes()` probes) must NOT
|
|
506
|
+
// compete with boot-readiness. We delay it well past the deploy health-probe window so a
|
|
507
|
+
// cold boot is never slowed by it, then run it detached. `.unref()` keeps it from holding
|
|
508
|
+
// the event loop open. Any failure is logged but never crashes the app. (`'differs'` never
|
|
509
|
+
// rebuilds a live index — see ensureRetentionTtlIndex.)
|
|
510
|
+
const ttlInstallTimer = setTimeout(() => {
|
|
511
|
+
void this.installRetentionTtlIndexes();
|
|
512
|
+
}, 30000);
|
|
513
|
+
if (typeof ttlInstallTimer.unref === 'function') {
|
|
514
|
+
ttlInstallTimer.unref();
|
|
515
|
+
}
|
|
516
|
+
})
|
|
517
|
+
.on('error', (error) => {
|
|
518
|
+
if (!this.systemControls.mongoose.started) {
|
|
519
|
+
// Initial DB-csatlakozás sikertelen:
|
|
520
|
+
// jelezzük a hibát (log + globalErrorHandler), de NEM szakítjuk meg az
|
|
521
|
+
// App startup-ot (nincs constructErrors push, nincs reject).
|
|
522
|
+
// A mongoose.init-et resetteljük, hogy a ready() ne várjon a DB-re.
|
|
523
|
+
// Ha a mongoose később mégis tudna csatlakozni, az 'open' event
|
|
524
|
+
// beállítja a started flag-et, így a runtime DB-műveletek elindulnak.
|
|
525
|
+
this.systemControls.mongoose.init = false;
|
|
526
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-SDB1', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.databaseConnect, error, 503);
|
|
527
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
528
|
+
resolve();
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-SDB2', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.databaseRuntime, error, 503);
|
|
532
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
try {
|
|
536
|
+
this.mongoose.connect(this._params.dbUri, this._params.dbOptions
|
|
537
|
+
/* {
|
|
538
|
+
directConnection: true,
|
|
539
|
+
} */
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
544
|
+
...this._getDefaultErrorSettings('startDB', error),
|
|
545
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB3`,
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
552
|
+
...this._getDefaultErrorSettings('startDB', error),
|
|
553
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SDB0`,
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
// 2026-06-20 — Mongo reconnect-guard. A MongoDB-driver a hostnevet connect-kor EGYSZER
|
|
557
|
+
// resolválja + cache-eli az IP-t; ha a Mongo-konténert recreate-elik (új docker-network IP),
|
|
558
|
+
// a driver a HALOTT IP-n ragad → ECONNREFUSED + buffering-timeout, és a service magától SOHA
|
|
559
|
+
// nem áll vissza. A guard sustained-disconnect (readyState !== 1) esetén — a driver saját
|
|
560
|
+
// grace-e UTÁN — TELJES disconnect()+connect()-et csinál → ÚJ MongoClient → ÚJ DNS-resolve →
|
|
561
|
+
// új IP → reconnect. Best-effort, always-on, healthy connection-t (===1) SOHA nem bánt; csak
|
|
562
|
+
// konténer-IP-frissítés, nem ír adatot. Lásd: mongo-reconnect-guard.util.ts.
|
|
563
|
+
try {
|
|
564
|
+
(0, mongo_reconnect_guard_util_1.startMongoReconnectGuard)({
|
|
565
|
+
getReadyState: () => this.mongoose.connection.readyState,
|
|
566
|
+
reconnect: async () => {
|
|
567
|
+
await this.mongoose.disconnect().catch(() => undefined);
|
|
568
|
+
await this.mongoose.connect(this._params.dbUri, this._params.dbOptions);
|
|
569
|
+
},
|
|
570
|
+
log: (msg) => {
|
|
571
|
+
this.reportSafeDiagnostic('DYNTS-AS0-MONGO-RECONNECT-EVENT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard, msg, 503);
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
catch (guardErr) {
|
|
576
|
+
this.reportSafeDiagnostic('DYNTS-AS0-MONGO-RECONNECT-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.mongoReconnectGuard, guardErr, 503);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* FR-258 / SR-2 — install MongoDB TTL indexes for every data-model that declared `retention`.
|
|
581
|
+
*
|
|
582
|
+
* Runs ONCE right after the DB connection opens. For each registered DB service (including the
|
|
583
|
+
* auto-created `_archived` siblings, which inherit the parent model's `retention`), it ensures a
|
|
584
|
+
* TTL index on the `__created` Date field with the resolved `expireAfterSeconds` — so MongoDB
|
|
585
|
+
* NATIVELY auto-deletes documents older than the configured age. This is the fleet-wide defense
|
|
586
|
+
* against the unbounded-collection-growth → in-memory-load → GC-thrash/OOM class.
|
|
587
|
+
*
|
|
588
|
+
* Guarantees:
|
|
589
|
+
* - **Non-fatal** — any error is logged but NEVER blocks startup (called fire-and-forget).
|
|
590
|
+
* - **Idempotent** — an existing index with the same TTL is a no-op; a CHANGED retention (different
|
|
591
|
+
* `expireAfterSeconds`, or an existing non-TTL `__created` index) is reconciled by drop+recreate
|
|
592
|
+
* (the field index is restored immediately, so query coverage is preserved).
|
|
593
|
+
*/
|
|
594
|
+
async installRetentionTtlIndexes() {
|
|
595
|
+
try {
|
|
596
|
+
const services = global_service_1.DyNTS_GlobalService.getAllDBServices();
|
|
597
|
+
let ensured = 0;
|
|
598
|
+
for (const service of services) {
|
|
599
|
+
const ttlSeconds = (0, fsm_dynamo_1.DyFM_resolveRetentionTtlSeconds)(service?.dataParams?.retention);
|
|
600
|
+
if (!ttlSeconds) {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const dataName = service.dataParams.dataName;
|
|
604
|
+
// The mongoose Model exposes the native driver collection (.indexes / .createIndex / .dropIndex).
|
|
605
|
+
const collection = service?.dataModel?.collection;
|
|
606
|
+
if (!collection || typeof collection.createIndex !== 'function') {
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
try {
|
|
610
|
+
const action = await DyNTS_App.ensureRetentionTtlIndex(collection, ttlSeconds);
|
|
611
|
+
if (action === 'created') {
|
|
612
|
+
ensured++;
|
|
613
|
+
if (this.logSetup) {
|
|
614
|
+
fsm_dynamo_1.DyFM_Log.success(`[FR-258 retention] TTL index created on "${dataName}" — ` +
|
|
615
|
+
`${Math.round(ttlSeconds / 86400)}d (${ttlSeconds}s)`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else if (action === 'differs') {
|
|
619
|
+
// Live index has a different TTL — left untouched at boot (see ensureRetentionTtlIndex doc).
|
|
620
|
+
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INDEX-DIFFERS', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, new Error('retention-index-differs'));
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
catch (idxErr) {
|
|
624
|
+
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INDEX-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, idxErr);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (ensured > 0) {
|
|
628
|
+
fsm_dynamo_1.DyFM_Log.success(`[FR-258 retention] ${ensured} TTL index(es) ensured (auto-retention active).`);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
catch (err) {
|
|
632
|
+
this.reportSafeDiagnostic('DYNTS-AS0-RETENTION-INSTALLER-FAILED', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.retention, err);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* FR-258 / SR-2 — ensure a single `{ __created: 1 }` TTL index with the given `expireAfterSeconds`.
|
|
637
|
+
* Extracted as a pure-ish static so it is unit-testable with a mock collection. Idempotent + BOOT-SAFE:
|
|
638
|
+
* - no existing `__created` index → create it → `'created'`
|
|
639
|
+
* - existing with the SAME TTL → no-op → `'noop'`
|
|
640
|
+
* - existing with a DIFFERENT TTL / non-TTL → leave it as-is → `'differs'` (warn only — NO drop+recreate)
|
|
641
|
+
*
|
|
642
|
+
* The `'differs'` case intentionally does NOT mutate the live index. Dropping + recreating a TTL index on a
|
|
643
|
+
* large (multi-GB) production collection is a heavy server-side operation; doing it automatically inside the
|
|
644
|
+
* startup path can starve the concurrent boot queries (including the deploy health-probe) and trigger a
|
|
645
|
+
* fail-safe revert. Create-if-missing is the essential growth-prevention behaviour; a deliberate retention
|
|
646
|
+
* CHANGE on an already-indexed collection is a maintenance action, not a silent every-boot rebuild.
|
|
647
|
+
*/
|
|
648
|
+
static async ensureRetentionTtlIndex(collection, ttlSeconds) {
|
|
649
|
+
const existingList = typeof collection.indexes === 'function'
|
|
650
|
+
? await collection.indexes().catch(() => [])
|
|
651
|
+
: [];
|
|
652
|
+
const existing = existingList.find((ix) => !!ix?.key && ix.key.__created === 1);
|
|
653
|
+
if (!existing) {
|
|
654
|
+
await collection.createIndex({ __created: 1 }, { expireAfterSeconds: ttlSeconds });
|
|
655
|
+
return 'created';
|
|
656
|
+
}
|
|
657
|
+
if (existing.expireAfterSeconds === ttlSeconds) {
|
|
658
|
+
return 'noop';
|
|
659
|
+
}
|
|
660
|
+
// Retention differs from the live index (or it is a non-TTL `__created` index). Leave it UNTOUCHED at
|
|
661
|
+
// boot — only report it. Avoids a heavy drop+recreate competing with boot-readiness on a large collection.
|
|
662
|
+
return 'differs';
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
*
|
|
666
|
+
*/
|
|
667
|
+
async initExpresses() {
|
|
668
|
+
if (this.fnLogs && this.deepLog)
|
|
669
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. initExpresses');
|
|
670
|
+
try {
|
|
671
|
+
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
672
|
+
if (this._portSettings.httpPort === undefined || this._portSettings.httpPort === null) {
|
|
673
|
+
let errorMsg = `\nYou have open routes, but httpPort is not set!` +
|
|
674
|
+
`\nThere are ${this._routingModules.filter(m => m.security != route_security_enum_1.DyNTS_RouteSecurity.secure).length} open/both routes` +
|
|
675
|
+
`\nroot security: ${this._security}` +
|
|
676
|
+
`\nset httpPort in DynamoBEServer - setupRoutingModules() to enable secure routes.`;
|
|
677
|
+
errorMsg += '\n\nThe routes setted to use open server:';
|
|
678
|
+
this._routingModules.forEach((module) => {
|
|
679
|
+
if (module.security != route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
680
|
+
errorMsg += `\n ${module.route} (security: ${module.security})`;
|
|
681
|
+
errorMsg += `\n subroutes using open sever:`;
|
|
682
|
+
module.endpoints.forEach((endpoint) => {
|
|
683
|
+
if (endpoint.security != route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
684
|
+
errorMsg += `\n ${endpoint.endpoint} (security: ${endpoint.security})`;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
const error = new Error(`Open routes cannot be established!\n${errorMsg}`);
|
|
690
|
+
const errorStack = error.stack.split('\n');
|
|
691
|
+
errorStack.splice(1, 2);
|
|
692
|
+
error.stack = errorStack.join('\n');
|
|
693
|
+
this.reportSafeDiagnostic('DYNTS-AS0-OPEN-ROUTE-CONFIGURATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
694
|
+
throw error;
|
|
695
|
+
}
|
|
696
|
+
await this.initOpenExpress();
|
|
697
|
+
}
|
|
698
|
+
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
699
|
+
if (!this._cert || !this._portSettings.httpsPort) {
|
|
700
|
+
let errorMsg = `\nYou have secure routes, but the certification paths or httpsPort are not set!` +
|
|
701
|
+
`\nThere are ${this._routingModules.filter(m => m.security && m.security !== route_security_enum_1.DyNTS_RouteSecurity.open).length} secure routes` +
|
|
702
|
+
`\nroot security: ${this._security}` +
|
|
703
|
+
`\nset...` +
|
|
704
|
+
`\n(missing exact howto...)` +
|
|
705
|
+
/* `\n httpsPort and` +
|
|
706
|
+
`\n cert: {` +
|
|
707
|
+
`\n keyPath: FileSystem.PathLike,` +
|
|
708
|
+
`\n certPath: FileSystem.PathLike,` +
|
|
709
|
+
`\n }` + */
|
|
710
|
+
`\nin DynamoBEServer - getRoutingModules() to enable secure routes.`;
|
|
711
|
+
errorMsg += '\n\nThe routes setted to use secure server:';
|
|
712
|
+
this._routingModules.forEach((module) => {
|
|
713
|
+
if (module.security && module.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
714
|
+
errorMsg += `\n ${module.route} (security: ${module.security})`;
|
|
715
|
+
errorMsg += `\n location: ${module.stackLocation}`;
|
|
716
|
+
errorMsg += `\n subroutes using secure sever:`;
|
|
717
|
+
module.endpoints.forEach((endpoint) => {
|
|
718
|
+
if (endpoint.security && endpoint.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
719
|
+
errorMsg += `\n ${endpoint.endpoint} (security: ${endpoint.security})`;
|
|
720
|
+
errorMsg += `\n location: ${endpoint.stackLocation}`;
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
const error = new Error(`Secure routes cannot be established!\n${errorMsg}`);
|
|
726
|
+
const errorStack = error.stack.split('\n');
|
|
727
|
+
errorStack.splice(1, 2);
|
|
728
|
+
error.stack = errorStack.join('\n');
|
|
729
|
+
this.reportSafeDiagnostic('DYNTS-AS0-SECURE-ROUTE-CONFIGURATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
730
|
+
throw error;
|
|
731
|
+
}
|
|
732
|
+
await this.initSecureExpress();
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
catch (error) {
|
|
736
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
737
|
+
...this._getDefaultErrorSettings('initExpresses', error),
|
|
738
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-IE0`,
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
*
|
|
744
|
+
*/
|
|
745
|
+
async initOpenExpress() {
|
|
746
|
+
if (this.fnLogs)
|
|
747
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. initOpenExpress');
|
|
748
|
+
this.openExpress = Express();
|
|
749
|
+
this.openExpress.set('maxHeaderSize', 10 * fsm_dynamo_1.megabyte); // 1024 * 1024 * 10, // 10MB
|
|
750
|
+
this.openExpress.use(BodyParser.urlencoded(this._portSettings.httpUrlencoded));
|
|
751
|
+
this.openExpress.use(BodyParser.json(this._portSettings.httpJson));
|
|
752
|
+
// BFR-011 / SEC-R2-8 — security headerek a CORS ELŐTT (az OPTIONS preflight-válaszok is kapják).
|
|
753
|
+
this.mountSecurityHeaders(this.openExpress);
|
|
754
|
+
// FR-041 — CORS allowlist enforcement. No-op if getCorsSettings() is not overridden.
|
|
755
|
+
this.mountCors(this.openExpress);
|
|
756
|
+
// FR-292 — a deployolt app-verzio minden valaszon. A CORS UTAN kell, mert az
|
|
757
|
+
// `Access-Control-Expose-Headers`-hoz HOZZAFUZ (kulonben a CORS felulirna).
|
|
758
|
+
this.mountAppVersionHeader(this.openExpress);
|
|
759
|
+
// BFR-OVERSEER-009 — opt-in auto-load-shed 503 CRITICAL memória-nyomásnál (esszenciális utak kivételével).
|
|
760
|
+
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.loadShedEnabled) {
|
|
761
|
+
this.openExpress.use((0, load_shed_util_1.DyNTS_createLoadShedMiddleware)());
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
*
|
|
766
|
+
*/
|
|
767
|
+
async initSecureExpress() {
|
|
768
|
+
if (this.fnLogs)
|
|
769
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. initSecureExpress');
|
|
770
|
+
this.secureExpress = Express();
|
|
771
|
+
this.secureExpress.use(BodyParser.urlencoded(this._portSettings.httpsUrlencoded));
|
|
772
|
+
this.secureExpress.use(BodyParser.json(this._portSettings.httpsJson));
|
|
773
|
+
// BFR-011 / SEC-R2-8 — security headerek a CORS ELŐTT (mint az open expressen).
|
|
774
|
+
this.mountSecurityHeaders(this.secureExpress);
|
|
775
|
+
// FR-041 — CORS allowlist enforcement (same as open express).
|
|
776
|
+
this.mountCors(this.secureExpress);
|
|
777
|
+
// FR-292 — a deployolt app-verzio minden valaszon (mint az open expressen).
|
|
778
|
+
this.mountAppVersionHeader(this.secureExpress);
|
|
779
|
+
// BFR-OVERSEER-009 — opt-in auto-load-shed 503 (mint az open expressen).
|
|
780
|
+
if (global_settings_const_1.DyNTS_global_settings.memoryGuard?.loadShedEnabled) {
|
|
781
|
+
this.secureExpress.use((0, load_shed_util_1.DyNTS_createLoadShedMiddleware)());
|
|
782
|
+
}
|
|
783
|
+
const options = {
|
|
784
|
+
key: FileSystem.readFileSync(this._cert.keyPath),
|
|
785
|
+
cert: FileSystem.readFileSync(this._cert.certPath),
|
|
786
|
+
maxHeaderSize: 10 * fsm_dynamo_1.megabyte, // 1024 * 1024 * 10, // 10MB
|
|
787
|
+
};
|
|
788
|
+
this.httpsServer = Https.createServer(options, this.secureExpress);
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
*
|
|
792
|
+
*/
|
|
793
|
+
async startExpresses() {
|
|
794
|
+
if (this.fnLogs && this.deepLog)
|
|
795
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. startExpresses');
|
|
796
|
+
try {
|
|
797
|
+
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
798
|
+
await new Promise((resolve, reject) => {
|
|
799
|
+
this.systemControls.httpsServer.init = true;
|
|
800
|
+
this.httpsServer
|
|
801
|
+
.listen(this._portSettings.httpsPort, this.params.secureHost, this.params.expressBacklog, () => {
|
|
802
|
+
this.systemControls.httpsServer.started = true;
|
|
803
|
+
fsm_dynamo_1.DyFM_Log.success(`\nHTTPS (secure) server is listening on port: ` +
|
|
804
|
+
`${this.params.secureHost}:${this._portSettings.httpsPort}`);
|
|
805
|
+
resolve();
|
|
806
|
+
})
|
|
807
|
+
.on('error', (error) => {
|
|
808
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTPS-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpsServer, error, 503);
|
|
809
|
+
if (!this.systemControls.httpsServer.started) {
|
|
810
|
+
const d_error = new fsm_dynamo_1.DyFM_Error({
|
|
811
|
+
...this._getDefaultErrorSettings('startExpresses', error),
|
|
812
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE1`,
|
|
813
|
+
message: `HTTPS (secure) start server ERROR`,
|
|
814
|
+
});
|
|
815
|
+
this.constructErrors.push(d_error);
|
|
816
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
817
|
+
reject(d_error);
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
821
|
+
}
|
|
822
|
+
})
|
|
823
|
+
.on('uncaughtException', (exception) => {
|
|
824
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTPS-UNCAUGHT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpsServer, exception);
|
|
825
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
826
|
+
});
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
if (this._security && this._security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
830
|
+
this.systemControls.httpServer.init = true;
|
|
831
|
+
await new Promise((resolve, reject) => {
|
|
832
|
+
this.httpServer = this.openExpress
|
|
833
|
+
.listen(this._portSettings.httpPort, this.params.openHost, this.params.expressBacklog, () => {
|
|
834
|
+
this.systemControls.httpServer.started = true;
|
|
835
|
+
const resolvedPort = this.httpServer?.address?.()?.['port'] ?? this._portSettings.httpPort;
|
|
836
|
+
if (this._portSettings.httpPort === 0) {
|
|
837
|
+
fsm_dynamo_1.DyFM_Log.H_warn(`\nHTTP (open) server is using a randomly selected port by the OS: ${resolvedPort}` +
|
|
838
|
+
`\n (httpPort was set to 0 — this is intended for testing only)`);
|
|
839
|
+
}
|
|
840
|
+
fsm_dynamo_1.DyFM_Log.success(`\nHTTP (open) server is listening on port: ` +
|
|
841
|
+
`${this.params.openHost}:${resolvedPort}`);
|
|
842
|
+
resolve();
|
|
843
|
+
})
|
|
844
|
+
.on('error', (error) => {
|
|
845
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTP-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpServer, error, 503);
|
|
846
|
+
if (!this.systemControls.httpServer.started) {
|
|
847
|
+
const d_error = new fsm_dynamo_1.DyFM_Error({
|
|
848
|
+
...this._getDefaultErrorSettings('startExpresses', error),
|
|
849
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE3`,
|
|
850
|
+
message: `HTTP (open) start server ERROR`,
|
|
851
|
+
});
|
|
852
|
+
this.constructErrors.push(d_error);
|
|
853
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
854
|
+
reject(d_error);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
858
|
+
}
|
|
859
|
+
})
|
|
860
|
+
.on('uncaughtException', (exception) => {
|
|
861
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-HTTP-UNCAUGHT', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.httpServer, exception);
|
|
862
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
863
|
+
});
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
catch (error) {
|
|
868
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
869
|
+
...this._getDefaultErrorSettings('startExpresses', error),
|
|
870
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-SE0`,
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
*
|
|
876
|
+
*/
|
|
877
|
+
async expressErrorHandling(error, req, res, next) {
|
|
878
|
+
try {
|
|
879
|
+
if (error) {
|
|
880
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback, error);
|
|
881
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
882
|
+
// Kliens-safe strip (BFR-FDPAUTHSERVICE-002): az express-error út eddig NYERS error-t küldött
|
|
883
|
+
// (0 strip) — DyFM-nél belső stack/verzió/issuer, axios-jellegű error-nál akár auth-header is
|
|
884
|
+
// kimehetett. A strip-szabályok SSOT-ja a DyNTS_ClientSafeError_Util.
|
|
885
|
+
res.send(client_safe_error_util_1.DyNTS_ClientSafeError_Util.toClientSafe(error));
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-MISSING-ERROR', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback);
|
|
889
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
catch (error) {
|
|
893
|
+
const diagnostic = this.reportSafeDiagnostic('DYNTS-AS0-EXPRESS-MULTILEVEL', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.expressFallback, error);
|
|
894
|
+
this.forwardSafeDiagnostic(diagnostic);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
*
|
|
899
|
+
*/
|
|
900
|
+
async mountSecureRoutes() {
|
|
901
|
+
try {
|
|
902
|
+
if (this.fnLogs && this.deepLog)
|
|
903
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. mountSecureRoutes');
|
|
904
|
+
if (!this.secureExpress) {
|
|
905
|
+
throw new Error('secureExpress was not initialized. ' +
|
|
906
|
+
'Secure routes require getCertificationSettings and httpsPort, and cert files must exist.' +
|
|
907
|
+
'\n\nYou need to set security to secure or both in any route and set httpsPort in getPortSettings.' +
|
|
908
|
+
'\n\nYou need to set cert files in getCertificationSettings.');
|
|
909
|
+
}
|
|
910
|
+
this.secureExpress.use((error, req, res, next) => this.expressErrorHandling(error, req, res, next));
|
|
911
|
+
await fsm_dynamo_1.DyFM_Array.asyncForEach(this._routingModules, async (module) => {
|
|
912
|
+
if (module.security !== route_security_enum_1.DyNTS_RouteSecurity.open) {
|
|
913
|
+
if (this.logSetup) {
|
|
914
|
+
fsm_dynamo_1.DyFM_Log.log(`route mount (secure): ${module.route}`);
|
|
915
|
+
}
|
|
916
|
+
const existingRoutes = this._routingModules.filter((mod) => mod.route === module.route);
|
|
917
|
+
if (1 < existingRoutes.length) {
|
|
918
|
+
const error = new Error(`ROUTE DUPLICATION: ${module.route}`);
|
|
919
|
+
/* const errorStack: string[] = error.stack.split('\n');
|
|
920
|
+
|
|
921
|
+
errorStack.splice(1, 4);
|
|
922
|
+
error.stack = errorStack.join('\n'); */
|
|
923
|
+
error.stack = module.stackLocation;
|
|
924
|
+
this.reportSafeDiagnostic('DYNTS-AS0-SECURE-ROUTE-DUPLICATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
925
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
926
|
+
...this._getDefaultErrorSettings('mountSecureRoutes', error),
|
|
927
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MSR1`,
|
|
928
|
+
message: `ROUTE DUPLICATION: ${module.route}`,
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
this.secureExpress.use(module.route, module.secureRouter);
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
catch (error) {
|
|
936
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
937
|
+
...this._getDefaultErrorSettings('mountSecureRoutes', error),
|
|
938
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MSR0`,
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
*
|
|
944
|
+
*/
|
|
945
|
+
async mountOpenRoutes() {
|
|
946
|
+
try {
|
|
947
|
+
if (this.fnLogs && this.deepLog)
|
|
948
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. mountOpenRoutes');
|
|
949
|
+
if (!this.openExpress) {
|
|
950
|
+
throw new Error('openExpress was not initialized. Open routes require getOpenExpress and httpPort.' +
|
|
951
|
+
'\n\nYou need to set security to open or both in any route and set httpPort in getPortSettings.');
|
|
952
|
+
}
|
|
953
|
+
this.openExpress.use((error, req, res, next) => this.expressErrorHandling(error, req, res, next));
|
|
954
|
+
await fsm_dynamo_1.DyFM_Array.asyncForEach(this._routingModules, async (module) => {
|
|
955
|
+
if (module.security !== route_security_enum_1.DyNTS_RouteSecurity.secure) {
|
|
956
|
+
if (this.logSetup) {
|
|
957
|
+
fsm_dynamo_1.DyFM_Log.log(`route mount (open): ${module.route}`);
|
|
958
|
+
}
|
|
959
|
+
const existingRoutes = this._routingModules.filter((mod) => mod.route === module.route);
|
|
960
|
+
if (1 < existingRoutes.length) {
|
|
961
|
+
const error = new Error(`ROUTE DUPLICATION: ${module.route}`);
|
|
962
|
+
/* const errorStack: string[] = error.stack.split('\n');
|
|
963
|
+
|
|
964
|
+
errorStack.splice(1, 4);
|
|
965
|
+
error.stack = errorStack.join('\n'); */
|
|
966
|
+
error.stack = module.stackLocation;
|
|
967
|
+
this.reportSafeDiagnostic('DYNTS-AS0-OPEN-ROUTE-DUPLICATION', safe_diagnostic_stage_type_enum_1.DyNTS_SafeDiagnosticStage_Type.routing, error);
|
|
968
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
969
|
+
...this._getDefaultErrorSettings('mountOpenRoutes', error),
|
|
970
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MOR1`,
|
|
971
|
+
message: `ROUTE DUPLICATION: ${module.route}`,
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
this.openExpress.use(module.route, module.openRouter);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
catch (error) {
|
|
979
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
980
|
+
...this._getDefaultErrorSettings('mountOpenRoutes', error),
|
|
981
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-AS0-MOR0`,
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* FR-041 — CORS middleware. Echoes a matching `Access-Control-Allow-Origin`
|
|
987
|
+
* for any request whose Origin header is in `getCorsSettings().allowedOrigins`,
|
|
988
|
+
* adds the canonical `Access-Control-*` companion headers, and short-circuits
|
|
989
|
+
* the OPTIONS preflight with a 204.
|
|
990
|
+
*
|
|
991
|
+
* No-op when the subclass does NOT override `getCorsSettings()` — preserves
|
|
992
|
+
* back-compat for apps that have always been same-origin and never needed
|
|
993
|
+
* CORS (the typical pre-FR-041 case).
|
|
994
|
+
*
|
|
995
|
+
* Why hand-rolled instead of the `cors` npm package:
|
|
996
|
+
* - ~30 lines, zero new dependency.
|
|
997
|
+
* - Full control over Vary/credentials/preflight semantics.
|
|
998
|
+
* - Aligns with FDP "no unnecessary deps" philosophy.
|
|
999
|
+
*/
|
|
1000
|
+
/**
|
|
1001
|
+
* BFR-011 / SEC-R2-8 — security response-headerek mountolása (a `mountCors` tükörképe).
|
|
1002
|
+
* A `DyNTS_global_settings.securityHeaders` alapján (default-ON) minden válaszra ráteszi a
|
|
1003
|
+
* biztonsági headereket + eltávolítja az `x-powered-by`-t. A CORS-mount ELŐTT hívandó, hogy az
|
|
1004
|
+
* OPTIONS preflight-válaszok (amiket a mountCors 204-gyel rövidre zár) is megkapják.
|
|
1005
|
+
*/
|
|
1006
|
+
mountSecurityHeaders(express) {
|
|
1007
|
+
const settings = global_settings_const_1.DyNTS_global_settings.securityHeaders;
|
|
1008
|
+
if (!settings || !settings.enabled) {
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
if (settings.removePoweredBy !== false) {
|
|
1012
|
+
express.disable('x-powered-by');
|
|
1013
|
+
}
|
|
1014
|
+
express.use((0, security_headers_util_1.DyNTS_createSecurityHeadersMiddleware)(settings, (0, get_environment_settings_util_1.DyNTS_getEnvironment_settings)().environment));
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* FR-292 — a deployolt app-verziot minden valaszra rateszi (`X-App-Version`), hogy a
|
|
1018
|
+
* bongeszoben NYITVA HAGYOTT SPA eszrevegye, ha kozben ujabb kliens-build ment ki.
|
|
1019
|
+
*
|
|
1020
|
+
* Nem polling: a jelzes a MAR MENO API-hivasokon utazik. Az `enabled` default TRUE — egy
|
|
1021
|
+
* informativ response-header, ami se PII-t, se belso reszletet nem szivarogtat, viszont
|
|
1022
|
+
* enelkul minden app kulon-kulon epitene ugyanezt.
|
|
1023
|
+
*/
|
|
1024
|
+
mountAppVersionHeader(express) {
|
|
1025
|
+
const settings = global_settings_const_1.DyNTS_global_settings.appVersionHeader;
|
|
1026
|
+
if (settings?.enabled === false) {
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
express.use((0, app_version_header_util_1.DyNTS_createAppVersionHeaderMiddleware)(() => global_settings_const_1.DyNTS_global_settings.systemVersion, settings?.headerName));
|
|
1030
|
+
}
|
|
1031
|
+
mountCors(express) {
|
|
1032
|
+
const settings = this.getCorsSettings?.();
|
|
1033
|
+
if (!settings) {
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
const allowCreds = settings.allowCredentials !== false;
|
|
1037
|
+
const methods = settings.allowedMethods ?? [
|
|
1038
|
+
'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS',
|
|
1039
|
+
];
|
|
1040
|
+
const headers = settings.allowedHeaders ?? [
|
|
1041
|
+
'Authorization', 'Content-Type', 'X-Admin-Key', 'X-Requested-With',
|
|
1042
|
+
];
|
|
1043
|
+
const exposed = settings.exposedHeaders ?? [
|
|
1044
|
+
'Content-Length', 'Content-Type',
|
|
1045
|
+
];
|
|
1046
|
+
const maxAge = settings.maxAgeSeconds ?? 86400;
|
|
1047
|
+
const isAllowed = (origin) => {
|
|
1048
|
+
if (settings.allowedOrigins === '*')
|
|
1049
|
+
return true;
|
|
1050
|
+
if (typeof settings.allowedOrigins === 'function') {
|
|
1051
|
+
return settings.allowedOrigins(origin);
|
|
1052
|
+
}
|
|
1053
|
+
return settings.allowedOrigins.includes(origin);
|
|
1054
|
+
};
|
|
1055
|
+
express.use((req, res, next) => {
|
|
1056
|
+
const origin = req.headers.origin;
|
|
1057
|
+
if (origin && isAllowed(origin)) {
|
|
1058
|
+
// Echo the matching origin (NOT wildcard) because credentials require it.
|
|
1059
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
1060
|
+
if (allowCreds) {
|
|
1061
|
+
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
1062
|
+
}
|
|
1063
|
+
res.setHeader('Access-Control-Allow-Methods', methods.join(', '));
|
|
1064
|
+
res.setHeader('Access-Control-Allow-Headers', headers.join(', '));
|
|
1065
|
+
res.setHeader('Access-Control-Expose-Headers', exposed.join(', '));
|
|
1066
|
+
res.setHeader('Access-Control-Max-Age', String(maxAge));
|
|
1067
|
+
res.setHeader('Vary', 'Origin');
|
|
1068
|
+
}
|
|
1069
|
+
if (req.method === 'OPTIONS') {
|
|
1070
|
+
res.status(204).end();
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
next();
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Generikus, auth-agnosztikus extension-point orchestrator. A `registerCustomMiddleware`
|
|
1078
|
+
* hookot hívja (ha a subclass override-olja) minden AKTÍV Express instance-ra
|
|
1079
|
+
* (open + secure), az API route-ok UTÁN, de a SPA static catch-all (`app.get('*')`)
|
|
1080
|
+
* ELŐTT — ez az EGYETLEN korrekt pont egy sub-path middleware-hez (pl. reverse-proxy),
|
|
1081
|
+
* mert a catch-all minden utána mountolt route-ot elnyel. No-op ha nincs override (back-compat).
|
|
1082
|
+
*/
|
|
1083
|
+
async mountCustomMiddleware() {
|
|
1084
|
+
if (!this.registerCustomMiddleware) {
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
if (this.openExpress) {
|
|
1088
|
+
await this.registerCustomMiddleware(this.openExpress, route_security_enum_1.DyNTS_RouteSecurity.open);
|
|
1089
|
+
}
|
|
1090
|
+
if (this.secureExpress) {
|
|
1091
|
+
await this.registerCustomMiddleware(this.secureExpress, route_security_enum_1.DyNTS_RouteSecurity.secure);
|
|
1092
|
+
}
|
|
1093
|
+
if (this.logSetup) {
|
|
1094
|
+
fsm_dynamo_1.DyFM_Log.log('\nCustom middleware registered (pre-static).');
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Ha getStaticClientSettings() visszaad beállításokat, a client static fájlok a '/' alatt
|
|
1099
|
+
* lesznek kiszolgálva (API route-ok után). SPA fallback opcionális (fallbackPath).
|
|
1100
|
+
* Asset cache (assetCacheMaxAge, assetCacheImmutable) és fallback cache (fallbackCacheMaxAge)
|
|
1101
|
+
* opcionálisak; ha nincs megadva fallbackCacheMaxAge, DyNTS_defaultFallbackCacheMaxAge (0) marad.
|
|
1102
|
+
*/
|
|
1103
|
+
async mountStaticClient() {
|
|
1104
|
+
const settings = this.getStaticClientSettings?.();
|
|
1105
|
+
if (!settings) {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const absoluteRoot = Path.isAbsolute(settings.root)
|
|
1109
|
+
? settings.root
|
|
1110
|
+
: Path.resolve(process.cwd(), settings.root);
|
|
1111
|
+
const hasAssetCache = settings.assetCacheMaxAge !== undefined || settings.assetCacheImmutable === true;
|
|
1112
|
+
const staticOptions = hasAssetCache && settings.assetCacheMaxAge !== undefined
|
|
1113
|
+
? {
|
|
1114
|
+
setHeaders: (res, filePath) => {
|
|
1115
|
+
// A HTML entry-fájlok (index.html) no-cache-t kapnak, a hash-elt asset-ek
|
|
1116
|
+
// immutable long-cache-t — lásd DyNTS_resolveStaticCacheControlHeader (served-stale-index fix).
|
|
1117
|
+
res.setHeader('Cache-Control', (0, static_cache_control_util_1.DyNTS_resolveStaticCacheControlHeader)({
|
|
1118
|
+
filePath: filePath,
|
|
1119
|
+
assetCacheMaxAge: settings.assetCacheMaxAge,
|
|
1120
|
+
assetCacheImmutable: settings.assetCacheImmutable === true,
|
|
1121
|
+
}));
|
|
1122
|
+
},
|
|
1123
|
+
}
|
|
1124
|
+
: undefined;
|
|
1125
|
+
const staticMiddleware = staticOptions
|
|
1126
|
+
? Express.static(absoluteRoot, staticOptions)
|
|
1127
|
+
: Express.static(absoluteRoot);
|
|
1128
|
+
const fallbackMaxAge = settings.fallbackCacheMaxAge ?? default_fallback_cache_max_age_const_1.DyNTS_defaultFallbackCacheMaxAge;
|
|
1129
|
+
// API-namespace guard (BFR-DYNAMOBUILDER-001): a catch-all fallback NE fedje az API-prefixeket —
|
|
1130
|
+
// egy ismeretlen `GET /api/...` 404 JSON-t kapjon, ne megtévesztő `200 + index.html`-t.
|
|
1131
|
+
// Konfigurálható (fallbackExcludePrefixes); default a bevett FDP namespace-pár.
|
|
1132
|
+
const excludePrefixes = settings.fallbackExcludePrefixes ?? ['/api', '/auth-api'];
|
|
1133
|
+
const isApiNamespacePath = (path) => excludePrefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
|
|
1134
|
+
if (this.openExpress) {
|
|
1135
|
+
this.openExpress.use('/', staticMiddleware);
|
|
1136
|
+
if (settings.fallbackPath) {
|
|
1137
|
+
this.openExpress.get('*', (req, res) => {
|
|
1138
|
+
if (isApiNamespacePath(req.path)) {
|
|
1139
|
+
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1143
|
+
res.sendFile(settings.fallbackPath, { root: absoluteRoot });
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
this.openExpress.get('*', (req, res) => {
|
|
1148
|
+
if (isApiNamespacePath(req.path)) {
|
|
1149
|
+
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
res.status(404).type('html').send(default_not_found_page_const_1.DyNTS_defaultNotFoundPageHtml);
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
if (this.secureExpress) {
|
|
1157
|
+
this.secureExpress.use('/', staticMiddleware);
|
|
1158
|
+
if (settings.fallbackPath) {
|
|
1159
|
+
this.secureExpress.get('*', (req, res) => {
|
|
1160
|
+
if (isApiNamespacePath(req.path)) {
|
|
1161
|
+
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
res.setHeader('Cache-Control', `max-age=${fallbackMaxAge}`);
|
|
1165
|
+
res.sendFile(settings.fallbackPath, { root: absoluteRoot });
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
else {
|
|
1169
|
+
this.secureExpress.get('*', (req, res) => {
|
|
1170
|
+
if (isApiNamespacePath(req.path)) {
|
|
1171
|
+
res.status(404).send({ message: `Unknown API endpoint: ${req.path}` });
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
res.status(404).type('html').send(default_not_found_page_const_1.DyNTS_defaultNotFoundPageHtml);
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
if (this.logSetup) {
|
|
1179
|
+
fsm_dynamo_1.DyFM_Log.log(`\nStatic client mounted at / (root: ${absoluteRoot})`);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
/**
|
|
1183
|
+
*
|
|
1184
|
+
*/
|
|
1185
|
+
setSecurity() {
|
|
1186
|
+
if (this.fnLogs && this.deepLog)
|
|
1187
|
+
fsm_dynamo_1.DyFM_Log.log('\nfn:. setSecurity');
|
|
1188
|
+
this._routingModules.forEach((module) => {
|
|
1189
|
+
if (!module.security) {
|
|
1190
|
+
fsm_dynamo_1.DyFM_Log.warn(`RoutingModule security is not set for ${module.route}\n`);
|
|
1191
|
+
}
|
|
1192
|
+
else if (!this._security) {
|
|
1193
|
+
this._security = module.security;
|
|
1194
|
+
}
|
|
1195
|
+
else if (this._security !== module.security) {
|
|
1196
|
+
this._security = route_security_enum_1.DyNTS_RouteSecurity.both;
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
if (!this._security) {
|
|
1200
|
+
let msg = `Could not set security for the server! (${this.security})`;
|
|
1201
|
+
msg += '\n RoutingModules:';
|
|
1202
|
+
this._routingModules.forEach((module) => {
|
|
1203
|
+
msg += `\n ${module.route} (security: ${module.security})`;
|
|
1204
|
+
});
|
|
1205
|
+
if (this._routingModules.length === 0) {
|
|
1206
|
+
msg += '\n - no RoutingModule found -\n';
|
|
1207
|
+
}
|
|
1208
|
+
fsm_dynamo_1.DyFM_Log.warn(msg);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
_getDefaultErrorSettings(fnName, error) {
|
|
1212
|
+
return {
|
|
1213
|
+
status: error?.___status ?? 500,
|
|
1214
|
+
message: error?.message ??
|
|
1215
|
+
error?._message ??
|
|
1216
|
+
`${fnName} was UNSUCCESSFUL (NTS)`,
|
|
1217
|
+
userMessage: error?.__userMessage ?? this.defaultErrorUserMsg,
|
|
1218
|
+
addECToUserMsg: !error?.__userMessage,
|
|
1219
|
+
issuerService: `${this?.constructor?.name}-DyNTS_App`,
|
|
1220
|
+
level: fsm_dynamo_1.DyFM_ErrorLevel.fatal,
|
|
1221
|
+
error: error,
|
|
1222
|
+
systemVersion: global_settings_const_1.DyNTS_global_settings.systemVersion,
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
exports.DyNTS_App = DyNTS_App;
|
|
1227
1227
|
//# sourceMappingURL=app.server.js.map
|