@futdevpro/nts-dynamo 1.15.15 → 1.15.16
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/.c8rc.json +26 -26
- package/.copilot/patterns.json +7 -7
- package/.cursor/rules/__assistant_guide.mdc +30 -30
- package/.cursor/rules/_ag_backend-structure.mdc +85 -85
- package/.cursor/rules/_ag_backend.mdc +16 -16
- package/.cursor/rules/_ag_frontend-structure.mdc +86 -86
- package/.cursor/rules/_ag_frontend.mdc +39 -39
- package/.cursor/rules/_ag_import-rules.mdc +44 -44
- package/.cursor/rules/_ag_naming.mdc +115 -115
- package/.cursor/rules/_ag_should-be.mdc +6 -6
- package/.cursor/rules/ai_development_guide.md +60 -60
- package/.cursor/rules/cursor-rules.md +160 -160
- package/.cursor/rules/default-command.mdc +464 -464
- package/.cursor/rules/error_code_pattern.md +39 -39
- package/.cursor/rules/saved rule mcp server use.md +15 -15
- package/.dynamo/version-bump.config.json +5 -0
- package/.github/workflows/main.yml +426 -393
- package/.husky/pre-commit +1 -0
- package/.vscode/settings.json +10 -10
- package/HOWTO.md +15 -15
- package/LICENSE +21 -21
- package/__documentations/2026-04-28-logs-module.md +49 -0
- package/__documentations/nts-integration-tests-2026-03-17.md +26 -26
- package/_specifications/BACKLOG.md +50 -50
- package/_specifications/TODO.md +15 -15
- package/_specifications/agent.md +138 -138
- package/eslint.config.js +3 -3
- package/nodemon.json +24 -24
- package/package.json +343 -362
- package/pipeline.cicd.config.json +152 -0
- package/scripts/run-coverage-tests.js +28 -28
- package/spec/support/helpers/spec-reporter-loader.js +359 -359
- package/spec/support/helpers/ts-node-helper.js +93 -93
- package/spec/support/jasmine.coverage.json +24 -24
- package/spec/support/jasmine.json +24 -24
- package/src/_collections/archive.util.spec.ts +57 -57
- package/src/_collections/archive.util.ts +18 -18
- package/src/_collections/atlas-default-db-options.const.ts +9 -9
- package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
- package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
- package/src/_collections/default-not-found-page.const.spec.ts +19 -19
- package/src/_collections/default-not-found-page.const.ts +22 -22
- package/src/_collections/default-socket-path.const.spec.ts +12 -12
- package/src/_collections/default-socket-path.const.ts +2 -2
- package/src/_collections/get-environment-settings.util.spec.ts +210 -210
- package/src/_collections/get-environment-settings.util.ts +48 -48
- package/src/_collections/sample.env +21 -21
- package/src/_collections/star.controller.spec.ts +224 -224
- package/src/_collections/star.controller.ts +129 -129
- package/src/_enums/data-model-type.enum.ts +14 -14
- package/src/_enums/data-service-function.enum.ts +24 -24
- package/src/_enums/predefined-data-types.enum.ts +16 -16
- package/src/_enums/route-security.enum.ts +12 -12
- package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
- package/src/_models/control-models/api-call-params.control-model.ts +142 -142
- package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
- package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
- package/src/_models/control-models/app-params.control-model.ts +136 -136
- package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
- package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/endpoint-params.control-model.spec.ts +578 -578
- package/src/_models/control-models/endpoint-params.control-model.ts +526 -526
- package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
- package/src/_models/control-models/http-settings.control-model.ts +37 -37
- package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
- package/src/_models/control-models/system-control.control-model.ts +12 -12
- package/src/_models/interfaces/certification-settings.interface.ts +7 -7
- package/src/_models/interfaces/environment-settings.interface.ts +59 -59
- package/src/_models/interfaces/global-log-settings.interface.ts +108 -108
- package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
- package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
- package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
- package/src/_models/interfaces/static-client-settings.interface.ts +28 -28
- package/src/_models/types/db-update.type.ts +100 -100
- package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
- package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
- package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
- package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
- package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
- package/src/_modules/ai/_modules/document-ai/index.ts +28 -28
- package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
- package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
- package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
- package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +240 -240
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.ts +98 -98
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +615 -615
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +437 -437
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +833 -833
- package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
- package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
- package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
- package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
- package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
- package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
- package/src/_modules/ai/_services/ai-llm.service-base.ts +332 -332
- package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +79 -79
- package/src/_modules/ai/_services/ai-provider.service-base.ts +29 -29
- package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
- package/src/_modules/ai/index.ts +13 -13
- package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
- package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
- package/src/_modules/assistant/_collections/ass.util.ts +50 -50
- package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
- package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
- package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
- package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
- package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
- package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
- package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
- package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
- package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
- package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
- package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
- package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
- package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
- package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
- package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
- package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
- package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
- package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
- package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
- package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
- package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
- package/src/_modules/custom-data/custom-data.controller.ts +67 -67
- package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
- package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
- package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
- package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
- package/src/_modules/custom-data/index.ts +9 -9
- package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
- package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
- package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
- package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
- package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
- package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
- package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
- package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
- package/src/_modules/defaults/index.ts +17 -17
- package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
- package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
- package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
- package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
- package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
- package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
- package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
- package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
- package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
- package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
- package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
- package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
- package/src/_modules/discord-assistant/index.ts +38 -38
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
- package/src/_modules/discord-assistant-voiced/index.ts +36 -36
- package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
- package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
- package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
- package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
- package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
- package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
- package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
- package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
- package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
- package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
- package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
- package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
- package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
- package/src/_modules/discord-bot/index.ts +36 -36
- package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +19 -19
- package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +345 -345
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +330 -330
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +393 -393
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +220 -220
- package/src/_modules/local-vector-search/index.ts +11 -11
- package/src/_modules/messaging/README.md +354 -354
- package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
- package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
- package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
- package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
- package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
- package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
- package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
- package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
- package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
- package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
- package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
- package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
- package/src/_modules/messaging/index.ts +30 -30
- package/src/_modules/mock/app-extended-server.mock.ts +201 -201
- package/src/_modules/mock/app-integration-test.mock.ts +51 -51
- package/src/_modules/mock/app-params.mock.spec.ts +21 -21
- package/src/_modules/mock/app-params.mock.ts +9 -9
- package/src/_modules/mock/app-server.mock.ts +188 -188
- package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
- package/src/_modules/mock/auth-service.mock.ts +28 -28
- package/src/_modules/mock/controller.mock.spec.ts +26 -26
- package/src/_modules/mock/controller.mock.ts +16 -16
- package/src/_modules/mock/data-model.mock.spec.ts +111 -111
- package/src/_modules/mock/data-model.mock.ts +82 -82
- package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
- package/src/_modules/mock/email-service-collection.mock.ts +15 -15
- package/src/_modules/mock/email-service.mock.spec.ts +17 -17
- package/src/_modules/mock/email-service.mock.ts +20 -20
- package/src/_modules/mock/email-template.mock.html +14 -14
- package/src/_modules/mock/endpoint.mock.ts +91 -91
- package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
- package/src/_modules/mock/socket-client.mock.ts +45 -45
- package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
- package/src/_modules/mock/socket-server.mock.ts +46 -46
- package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
- package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
- package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
- package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
- package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
- package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
- package/src/_modules/oauth2/index.ts +17 -17
- package/src/_modules/server/errors/errors.control-service.spec.ts +230 -230
- package/src/_modules/server/errors/errors.control-service.ts +69 -69
- package/src/_modules/server/errors/errors.controller.spec.ts +165 -165
- package/src/_modules/server/errors/errors.controller.ts +270 -270
- package/src/_modules/server/errors/errors.data-service.spec.ts +355 -355
- package/src/_modules/server/index.ts +30 -30
- package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
- package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
- package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
- package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
- package/src/_modules/server/server-status/server-status.control-service.spec.ts +516 -516
- package/src/_modules/server/server-status/server-status.control-service.ts +336 -336
- package/src/_modules/server/server-status/server-status.controller.spec.ts +156 -156
- package/src/_modules/server/server-status/server-status.controller.ts +131 -131
- package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
- package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
- package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
- package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
- package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +46 -46
- package/src/_modules/socket/_models/socket-server-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
- package/src/_modules/socket/_services/socket-client.service.ts +260 -260
- package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
- package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
- package/src/_modules/socket/app-extended.server.ts +630 -630
- package/src/_modules/socket/index.ts +42 -42
- package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
- package/src/_modules/test/get-test-routing-module.util.ts +23 -23
- package/src/_modules/test/index.ts +11 -11
- package/src/_modules/test/test.controller.spec.ts +72 -72
- package/src/_modules/test/test.controller.ts +115 -115
- package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
- package/src/_modules/usage/index.ts +15 -15
- package/src/_modules/usage/usage.controller.spec.ts +81 -81
- package/src/_modules/usage/usage.controller.ts +126 -126
- package/src/_modules/usage/usage.data-service.spec.ts +332 -332
- package/src/_modules/usage/usage.data-service.ts +185 -185
- package/src/_services/base/api.service-base.spec.ts +125 -125
- package/src/_services/base/api.service-base.ts +74 -74
- package/src/_services/base/archive-data.service.spec.ts +196 -196
- package/src/_services/base/archive-data.service.ts +216 -216
- package/src/_services/base/data.service.spec.ts +493 -493
- package/src/_services/base/data.service.ts +2525 -2525
- package/src/_services/base/db.service.spec.ts +73 -73
- package/src/_services/base/db.service.ts +1575 -1575
- package/src/_services/base/singleton.service-base.spec.ts +28 -28
- package/src/_services/base/singleton.service-base.ts +24 -24
- package/src/_services/base/singleton.service.spec.ts +114 -114
- package/src/_services/base/singleton.service.ts +38 -38
- package/src/_services/core/api.service.spec.ts +140 -140
- package/src/_services/core/auth.service.spec.ts +159 -159
- package/src/_services/core/auth.service.ts +174 -174
- package/src/_services/core/email.service.spec.ts +85 -85
- package/src/_services/core/email.service.ts +742 -742
- package/src/_services/core/global.service.spec.ts +275 -275
- package/src/_services/core/global.service.ts +461 -461
- package/src/_services/core/service-collection.service.spec.ts +46 -46
- package/src/_services/core/service-collection.service.ts +6 -6
- package/src/_services/route/controller.service.spec.ts +53 -53
- package/src/_services/route/controller.service.ts +148 -148
- package/src/_services/route/routing-module.service.spec.ts +98 -98
- package/src/_services/route/routing-module.service.ts +330 -330
- package/src/_services/shared.static-service.spec.ts +99 -99
- package/src/_services/shared.static-service.ts +78 -78
- package/src/index.ts +94 -94
- package/tsconfig.app.json +12 -12
- package/tsconfig.json +42 -42
- package/build/_modules/logs/get-logs-routing-module.util.d.ts +0 -19
- package/build/_modules/logs/get-logs-routing-module.util.d.ts.map +0 -1
- package/build/_modules/logs/get-logs-routing-module.util.js +0 -32
- package/build/_modules/logs/get-logs-routing-module.util.js.map +0 -1
- package/build/_modules/logs/index.d.ts +0 -4
- package/build/_modules/logs/index.d.ts.map +0 -1
- package/build/_modules/logs/index.js +0 -10
- package/build/_modules/logs/index.js.map +0 -1
- package/build/_modules/logs/log-buffer.service.d.ts +0 -38
- package/build/_modules/logs/log-buffer.service.d.ts.map +0 -1
- package/build/_modules/logs/log-buffer.service.js +0 -97
- package/build/_modules/logs/log-buffer.service.js.map +0 -1
- package/build/_modules/logs/logs.controller.d.ts +0 -27
- package/build/_modules/logs/logs.controller.d.ts.map +0 -1
- package/build/_modules/logs/logs.controller.js +0 -90
- package/build/_modules/logs/logs.controller.js.map +0 -1
- package/build/_modules/logs/logs.service.d.ts +0 -40
- package/build/_modules/logs/logs.service.d.ts.map +0 -1
- package/build/_modules/logs/logs.service.js +0 -97
- package/build/_modules/logs/logs.service.js.map +0 -1
- package/src/_modules/logs/get-logs-routing-module.util.ts +0 -36
- package/src/_modules/logs/index.ts +0 -3
- package/src/_modules/logs/log-buffer.service.ts +0 -101
- package/src/_modules/logs/logs.controller.ts +0 -109
- package/src/_modules/logs/logs.service.ts +0 -100
|
@@ -1,639 +1,639 @@
|
|
|
1
|
-
import { DyFM_Log, DyFM_Error, DyFM_AnyError, DyFM_Error_Settings } from '@futdevpro/fsm-dynamo';
|
|
2
|
-
import { DyNTS_global_settings } from '../../../../../_collections/global-settings.const';
|
|
3
|
-
import { DyNTS_DAI_DocChunk } from '../_models/data-models/dai-doc-chunk.data-model';
|
|
4
|
-
import { DyNTS_DAI_DocPage } from '../_models/data-models/dai-doc-page.data-model';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface DyNTS_DAI_DocChunking_Header {
|
|
8
|
-
level: number;
|
|
9
|
-
header: string;
|
|
10
|
-
index: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface DyNTS_DAI_DocChunking_BreakPoint {
|
|
14
|
-
index: number;
|
|
15
|
-
level: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* ClickUp dokumentum chunking szolgáltatás
|
|
20
|
-
* @author AI
|
|
21
|
-
* @description ClickUp dokumentumok intelligens chunking-ja a leghosszabb lehetséges chunk-ok létrehozásához
|
|
22
|
-
*/
|
|
23
|
-
export class DyNTS_DAI_DocChunking_Util {
|
|
24
|
-
|
|
25
|
-
protected static readonly defaultErrorUserMsg: string =
|
|
26
|
-
`We encountered an unhandled Control Service Error, ` +
|
|
27
|
-
`\nplease contact the responsible development team.`;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Unified break points configuration
|
|
31
|
-
*/
|
|
32
|
-
private static readonly breakPoints: { pattern: string, level: number, includeLength: number }[] = [
|
|
33
|
-
{ pattern: '\n# ', level: 1, includeLength: 0 }, // Header 1 - cut before marker
|
|
34
|
-
{ pattern: '\n## ', level: 2, includeLength: 0 }, // Header 2 - cut before marker
|
|
35
|
-
{ pattern: '\n### ', level: 3, includeLength: 0 }, // Header 3 - cut before marker
|
|
36
|
-
{ pattern: '\n#### ', level: 4, includeLength: 0 }, // Header 4 - cut before marker
|
|
37
|
-
{ pattern: '\n\n', level: 0, includeLength: 2 }, // Double line break - include
|
|
38
|
-
{ pattern: '\n', level: 0, includeLength: 1 }, // Single line break - include
|
|
39
|
-
{ pattern: '. ', level: 0, includeLength: 2 }, // Sentence end - include
|
|
40
|
-
{ pattern: ' ', level: 0, includeLength: 1 }, // Word break - include
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
protected static readonly debugLog: boolean = false;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Markdown tartalom chunking-ja a leghosszabb lehetséges chunk-ok létrehozásához
|
|
47
|
-
* @param page - ClickUp dokumentum oldal
|
|
48
|
-
* @param issuer - Kérés kezdeményezője
|
|
49
|
-
* @returns Promise<CU_DocChunk[]> - Létrehozott chunk-ok listája
|
|
50
|
-
*/
|
|
51
|
-
static async chunkMdContent<
|
|
52
|
-
T_Chunk extends DyNTS_DAI_DocChunk,
|
|
53
|
-
T_Page extends DyNTS_DAI_DocPage<T_Chunk>,
|
|
54
|
-
>(
|
|
55
|
-
page: T_Page,
|
|
56
|
-
getPageLink: (page: T_Page, issuer: string) => string,
|
|
57
|
-
issuer: string,
|
|
58
|
-
debugLog?: boolean
|
|
59
|
-
): Promise<T_Chunk[]> {
|
|
60
|
-
try {
|
|
61
|
-
if (debugLog) {
|
|
62
|
-
DyFM_Log.info(`Chunking page "${page.name}"...`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (page.content.includes('#####')) {
|
|
66
|
-
DyFM_Log.warn('lvl5+ headers are not supported yet for page: ' + page.name);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (!page.documentId) {
|
|
70
|
-
throw new DyFM_Error({
|
|
71
|
-
...this.getDefaultErrorSettings('chunkMdContent', new Error('Page documentId is not set'), issuer),
|
|
72
|
-
errorCode: 'CCAP-CUC-CC2',
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!page._id) {
|
|
77
|
-
throw new DyFM_Error({
|
|
78
|
-
...this.getDefaultErrorSettings('chunkMdContent', new Error('Page _id is not set'), issuer),
|
|
79
|
-
errorCode: 'CCAP-CUC-CC3',
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/* DyFM_Log.log(`Chunking page: ${page.name}\n\n`, JSON.stringify(page.content, null, 2)); */
|
|
84
|
-
|
|
85
|
-
let leftovers: string = page.content;
|
|
86
|
-
const maxChunkSize: number = DyNTS_global_settings.docChunking.maxChunkSize;
|
|
87
|
-
const maxChunkCount: number = DyNTS_global_settings.docChunking.maxChunkCount;
|
|
88
|
-
const chunks: T_Chunk[] = [];
|
|
89
|
-
let chunkIndex: number = 0;
|
|
90
|
-
let currentPosition: number = 0; // Track current position in original content
|
|
91
|
-
|
|
92
|
-
// Parse all headers to build hierarchy
|
|
93
|
-
const headerHierarchy: DyNTS_DAI_DocChunking_Header[] = this.parseHeaderHierarchy(leftovers);
|
|
94
|
-
|
|
95
|
-
// Debug: Log parsed headers
|
|
96
|
-
/* console.log('\n=== Parsed Header Hierarchy ===');
|
|
97
|
-
headerHierarchy.forEach((header, index) => {
|
|
98
|
-
console.log(`${index}: Level ${header.level} at position ${header.index}: "${header.header}"`);
|
|
99
|
-
});
|
|
100
|
-
console.log('=== End Header Hierarchy ===\n'); */
|
|
101
|
-
|
|
102
|
-
// Track the last headers of each level as we progress
|
|
103
|
-
const lastHeaders: Map<number, string> = new Map();
|
|
104
|
-
|
|
105
|
-
while (leftovers.length > 0 && chunkIndex < maxChunkCount) {
|
|
106
|
-
// Ha a teljes tartalom belefér egy chunk-ba, adjuk vissza az egészet
|
|
107
|
-
if (leftovers.length <= maxChunkSize) {
|
|
108
|
-
const chunkContent = leftovers.trim();
|
|
109
|
-
|
|
110
|
-
if (chunkContent.length > 0) {
|
|
111
|
-
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders);
|
|
112
|
-
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders);
|
|
113
|
-
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
114
|
-
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
115
|
-
|
|
116
|
-
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
117
|
-
externalDocumentId: page.externalDocumentId,
|
|
118
|
-
documentId: page.documentId,
|
|
119
|
-
externalPageId: page.externalPageId,
|
|
120
|
-
pageId: page._id,
|
|
121
|
-
|
|
122
|
-
filePathParents: page.parentedPath,
|
|
123
|
-
chunkHeadParents: headParents,
|
|
124
|
-
|
|
125
|
-
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
126
|
-
/* path: [ ...page.parentedPath, ...headParents ].join('/'), */
|
|
127
|
-
path: page.allFlaggedParentsMerged,
|
|
128
|
-
|
|
129
|
-
documentName: page.externalDocumentId,
|
|
130
|
-
pageName: page.name,
|
|
131
|
-
pageLink: getPageLink(page, issuer),
|
|
132
|
-
chunkIndex: chunkIndex,
|
|
133
|
-
|
|
134
|
-
chunkContent: chunkContent,
|
|
135
|
-
/* chunkOriginalContent: chunkContent,
|
|
136
|
-
|
|
137
|
-
chunkContent: chunkWithHierarchy, */
|
|
138
|
-
}) as T_Chunk;
|
|
139
|
-
|
|
140
|
-
if (this.debugLog || debugLog) {
|
|
141
|
-
DyFM_Log.H_info(
|
|
142
|
-
'Full content (before assembleChunkWithHeaders)',
|
|
143
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
144
|
-
{ chunk: chunk.chunkContent }
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
149
|
-
if (this.debugLog || debugLog) {
|
|
150
|
-
DyFM_Log.H_info(
|
|
151
|
-
'Full content (after assembleChunkWithHeaders)',
|
|
152
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
153
|
-
{
|
|
154
|
-
chunk: chunk.chunkContent,
|
|
155
|
-
}
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/* await DyFM_Async.wait(100_000); */
|
|
160
|
-
chunks.push(chunk);
|
|
161
|
-
}
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Keressük meg a legjobb break point-ot a maxChunkSize-n belül
|
|
166
|
-
const breakPoint: DyNTS_DAI_DocChunking_BreakPoint | null = this.findBestBreakPoint(leftovers, maxChunkSize);
|
|
167
|
-
|
|
168
|
-
if (breakPoint && breakPoint.index > 0) {
|
|
169
|
-
// Ha találtunk break point-ot, vágjunk a marker előtt
|
|
170
|
-
const chunkContent: string = leftovers.substring(0, breakPoint.index).trim();
|
|
171
|
-
|
|
172
|
-
// Debug: Log current state
|
|
173
|
-
/* console.log(`\n--- Creating chunk ${chunkIndex} ---`);
|
|
174
|
-
console.log(`Current position: ${currentPosition}`);
|
|
175
|
-
console.log(`Last headers:`, Object.fromEntries(lastHeaders));
|
|
176
|
-
console.log(`Chunk content preview:`, chunkContent.substring(0, 100) + '...'); */
|
|
177
|
-
|
|
178
|
-
// Check if chunk has headers
|
|
179
|
-
//const hasHeaders: boolean = headerHierarchy.some(header =>
|
|
180
|
-
// header.index >= currentPosition && header.index < currentPosition + breakPoint.index
|
|
181
|
-
//);
|
|
182
|
-
/* console.log(`Chunk has headers: ${hasHeaders}`); */
|
|
183
|
-
|
|
184
|
-
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders);
|
|
185
|
-
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders);
|
|
186
|
-
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
187
|
-
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
188
|
-
|
|
189
|
-
/* console.log(`Chunk path:`, chunkPath);
|
|
190
|
-
console.log(`Chunk with hierarchy preview:`, chunkWithHierarchy.substring(0, 100) + '...'); */
|
|
191
|
-
|
|
192
|
-
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
193
|
-
externalDocumentId: page.externalDocumentId,
|
|
194
|
-
externalPageId: page.externalPageId,
|
|
195
|
-
documentId: page.documentId,
|
|
196
|
-
pageId: page._id,
|
|
197
|
-
|
|
198
|
-
filePathParents: page.parentedPath,
|
|
199
|
-
chunkHeadParents: headParents,
|
|
200
|
-
|
|
201
|
-
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
202
|
-
path: [ ...page.parentedPath, ...headParents ].join('/'),
|
|
203
|
-
|
|
204
|
-
documentName: page.externalDocumentId,
|
|
205
|
-
pageName: page.name,
|
|
206
|
-
pageLink: getPageLink(page, issuer),
|
|
207
|
-
chunkIndex: chunkIndex,
|
|
208
|
-
|
|
209
|
-
chunkContent: chunkContent,
|
|
210
|
-
/* chunkOriginalContent: chunkContent,
|
|
211
|
-
|
|
212
|
-
chunkContent: chunkWithHierarchy, */
|
|
213
|
-
}) as T_Chunk;
|
|
214
|
-
|
|
215
|
-
if (this.debugLog || debugLog) {
|
|
216
|
-
DyFM_Log.H_info(
|
|
217
|
-
'Break point (before assembleChunkWithHeaders)',
|
|
218
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
219
|
-
{ chunk: chunk.chunkContent }
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
224
|
-
if (this.debugLog || debugLog) {
|
|
225
|
-
DyFM_Log.H_info(
|
|
226
|
-
'Break point (after assembleChunkWithHeaders)',
|
|
227
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
228
|
-
{
|
|
229
|
-
chunk: chunk.chunkContent,
|
|
230
|
-
}
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
chunks.push(chunk);
|
|
235
|
-
chunkIndex++;
|
|
236
|
-
currentPosition += breakPoint.index;
|
|
237
|
-
leftovers = leftovers.substring(breakPoint.index);
|
|
238
|
-
|
|
239
|
-
// Update last headers after creating the chunk
|
|
240
|
-
this.updateLastHeaders(headerHierarchy, currentPosition, lastHeaders);
|
|
241
|
-
|
|
242
|
-
/* console.log(`Updated last headers:`, Object.fromEntries(lastHeaders));
|
|
243
|
-
console.log(`--- End chunk ${chunkIndex - 1} ---\n`); */
|
|
244
|
-
} else {
|
|
245
|
-
// Ha nem találtunk break point-ot, használjuk a maxChunkSize-t
|
|
246
|
-
const chunkContent: string = leftovers.substring(0, maxChunkSize).trim();
|
|
247
|
-
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders);
|
|
248
|
-
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders);
|
|
249
|
-
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
250
|
-
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
251
|
-
|
|
252
|
-
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
253
|
-
externalDocumentId: page.externalDocumentId,
|
|
254
|
-
externalPageId: page.externalPageId,
|
|
255
|
-
documentId: page.documentId,
|
|
256
|
-
pageId: page._id,
|
|
257
|
-
|
|
258
|
-
filePathParents: page.parentedPath,
|
|
259
|
-
chunkHeadParents: headParents,
|
|
260
|
-
|
|
261
|
-
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
262
|
-
path: [ ...page.parentedPath, ...headParents ].join('/'),
|
|
263
|
-
|
|
264
|
-
documentName: page.externalDocumentId,
|
|
265
|
-
pageName: page.name,
|
|
266
|
-
pageLink: getPageLink(page, issuer),
|
|
267
|
-
chunkIndex: chunkIndex,
|
|
268
|
-
|
|
269
|
-
chunkContent: chunkContent,
|
|
270
|
-
/* chunkOriginalContent: chunkContent,
|
|
271
|
-
|
|
272
|
-
chunkContent: chunkWithHierarchy, */
|
|
273
|
-
}) as T_Chunk;
|
|
274
|
-
|
|
275
|
-
if (this.debugLog || debugLog) {
|
|
276
|
-
DyFM_Log.H_info(
|
|
277
|
-
'Max chunk size',
|
|
278
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
279
|
-
{ chunk: chunk.chunkContent }
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
284
|
-
if (this.debugLog || debugLog) {
|
|
285
|
-
DyFM_Log.H_info(
|
|
286
|
-
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
287
|
-
{
|
|
288
|
-
chunk: chunk.chunkContent,
|
|
289
|
-
}
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
chunks.push(chunk);
|
|
294
|
-
chunkIndex++;
|
|
295
|
-
currentPosition += maxChunkSize;
|
|
296
|
-
leftovers = leftovers.substring(maxChunkSize);
|
|
297
|
-
|
|
298
|
-
// Update last headers after creating the chunk
|
|
299
|
-
this.updateLastHeaders(headerHierarchy, currentPosition, lastHeaders);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Safety check to prevent infinite loops
|
|
303
|
-
if (leftovers.length > 0 && leftovers.length >= page.content.length) {
|
|
304
|
-
throw new DyFM_Error({
|
|
305
|
-
...this.getDefaultErrorSettings(
|
|
306
|
-
'chunkMdContent',
|
|
307
|
-
new Error('Infinite loop detected in chunking'),
|
|
308
|
-
issuer
|
|
309
|
-
),
|
|
310
|
-
errorCode: 'CCAP-CUC-CC1',
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Log warning if we hit the chunk count limit
|
|
316
|
-
if (chunkIndex >= maxChunkCount && leftovers.length > 0) {
|
|
317
|
-
DyFM_Log.warn(
|
|
318
|
-
`⚠️ Reached maximum chunk count (${maxChunkCount}). Remaining content: ${leftovers.length} characters`,
|
|
319
|
-
{
|
|
320
|
-
pageName: page.name,
|
|
321
|
-
pageSize: page.content.length,
|
|
322
|
-
}
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/* DyFM_Log.info(`✅ Created ${chunks.length} chunks`); */
|
|
327
|
-
return chunks;
|
|
328
|
-
} catch (error) {
|
|
329
|
-
throw new DyFM_Error({
|
|
330
|
-
...this.getDefaultErrorSettings('chunkMdContent', error, issuer),
|
|
331
|
-
errorCode: 'CCAP-CUC-CP0',
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/* private static assembleChunkWithHeaders(chunk: DyNTS_DAI_DocChunk, issuer: string): string {
|
|
337
|
-
try {
|
|
338
|
-
const fileHeaders = chunk.filePathParents.map(
|
|
339
|
-
(header, index) => `${'>'.repeat(index + 1)} **${header}**`
|
|
340
|
-
).join('\n');
|
|
341
|
-
const headers = chunk.chunkHeadParents.filter(
|
|
342
|
-
path => !chunk.chunkOriginalContent.includes(path)
|
|
343
|
-
).join('\n');
|
|
344
|
-
return `${fileHeaders}\n\n${headers}\n\n${chunk.chunkOriginalContent}`;
|
|
345
|
-
} catch (error) {
|
|
346
|
-
throw new DyFM_Error({
|
|
347
|
-
...this.getDefaultErrorSettings('assembleChunkWithHeaders', error, issuer),
|
|
348
|
-
errorCode: 'CCAP-CUC-ACH0',
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
} */
|
|
352
|
-
|
|
353
|
-
static reassembleChunksToContent(
|
|
354
|
-
chunks: DyNTS_DAI_DocChunk[],
|
|
355
|
-
issuer: string
|
|
356
|
-
): string {
|
|
357
|
-
try {
|
|
358
|
-
let pageContent: string = '';
|
|
359
|
-
|
|
360
|
-
for (const chunk of chunks) {
|
|
361
|
-
if (!chunk) {
|
|
362
|
-
throw new DyFM_Error({
|
|
363
|
-
...this.getDefaultErrorSettings(
|
|
364
|
-
'reassembleChunksToContent',
|
|
365
|
-
new Error('Chunk is null, you`ve passing null chunks to the function'),
|
|
366
|
-
issuer
|
|
367
|
-
),
|
|
368
|
-
errorCode: 'CCAP-CUC-RCTC0',
|
|
369
|
-
|
|
370
|
-
additionalContent: {
|
|
371
|
-
chunks: chunks,
|
|
372
|
-
},
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
pageContent += chunk.chunkContent;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return pageContent;
|
|
380
|
-
} catch (error) {
|
|
381
|
-
throw new DyFM_Error({
|
|
382
|
-
...this.getDefaultErrorSettings('reassembleChunks', error, issuer),
|
|
383
|
-
errorCode: 'CCAP-CUC-RC0',
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
* Find the best break point within the chunk size
|
|
390
|
-
* @param text - The text to search in
|
|
391
|
-
* @param maxIndex - Maximum index to search up to
|
|
392
|
-
* @returns The best break point or null if not found
|
|
393
|
-
*/
|
|
394
|
-
private static findBestBreakPoint(text: string, maxIndex: number): DyNTS_DAI_DocChunking_BreakPoint | null {
|
|
395
|
-
for (const breakPoint of this.breakPoints) {
|
|
396
|
-
const index: number = this.findLastOccurrence(text, breakPoint.pattern, maxIndex);
|
|
397
|
-
|
|
398
|
-
if (index > 0) {
|
|
399
|
-
return {
|
|
400
|
-
index: index + breakPoint.includeLength,
|
|
401
|
-
level: breakPoint.level
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
return null;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Parse header hierarchy from the content
|
|
410
|
-
* @param content - The content to parse
|
|
411
|
-
* @returns Array of header positions and levels
|
|
412
|
-
*/
|
|
413
|
-
private static parseHeaderHierarchy(content: string): DyNTS_DAI_DocChunking_Header[] {
|
|
414
|
-
const headers: DyNTS_DAI_DocChunking_Header[] = [];
|
|
415
|
-
const lines: string[] = content.split('\n');
|
|
416
|
-
let currentIndex: number = 0;
|
|
417
|
-
|
|
418
|
-
for (const line of lines) {
|
|
419
|
-
const trimmedLine: string = line.trim();
|
|
420
|
-
|
|
421
|
-
// Check if line starts with # and determine the level
|
|
422
|
-
if (trimmedLine.startsWith('#')) {
|
|
423
|
-
const match: RegExpMatchArray | null = trimmedLine.match(/^(#+)\s+(.+)$/);
|
|
424
|
-
|
|
425
|
-
if (match) {
|
|
426
|
-
const level: number = match[1].length; // Count the number of # symbols
|
|
427
|
-
const headerText: string = trimmedLine;
|
|
428
|
-
|
|
429
|
-
if (level >= 1 && level <= 4) { // Only support levels 1-4
|
|
430
|
-
headers.push({
|
|
431
|
-
index: currentIndex,
|
|
432
|
-
level: level,
|
|
433
|
-
header: headerText
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
currentIndex += line.length + 1; // +1 for the newline
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
return headers;
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Update the last headers map based on current position
|
|
447
|
-
* @param headerHierarchy - The parsed header hierarchy
|
|
448
|
-
* @param currentPosition - Current position in content
|
|
449
|
-
* @param lastHeaders - Map to store last headers of each level
|
|
450
|
-
*/
|
|
451
|
-
private static updateLastHeaders(
|
|
452
|
-
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
453
|
-
currentPosition: number,
|
|
454
|
-
lastHeaders: Map<number, string>
|
|
455
|
-
): void {
|
|
456
|
-
// Find all headers that come before current position (not including current position)
|
|
457
|
-
for (const header of headerHierarchy) {
|
|
458
|
-
if (header.index < currentPosition) {
|
|
459
|
-
// Set this header as the last header for its level
|
|
460
|
-
lastHeaders.set(header.level, header.header);
|
|
461
|
-
|
|
462
|
-
// Clear all lower level headers (higher level numbers) when any header comes
|
|
463
|
-
// For example, if we see a level 2 header, clear levels 3, 4
|
|
464
|
-
// If we see a level 1 header, clear levels 2, 3, 4
|
|
465
|
-
for (let level: number = header.level + 1; level <= 4; level++) {
|
|
466
|
-
lastHeaders.delete(level);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Visszaadja a chunk-hoz tartozó releváns szülő fejléceket a hierarchia alapján.
|
|
474
|
-
* @param headerHierarchy - A feldolgozott fejléc-hierarchia
|
|
475
|
-
* @param startIndex - A chunk kezdőindexe az eredeti tartalomban
|
|
476
|
-
* @param endIndex - A chunk végindexe az eredeti tartalomban
|
|
477
|
-
* @param lastHeaders - Az utolsó ismert fejlécek szintenként
|
|
478
|
-
* @returns A releváns szülő fejlécek tömbje
|
|
479
|
-
*/
|
|
480
|
-
private static getRelevantHeaders(
|
|
481
|
-
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
482
|
-
startIndex: number,
|
|
483
|
-
endIndex: number,
|
|
484
|
-
lastHeaders: Map<number, string>
|
|
485
|
-
): string[] {
|
|
486
|
-
// Keressük meg az első fejlécet a chunkban
|
|
487
|
-
const firstHeaderInChunk: DyNTS_DAI_DocChunking_Header | undefined = headerHierarchy.find(header =>
|
|
488
|
-
header.index >= startIndex && header.index < endIndex
|
|
489
|
-
);
|
|
490
|
-
|
|
491
|
-
if (!firstHeaderInChunk) {
|
|
492
|
-
// Nincs fejléc a chunkban, a legmagasabb szintű utolsó fejlécet használjuk
|
|
493
|
-
let highestLevel: number = 0;
|
|
494
|
-
let highestHeader: string = '';
|
|
495
|
-
|
|
496
|
-
for (const [level, header] of lastHeaders.entries()) {
|
|
497
|
-
if (level > highestLevel) {
|
|
498
|
-
highestLevel = level;
|
|
499
|
-
highestHeader = header;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
return highestHeader ? [highestHeader] : [];
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
// Szülő fejlécek összegyűjtése az első fejléc szintje alapján
|
|
506
|
-
const relevantHeaders: string[] = [];
|
|
507
|
-
for (let level: number = 1; level < firstHeaderInChunk.level; level++) {
|
|
508
|
-
const parentHeader: string | undefined = lastHeaders.get(level);
|
|
509
|
-
|
|
510
|
-
if (parentHeader) {
|
|
511
|
-
relevantHeaders.push(parentHeader);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return relevantHeaders;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
/**
|
|
518
|
-
* Build hierarchical chunk path based on header structure
|
|
519
|
-
* @param pageName - The page name
|
|
520
|
-
* @param headerHierarchy - The parsed header hierarchy
|
|
521
|
-
* @param startIndex - Start index of the chunk in original content
|
|
522
|
-
* @param endIndex - End index of the chunk in original content
|
|
523
|
-
* @param lastHeaders - Map of last headers for each level
|
|
524
|
-
* @returns Hierarchical path array
|
|
525
|
-
*/
|
|
526
|
-
private static buildChunkPath(
|
|
527
|
-
pageName: string,
|
|
528
|
-
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
529
|
-
startIndex: number,
|
|
530
|
-
endIndex: number,
|
|
531
|
-
lastHeaders: Map<number, string>
|
|
532
|
-
): string[] {
|
|
533
|
-
// Find the first header within this chunk
|
|
534
|
-
const firstHeaderInChunk: DyNTS_DAI_DocChunking_Header | undefined = headerHierarchy.find(header =>
|
|
535
|
-
header.index >= startIndex && header.index < endIndex
|
|
536
|
-
);
|
|
537
|
-
|
|
538
|
-
if (!firstHeaderInChunk) {
|
|
539
|
-
// No header in chunk, use the highest level from lastHeaders as parent
|
|
540
|
-
const pathParts: string[] = [pageName];
|
|
541
|
-
|
|
542
|
-
// Find the highest level header from lastHeaders
|
|
543
|
-
let highestLevel: number = 0;
|
|
544
|
-
let highestHeader: string = '';
|
|
545
|
-
|
|
546
|
-
for (const [level, header] of lastHeaders.entries()) {
|
|
547
|
-
if (level > highestLevel) {
|
|
548
|
-
highestLevel = level;
|
|
549
|
-
highestHeader = header;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (highestHeader) {
|
|
554
|
-
pathParts.push(highestHeader);
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return pathParts;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Build the path hierarchy
|
|
561
|
-
const pathParts: string[] = [pageName];
|
|
562
|
-
|
|
563
|
-
// Add parent headers from lastHeaders (these are the actual parent headers)
|
|
564
|
-
for (let level = 1; level < firstHeaderInChunk.level; level++) {
|
|
565
|
-
const parentHeader: string | undefined = lastHeaders.get(level);
|
|
566
|
-
|
|
567
|
-
if (parentHeader) {
|
|
568
|
-
pathParts.push(parentHeader); // Include the full header with markdown symbols
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
// Add the first header in chunk
|
|
573
|
-
pathParts.push(firstHeaderInChunk.header); // Include the full header with markdown symbols
|
|
574
|
-
|
|
575
|
-
return pathParts;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Add header hierarchy to the beginning of a chunk
|
|
580
|
-
* @param chunkContent - The chunk content
|
|
581
|
-
* @param headerHierarchy - The parsed header hierarchy
|
|
582
|
-
* @param startIndex - Start index of the chunk in original content
|
|
583
|
-
* @param endIndex - End index of the chunk in original content
|
|
584
|
-
* @param lastHeaders - Map of last headers for each level
|
|
585
|
-
* @returns Content with header hierarchy added
|
|
586
|
-
*/
|
|
587
|
-
private static addHeaderHierarchy(
|
|
588
|
-
chunkContent: string,
|
|
589
|
-
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
590
|
-
startIndex: number,
|
|
591
|
-
endIndex: number,
|
|
592
|
-
lastHeaders: Map<number, string>
|
|
593
|
-
): string {
|
|
594
|
-
const relevantHeaders: string[] = this.getRelevantHeaders(headerHierarchy, startIndex, endIndex, lastHeaders);
|
|
595
|
-
|
|
596
|
-
if (relevantHeaders.length > 0) {
|
|
597
|
-
return relevantHeaders.join('\n') + '\n\n' + chunkContent;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
return chunkContent;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
/**
|
|
604
|
-
* Helper method to find the last occurrence of a pattern within a specified range
|
|
605
|
-
* @param text - The text to search in
|
|
606
|
-
* @param pattern - The pattern to search for
|
|
607
|
-
* @param maxIndex - Maximum index to search up to
|
|
608
|
-
* @returns The index of the last occurrence, or -1 if not found
|
|
609
|
-
*/
|
|
610
|
-
private static findLastOccurrence(text: string, pattern: string, maxIndex: number): number {
|
|
611
|
-
const searchText: string = text.substring(0, maxIndex);
|
|
612
|
-
const lastIndex: number = searchText.lastIndexOf(pattern);
|
|
613
|
-
|
|
614
|
-
return lastIndex;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
protected static getDefaultErrorSettings(
|
|
618
|
-
fnName: string,
|
|
619
|
-
error: DyFM_AnyError,
|
|
620
|
-
issuer: string,
|
|
621
|
-
/** @deprecated we wont support the separate user message in the future, use the message instead */
|
|
622
|
-
useMessageAsUserMessage: boolean = true,
|
|
623
|
-
/* errorCode: string, */
|
|
624
|
-
): DyFM_Error_Settings {
|
|
625
|
-
return {
|
|
626
|
-
status: (error as DyFM_Error)?.___status ?? 500,
|
|
627
|
-
message: (error as Error)?.message ??
|
|
628
|
-
(error as DyFM_Error)?._message ??
|
|
629
|
-
`${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
|
|
630
|
-
addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
|
|
631
|
-
userMessage: (error as DyFM_Error)?.__userMessage ??
|
|
632
|
-
(useMessageAsUserMessage ? (error as Error)?.message : this.defaultErrorUserMsg),
|
|
633
|
-
/* errorCode: errorCode, */
|
|
634
|
-
issuer: issuer,
|
|
635
|
-
issuerService: this.constructor?.name,
|
|
636
|
-
error: error,
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
}
|
|
1
|
+
import { DyFM_Log, DyFM_Error, DyFM_AnyError, DyFM_Error_Settings } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
import { DyNTS_global_settings } from '../../../../../_collections/global-settings.const';
|
|
3
|
+
import { DyNTS_DAI_DocChunk } from '../_models/data-models/dai-doc-chunk.data-model';
|
|
4
|
+
import { DyNTS_DAI_DocPage } from '../_models/data-models/dai-doc-page.data-model';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
interface DyNTS_DAI_DocChunking_Header {
|
|
8
|
+
level: number;
|
|
9
|
+
header: string;
|
|
10
|
+
index: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface DyNTS_DAI_DocChunking_BreakPoint {
|
|
14
|
+
index: number;
|
|
15
|
+
level: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ClickUp dokumentum chunking szolgáltatás
|
|
20
|
+
* @author AI
|
|
21
|
+
* @description ClickUp dokumentumok intelligens chunking-ja a leghosszabb lehetséges chunk-ok létrehozásához
|
|
22
|
+
*/
|
|
23
|
+
export class DyNTS_DAI_DocChunking_Util {
|
|
24
|
+
|
|
25
|
+
protected static readonly defaultErrorUserMsg: string =
|
|
26
|
+
`We encountered an unhandled Control Service Error, ` +
|
|
27
|
+
`\nplease contact the responsible development team.`;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Unified break points configuration
|
|
31
|
+
*/
|
|
32
|
+
private static readonly breakPoints: { pattern: string, level: number, includeLength: number }[] = [
|
|
33
|
+
{ pattern: '\n# ', level: 1, includeLength: 0 }, // Header 1 - cut before marker
|
|
34
|
+
{ pattern: '\n## ', level: 2, includeLength: 0 }, // Header 2 - cut before marker
|
|
35
|
+
{ pattern: '\n### ', level: 3, includeLength: 0 }, // Header 3 - cut before marker
|
|
36
|
+
{ pattern: '\n#### ', level: 4, includeLength: 0 }, // Header 4 - cut before marker
|
|
37
|
+
{ pattern: '\n\n', level: 0, includeLength: 2 }, // Double line break - include
|
|
38
|
+
{ pattern: '\n', level: 0, includeLength: 1 }, // Single line break - include
|
|
39
|
+
{ pattern: '. ', level: 0, includeLength: 2 }, // Sentence end - include
|
|
40
|
+
{ pattern: ' ', level: 0, includeLength: 1 }, // Word break - include
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
protected static readonly debugLog: boolean = false;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Markdown tartalom chunking-ja a leghosszabb lehetséges chunk-ok létrehozásához
|
|
47
|
+
* @param page - ClickUp dokumentum oldal
|
|
48
|
+
* @param issuer - Kérés kezdeményezője
|
|
49
|
+
* @returns Promise<CU_DocChunk[]> - Létrehozott chunk-ok listája
|
|
50
|
+
*/
|
|
51
|
+
static async chunkMdContent<
|
|
52
|
+
T_Chunk extends DyNTS_DAI_DocChunk,
|
|
53
|
+
T_Page extends DyNTS_DAI_DocPage<T_Chunk>,
|
|
54
|
+
>(
|
|
55
|
+
page: T_Page,
|
|
56
|
+
getPageLink: (page: T_Page, issuer: string) => string,
|
|
57
|
+
issuer: string,
|
|
58
|
+
debugLog?: boolean
|
|
59
|
+
): Promise<T_Chunk[]> {
|
|
60
|
+
try {
|
|
61
|
+
if (debugLog) {
|
|
62
|
+
DyFM_Log.info(`Chunking page "${page.name}"...`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (page.content.includes('#####')) {
|
|
66
|
+
DyFM_Log.warn('lvl5+ headers are not supported yet for page: ' + page.name);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!page.documentId) {
|
|
70
|
+
throw new DyFM_Error({
|
|
71
|
+
...this.getDefaultErrorSettings('chunkMdContent', new Error('Page documentId is not set'), issuer),
|
|
72
|
+
errorCode: 'CCAP-CUC-CC2',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!page._id) {
|
|
77
|
+
throw new DyFM_Error({
|
|
78
|
+
...this.getDefaultErrorSettings('chunkMdContent', new Error('Page _id is not set'), issuer),
|
|
79
|
+
errorCode: 'CCAP-CUC-CC3',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* DyFM_Log.log(`Chunking page: ${page.name}\n\n`, JSON.stringify(page.content, null, 2)); */
|
|
84
|
+
|
|
85
|
+
let leftovers: string = page.content;
|
|
86
|
+
const maxChunkSize: number = DyNTS_global_settings.docChunking.maxChunkSize;
|
|
87
|
+
const maxChunkCount: number = DyNTS_global_settings.docChunking.maxChunkCount;
|
|
88
|
+
const chunks: T_Chunk[] = [];
|
|
89
|
+
let chunkIndex: number = 0;
|
|
90
|
+
let currentPosition: number = 0; // Track current position in original content
|
|
91
|
+
|
|
92
|
+
// Parse all headers to build hierarchy
|
|
93
|
+
const headerHierarchy: DyNTS_DAI_DocChunking_Header[] = this.parseHeaderHierarchy(leftovers);
|
|
94
|
+
|
|
95
|
+
// Debug: Log parsed headers
|
|
96
|
+
/* console.log('\n=== Parsed Header Hierarchy ===');
|
|
97
|
+
headerHierarchy.forEach((header, index) => {
|
|
98
|
+
console.log(`${index}: Level ${header.level} at position ${header.index}: "${header.header}"`);
|
|
99
|
+
});
|
|
100
|
+
console.log('=== End Header Hierarchy ===\n'); */
|
|
101
|
+
|
|
102
|
+
// Track the last headers of each level as we progress
|
|
103
|
+
const lastHeaders: Map<number, string> = new Map();
|
|
104
|
+
|
|
105
|
+
while (leftovers.length > 0 && chunkIndex < maxChunkCount) {
|
|
106
|
+
// Ha a teljes tartalom belefér egy chunk-ba, adjuk vissza az egészet
|
|
107
|
+
if (leftovers.length <= maxChunkSize) {
|
|
108
|
+
const chunkContent = leftovers.trim();
|
|
109
|
+
|
|
110
|
+
if (chunkContent.length > 0) {
|
|
111
|
+
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders);
|
|
112
|
+
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders);
|
|
113
|
+
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + leftovers.length, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
114
|
+
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
115
|
+
|
|
116
|
+
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
117
|
+
externalDocumentId: page.externalDocumentId,
|
|
118
|
+
documentId: page.documentId,
|
|
119
|
+
externalPageId: page.externalPageId,
|
|
120
|
+
pageId: page._id,
|
|
121
|
+
|
|
122
|
+
filePathParents: page.parentedPath,
|
|
123
|
+
chunkHeadParents: headParents,
|
|
124
|
+
|
|
125
|
+
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
126
|
+
/* path: [ ...page.parentedPath, ...headParents ].join('/'), */
|
|
127
|
+
path: page.allFlaggedParentsMerged,
|
|
128
|
+
|
|
129
|
+
documentName: page.externalDocumentId,
|
|
130
|
+
pageName: page.name,
|
|
131
|
+
pageLink: getPageLink(page, issuer),
|
|
132
|
+
chunkIndex: chunkIndex,
|
|
133
|
+
|
|
134
|
+
chunkContent: chunkContent,
|
|
135
|
+
/* chunkOriginalContent: chunkContent,
|
|
136
|
+
|
|
137
|
+
chunkContent: chunkWithHierarchy, */
|
|
138
|
+
}) as T_Chunk;
|
|
139
|
+
|
|
140
|
+
if (this.debugLog || debugLog) {
|
|
141
|
+
DyFM_Log.H_info(
|
|
142
|
+
'Full content (before assembleChunkWithHeaders)',
|
|
143
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
144
|
+
{ chunk: chunk.chunkContent }
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
149
|
+
if (this.debugLog || debugLog) {
|
|
150
|
+
DyFM_Log.H_info(
|
|
151
|
+
'Full content (after assembleChunkWithHeaders)',
|
|
152
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
153
|
+
{
|
|
154
|
+
chunk: chunk.chunkContent,
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* await DyFM_Async.wait(100_000); */
|
|
160
|
+
chunks.push(chunk);
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Keressük meg a legjobb break point-ot a maxChunkSize-n belül
|
|
166
|
+
const breakPoint: DyNTS_DAI_DocChunking_BreakPoint | null = this.findBestBreakPoint(leftovers, maxChunkSize);
|
|
167
|
+
|
|
168
|
+
if (breakPoint && breakPoint.index > 0) {
|
|
169
|
+
// Ha találtunk break point-ot, vágjunk a marker előtt
|
|
170
|
+
const chunkContent: string = leftovers.substring(0, breakPoint.index).trim();
|
|
171
|
+
|
|
172
|
+
// Debug: Log current state
|
|
173
|
+
/* console.log(`\n--- Creating chunk ${chunkIndex} ---`);
|
|
174
|
+
console.log(`Current position: ${currentPosition}`);
|
|
175
|
+
console.log(`Last headers:`, Object.fromEntries(lastHeaders));
|
|
176
|
+
console.log(`Chunk content preview:`, chunkContent.substring(0, 100) + '...'); */
|
|
177
|
+
|
|
178
|
+
// Check if chunk has headers
|
|
179
|
+
//const hasHeaders: boolean = headerHierarchy.some(header =>
|
|
180
|
+
// header.index >= currentPosition && header.index < currentPosition + breakPoint.index
|
|
181
|
+
//);
|
|
182
|
+
/* console.log(`Chunk has headers: ${hasHeaders}`); */
|
|
183
|
+
|
|
184
|
+
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders);
|
|
185
|
+
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders);
|
|
186
|
+
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + breakPoint.index, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
187
|
+
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
188
|
+
|
|
189
|
+
/* console.log(`Chunk path:`, chunkPath);
|
|
190
|
+
console.log(`Chunk with hierarchy preview:`, chunkWithHierarchy.substring(0, 100) + '...'); */
|
|
191
|
+
|
|
192
|
+
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
193
|
+
externalDocumentId: page.externalDocumentId,
|
|
194
|
+
externalPageId: page.externalPageId,
|
|
195
|
+
documentId: page.documentId,
|
|
196
|
+
pageId: page._id,
|
|
197
|
+
|
|
198
|
+
filePathParents: page.parentedPath,
|
|
199
|
+
chunkHeadParents: headParents,
|
|
200
|
+
|
|
201
|
+
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
202
|
+
path: [ ...page.parentedPath, ...headParents ].join('/'),
|
|
203
|
+
|
|
204
|
+
documentName: page.externalDocumentId,
|
|
205
|
+
pageName: page.name,
|
|
206
|
+
pageLink: getPageLink(page, issuer),
|
|
207
|
+
chunkIndex: chunkIndex,
|
|
208
|
+
|
|
209
|
+
chunkContent: chunkContent,
|
|
210
|
+
/* chunkOriginalContent: chunkContent,
|
|
211
|
+
|
|
212
|
+
chunkContent: chunkWithHierarchy, */
|
|
213
|
+
}) as T_Chunk;
|
|
214
|
+
|
|
215
|
+
if (this.debugLog || debugLog) {
|
|
216
|
+
DyFM_Log.H_info(
|
|
217
|
+
'Break point (before assembleChunkWithHeaders)',
|
|
218
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
219
|
+
{ chunk: chunk.chunkContent }
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
224
|
+
if (this.debugLog || debugLog) {
|
|
225
|
+
DyFM_Log.H_info(
|
|
226
|
+
'Break point (after assembleChunkWithHeaders)',
|
|
227
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
228
|
+
{
|
|
229
|
+
chunk: chunk.chunkContent,
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
chunks.push(chunk);
|
|
235
|
+
chunkIndex++;
|
|
236
|
+
currentPosition += breakPoint.index;
|
|
237
|
+
leftovers = leftovers.substring(breakPoint.index);
|
|
238
|
+
|
|
239
|
+
// Update last headers after creating the chunk
|
|
240
|
+
this.updateLastHeaders(headerHierarchy, currentPosition, lastHeaders);
|
|
241
|
+
|
|
242
|
+
/* console.log(`Updated last headers:`, Object.fromEntries(lastHeaders));
|
|
243
|
+
console.log(`--- End chunk ${chunkIndex - 1} ---\n`); */
|
|
244
|
+
} else {
|
|
245
|
+
// Ha nem találtunk break point-ot, használjuk a maxChunkSize-t
|
|
246
|
+
const chunkContent: string = leftovers.substring(0, maxChunkSize).trim();
|
|
247
|
+
//const chunkWithHierarchy: string = this.addHeaderHierarchy(chunkContent, headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders);
|
|
248
|
+
//const chunkPath: string[] = this.buildChunkPath(page.name, headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders);
|
|
249
|
+
const headParents: string[] = this.getRelevantHeaders(headerHierarchy, currentPosition, currentPosition + maxChunkSize, lastHeaders); // headerHierarchy.map(header => header.header);
|
|
250
|
+
//const allFlaggedParents: string[] = [ ...page.allFlaggedParents, ...headParents ];
|
|
251
|
+
|
|
252
|
+
const chunk: T_Chunk = new DyNTS_DAI_DocChunk({
|
|
253
|
+
externalDocumentId: page.externalDocumentId,
|
|
254
|
+
externalPageId: page.externalPageId,
|
|
255
|
+
documentId: page.documentId,
|
|
256
|
+
pageId: page._id,
|
|
257
|
+
|
|
258
|
+
filePathParents: page.parentedPath,
|
|
259
|
+
chunkHeadParents: headParents,
|
|
260
|
+
|
|
261
|
+
allFlaggedParents: [ ...page.allFlaggedParents, ...headParents ],
|
|
262
|
+
path: [ ...page.parentedPath, ...headParents ].join('/'),
|
|
263
|
+
|
|
264
|
+
documentName: page.externalDocumentId,
|
|
265
|
+
pageName: page.name,
|
|
266
|
+
pageLink: getPageLink(page, issuer),
|
|
267
|
+
chunkIndex: chunkIndex,
|
|
268
|
+
|
|
269
|
+
chunkContent: chunkContent,
|
|
270
|
+
/* chunkOriginalContent: chunkContent,
|
|
271
|
+
|
|
272
|
+
chunkContent: chunkWithHierarchy, */
|
|
273
|
+
}) as T_Chunk;
|
|
274
|
+
|
|
275
|
+
if (this.debugLog || debugLog) {
|
|
276
|
+
DyFM_Log.H_info(
|
|
277
|
+
'Max chunk size',
|
|
278
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
279
|
+
{ chunk: chunk.chunkContent }
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* chunk.chunkContent = this.assembleChunkWithHeaders(chunk, issuer); */
|
|
284
|
+
if (this.debugLog || debugLog) {
|
|
285
|
+
DyFM_Log.H_info(
|
|
286
|
+
`Chunk ${chunkIndex}: ${chunk.path.replaceAll('/', '/\n').split('/')}`,
|
|
287
|
+
{
|
|
288
|
+
chunk: chunk.chunkContent,
|
|
289
|
+
}
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
chunks.push(chunk);
|
|
294
|
+
chunkIndex++;
|
|
295
|
+
currentPosition += maxChunkSize;
|
|
296
|
+
leftovers = leftovers.substring(maxChunkSize);
|
|
297
|
+
|
|
298
|
+
// Update last headers after creating the chunk
|
|
299
|
+
this.updateLastHeaders(headerHierarchy, currentPosition, lastHeaders);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Safety check to prevent infinite loops
|
|
303
|
+
if (leftovers.length > 0 && leftovers.length >= page.content.length) {
|
|
304
|
+
throw new DyFM_Error({
|
|
305
|
+
...this.getDefaultErrorSettings(
|
|
306
|
+
'chunkMdContent',
|
|
307
|
+
new Error('Infinite loop detected in chunking'),
|
|
308
|
+
issuer
|
|
309
|
+
),
|
|
310
|
+
errorCode: 'CCAP-CUC-CC1',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Log warning if we hit the chunk count limit
|
|
316
|
+
if (chunkIndex >= maxChunkCount && leftovers.length > 0) {
|
|
317
|
+
DyFM_Log.warn(
|
|
318
|
+
`⚠️ Reached maximum chunk count (${maxChunkCount}). Remaining content: ${leftovers.length} characters`,
|
|
319
|
+
{
|
|
320
|
+
pageName: page.name,
|
|
321
|
+
pageSize: page.content.length,
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* DyFM_Log.info(`✅ Created ${chunks.length} chunks`); */
|
|
327
|
+
return chunks;
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw new DyFM_Error({
|
|
330
|
+
...this.getDefaultErrorSettings('chunkMdContent', error, issuer),
|
|
331
|
+
errorCode: 'CCAP-CUC-CP0',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* private static assembleChunkWithHeaders(chunk: DyNTS_DAI_DocChunk, issuer: string): string {
|
|
337
|
+
try {
|
|
338
|
+
const fileHeaders = chunk.filePathParents.map(
|
|
339
|
+
(header, index) => `${'>'.repeat(index + 1)} **${header}**`
|
|
340
|
+
).join('\n');
|
|
341
|
+
const headers = chunk.chunkHeadParents.filter(
|
|
342
|
+
path => !chunk.chunkOriginalContent.includes(path)
|
|
343
|
+
).join('\n');
|
|
344
|
+
return `${fileHeaders}\n\n${headers}\n\n${chunk.chunkOriginalContent}`;
|
|
345
|
+
} catch (error) {
|
|
346
|
+
throw new DyFM_Error({
|
|
347
|
+
...this.getDefaultErrorSettings('assembleChunkWithHeaders', error, issuer),
|
|
348
|
+
errorCode: 'CCAP-CUC-ACH0',
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
} */
|
|
352
|
+
|
|
353
|
+
static reassembleChunksToContent(
|
|
354
|
+
chunks: DyNTS_DAI_DocChunk[],
|
|
355
|
+
issuer: string
|
|
356
|
+
): string {
|
|
357
|
+
try {
|
|
358
|
+
let pageContent: string = '';
|
|
359
|
+
|
|
360
|
+
for (const chunk of chunks) {
|
|
361
|
+
if (!chunk) {
|
|
362
|
+
throw new DyFM_Error({
|
|
363
|
+
...this.getDefaultErrorSettings(
|
|
364
|
+
'reassembleChunksToContent',
|
|
365
|
+
new Error('Chunk is null, you`ve passing null chunks to the function'),
|
|
366
|
+
issuer
|
|
367
|
+
),
|
|
368
|
+
errorCode: 'CCAP-CUC-RCTC0',
|
|
369
|
+
|
|
370
|
+
additionalContent: {
|
|
371
|
+
chunks: chunks,
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
pageContent += chunk.chunkContent;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return pageContent;
|
|
380
|
+
} catch (error) {
|
|
381
|
+
throw new DyFM_Error({
|
|
382
|
+
...this.getDefaultErrorSettings('reassembleChunks', error, issuer),
|
|
383
|
+
errorCode: 'CCAP-CUC-RC0',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Find the best break point within the chunk size
|
|
390
|
+
* @param text - The text to search in
|
|
391
|
+
* @param maxIndex - Maximum index to search up to
|
|
392
|
+
* @returns The best break point or null if not found
|
|
393
|
+
*/
|
|
394
|
+
private static findBestBreakPoint(text: string, maxIndex: number): DyNTS_DAI_DocChunking_BreakPoint | null {
|
|
395
|
+
for (const breakPoint of this.breakPoints) {
|
|
396
|
+
const index: number = this.findLastOccurrence(text, breakPoint.pattern, maxIndex);
|
|
397
|
+
|
|
398
|
+
if (index > 0) {
|
|
399
|
+
return {
|
|
400
|
+
index: index + breakPoint.includeLength,
|
|
401
|
+
level: breakPoint.level
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Parse header hierarchy from the content
|
|
410
|
+
* @param content - The content to parse
|
|
411
|
+
* @returns Array of header positions and levels
|
|
412
|
+
*/
|
|
413
|
+
private static parseHeaderHierarchy(content: string): DyNTS_DAI_DocChunking_Header[] {
|
|
414
|
+
const headers: DyNTS_DAI_DocChunking_Header[] = [];
|
|
415
|
+
const lines: string[] = content.split('\n');
|
|
416
|
+
let currentIndex: number = 0;
|
|
417
|
+
|
|
418
|
+
for (const line of lines) {
|
|
419
|
+
const trimmedLine: string = line.trim();
|
|
420
|
+
|
|
421
|
+
// Check if line starts with # and determine the level
|
|
422
|
+
if (trimmedLine.startsWith('#')) {
|
|
423
|
+
const match: RegExpMatchArray | null = trimmedLine.match(/^(#+)\s+(.+)$/);
|
|
424
|
+
|
|
425
|
+
if (match) {
|
|
426
|
+
const level: number = match[1].length; // Count the number of # symbols
|
|
427
|
+
const headerText: string = trimmedLine;
|
|
428
|
+
|
|
429
|
+
if (level >= 1 && level <= 4) { // Only support levels 1-4
|
|
430
|
+
headers.push({
|
|
431
|
+
index: currentIndex,
|
|
432
|
+
level: level,
|
|
433
|
+
header: headerText
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
currentIndex += line.length + 1; // +1 for the newline
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return headers;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Update the last headers map based on current position
|
|
447
|
+
* @param headerHierarchy - The parsed header hierarchy
|
|
448
|
+
* @param currentPosition - Current position in content
|
|
449
|
+
* @param lastHeaders - Map to store last headers of each level
|
|
450
|
+
*/
|
|
451
|
+
private static updateLastHeaders(
|
|
452
|
+
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
453
|
+
currentPosition: number,
|
|
454
|
+
lastHeaders: Map<number, string>
|
|
455
|
+
): void {
|
|
456
|
+
// Find all headers that come before current position (not including current position)
|
|
457
|
+
for (const header of headerHierarchy) {
|
|
458
|
+
if (header.index < currentPosition) {
|
|
459
|
+
// Set this header as the last header for its level
|
|
460
|
+
lastHeaders.set(header.level, header.header);
|
|
461
|
+
|
|
462
|
+
// Clear all lower level headers (higher level numbers) when any header comes
|
|
463
|
+
// For example, if we see a level 2 header, clear levels 3, 4
|
|
464
|
+
// If we see a level 1 header, clear levels 2, 3, 4
|
|
465
|
+
for (let level: number = header.level + 1; level <= 4; level++) {
|
|
466
|
+
lastHeaders.delete(level);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Visszaadja a chunk-hoz tartozó releváns szülő fejléceket a hierarchia alapján.
|
|
474
|
+
* @param headerHierarchy - A feldolgozott fejléc-hierarchia
|
|
475
|
+
* @param startIndex - A chunk kezdőindexe az eredeti tartalomban
|
|
476
|
+
* @param endIndex - A chunk végindexe az eredeti tartalomban
|
|
477
|
+
* @param lastHeaders - Az utolsó ismert fejlécek szintenként
|
|
478
|
+
* @returns A releváns szülő fejlécek tömbje
|
|
479
|
+
*/
|
|
480
|
+
private static getRelevantHeaders(
|
|
481
|
+
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
482
|
+
startIndex: number,
|
|
483
|
+
endIndex: number,
|
|
484
|
+
lastHeaders: Map<number, string>
|
|
485
|
+
): string[] {
|
|
486
|
+
// Keressük meg az első fejlécet a chunkban
|
|
487
|
+
const firstHeaderInChunk: DyNTS_DAI_DocChunking_Header | undefined = headerHierarchy.find(header =>
|
|
488
|
+
header.index >= startIndex && header.index < endIndex
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
if (!firstHeaderInChunk) {
|
|
492
|
+
// Nincs fejléc a chunkban, a legmagasabb szintű utolsó fejlécet használjuk
|
|
493
|
+
let highestLevel: number = 0;
|
|
494
|
+
let highestHeader: string = '';
|
|
495
|
+
|
|
496
|
+
for (const [level, header] of lastHeaders.entries()) {
|
|
497
|
+
if (level > highestLevel) {
|
|
498
|
+
highestLevel = level;
|
|
499
|
+
highestHeader = header;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return highestHeader ? [highestHeader] : [];
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Szülő fejlécek összegyűjtése az első fejléc szintje alapján
|
|
506
|
+
const relevantHeaders: string[] = [];
|
|
507
|
+
for (let level: number = 1; level < firstHeaderInChunk.level; level++) {
|
|
508
|
+
const parentHeader: string | undefined = lastHeaders.get(level);
|
|
509
|
+
|
|
510
|
+
if (parentHeader) {
|
|
511
|
+
relevantHeaders.push(parentHeader);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return relevantHeaders;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Build hierarchical chunk path based on header structure
|
|
519
|
+
* @param pageName - The page name
|
|
520
|
+
* @param headerHierarchy - The parsed header hierarchy
|
|
521
|
+
* @param startIndex - Start index of the chunk in original content
|
|
522
|
+
* @param endIndex - End index of the chunk in original content
|
|
523
|
+
* @param lastHeaders - Map of last headers for each level
|
|
524
|
+
* @returns Hierarchical path array
|
|
525
|
+
*/
|
|
526
|
+
private static buildChunkPath(
|
|
527
|
+
pageName: string,
|
|
528
|
+
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
529
|
+
startIndex: number,
|
|
530
|
+
endIndex: number,
|
|
531
|
+
lastHeaders: Map<number, string>
|
|
532
|
+
): string[] {
|
|
533
|
+
// Find the first header within this chunk
|
|
534
|
+
const firstHeaderInChunk: DyNTS_DAI_DocChunking_Header | undefined = headerHierarchy.find(header =>
|
|
535
|
+
header.index >= startIndex && header.index < endIndex
|
|
536
|
+
);
|
|
537
|
+
|
|
538
|
+
if (!firstHeaderInChunk) {
|
|
539
|
+
// No header in chunk, use the highest level from lastHeaders as parent
|
|
540
|
+
const pathParts: string[] = [pageName];
|
|
541
|
+
|
|
542
|
+
// Find the highest level header from lastHeaders
|
|
543
|
+
let highestLevel: number = 0;
|
|
544
|
+
let highestHeader: string = '';
|
|
545
|
+
|
|
546
|
+
for (const [level, header] of lastHeaders.entries()) {
|
|
547
|
+
if (level > highestLevel) {
|
|
548
|
+
highestLevel = level;
|
|
549
|
+
highestHeader = header;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (highestHeader) {
|
|
554
|
+
pathParts.push(highestHeader);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return pathParts;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Build the path hierarchy
|
|
561
|
+
const pathParts: string[] = [pageName];
|
|
562
|
+
|
|
563
|
+
// Add parent headers from lastHeaders (these are the actual parent headers)
|
|
564
|
+
for (let level = 1; level < firstHeaderInChunk.level; level++) {
|
|
565
|
+
const parentHeader: string | undefined = lastHeaders.get(level);
|
|
566
|
+
|
|
567
|
+
if (parentHeader) {
|
|
568
|
+
pathParts.push(parentHeader); // Include the full header with markdown symbols
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Add the first header in chunk
|
|
573
|
+
pathParts.push(firstHeaderInChunk.header); // Include the full header with markdown symbols
|
|
574
|
+
|
|
575
|
+
return pathParts;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Add header hierarchy to the beginning of a chunk
|
|
580
|
+
* @param chunkContent - The chunk content
|
|
581
|
+
* @param headerHierarchy - The parsed header hierarchy
|
|
582
|
+
* @param startIndex - Start index of the chunk in original content
|
|
583
|
+
* @param endIndex - End index of the chunk in original content
|
|
584
|
+
* @param lastHeaders - Map of last headers for each level
|
|
585
|
+
* @returns Content with header hierarchy added
|
|
586
|
+
*/
|
|
587
|
+
private static addHeaderHierarchy(
|
|
588
|
+
chunkContent: string,
|
|
589
|
+
headerHierarchy: DyNTS_DAI_DocChunking_Header[],
|
|
590
|
+
startIndex: number,
|
|
591
|
+
endIndex: number,
|
|
592
|
+
lastHeaders: Map<number, string>
|
|
593
|
+
): string {
|
|
594
|
+
const relevantHeaders: string[] = this.getRelevantHeaders(headerHierarchy, startIndex, endIndex, lastHeaders);
|
|
595
|
+
|
|
596
|
+
if (relevantHeaders.length > 0) {
|
|
597
|
+
return relevantHeaders.join('\n') + '\n\n' + chunkContent;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return chunkContent;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Helper method to find the last occurrence of a pattern within a specified range
|
|
605
|
+
* @param text - The text to search in
|
|
606
|
+
* @param pattern - The pattern to search for
|
|
607
|
+
* @param maxIndex - Maximum index to search up to
|
|
608
|
+
* @returns The index of the last occurrence, or -1 if not found
|
|
609
|
+
*/
|
|
610
|
+
private static findLastOccurrence(text: string, pattern: string, maxIndex: number): number {
|
|
611
|
+
const searchText: string = text.substring(0, maxIndex);
|
|
612
|
+
const lastIndex: number = searchText.lastIndexOf(pattern);
|
|
613
|
+
|
|
614
|
+
return lastIndex;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
protected static getDefaultErrorSettings(
|
|
618
|
+
fnName: string,
|
|
619
|
+
error: DyFM_AnyError,
|
|
620
|
+
issuer: string,
|
|
621
|
+
/** @deprecated we wont support the separate user message in the future, use the message instead */
|
|
622
|
+
useMessageAsUserMessage: boolean = true,
|
|
623
|
+
/* errorCode: string, */
|
|
624
|
+
): DyFM_Error_Settings {
|
|
625
|
+
return {
|
|
626
|
+
status: (error as DyFM_Error)?.___status ?? 500,
|
|
627
|
+
message: (error as Error)?.message ??
|
|
628
|
+
(error as DyFM_Error)?._message ??
|
|
629
|
+
`${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
|
|
630
|
+
addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
|
|
631
|
+
userMessage: (error as DyFM_Error)?.__userMessage ??
|
|
632
|
+
(useMessageAsUserMessage ? (error as Error)?.message : this.defaultErrorUserMsg),
|
|
633
|
+
/* errorCode: errorCode, */
|
|
634
|
+
issuer: issuer,
|
|
635
|
+
issuerService: this.constructor?.name,
|
|
636
|
+
error: error,
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
}
|