@lhremote/core 0.1.0 → 0.2.1
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 +124 -0
- package/dist/cdp/app-discovery.d.ts +22 -0
- package/dist/cdp/app-discovery.d.ts.map +1 -0
- package/dist/cdp/app-discovery.js +60 -0
- package/dist/cdp/app-discovery.js.map +1 -0
- package/dist/cdp/app-discovery.test.d.ts +2 -0
- package/dist/cdp/app-discovery.test.d.ts.map +1 -0
- package/dist/cdp/app-discovery.test.js +124 -0
- package/dist/cdp/app-discovery.test.js.map +1 -0
- package/dist/cdp/client.d.ts +14 -0
- package/dist/cdp/client.d.ts.map +1 -1
- package/dist/cdp/client.integration.test.js +10 -3
- package/dist/cdp/client.integration.test.js.map +1 -1
- package/dist/cdp/client.js +41 -8
- package/dist/cdp/client.js.map +1 -1
- package/dist/cdp/client.test.js +267 -3
- package/dist/cdp/client.test.js.map +1 -1
- package/dist/cdp/discovery.d.ts.map +1 -1
- package/dist/cdp/discovery.integration.test.js +2 -0
- package/dist/cdp/discovery.integration.test.js.map +1 -1
- package/dist/cdp/discovery.js +2 -0
- package/dist/cdp/discovery.js.map +1 -1
- package/dist/cdp/discovery.test.js +2 -0
- package/dist/cdp/discovery.test.js.map +1 -1
- package/dist/cdp/errors.d.ts.map +1 -1
- package/dist/cdp/errors.js +2 -0
- package/dist/cdp/errors.js.map +1 -1
- package/dist/cdp/errors.test.js +2 -0
- package/dist/cdp/errors.test.js.map +1 -1
- package/dist/cdp/index.d.ts +1 -0
- package/dist/cdp/index.d.ts.map +1 -1
- package/dist/cdp/index.js +3 -0
- package/dist/cdp/index.js.map +1 -1
- package/dist/cdp/instance-discovery.d.ts.map +1 -1
- package/dist/cdp/instance-discovery.integration.test.js +2 -0
- package/dist/cdp/instance-discovery.integration.test.js.map +1 -1
- package/dist/cdp/instance-discovery.js +5 -17
- package/dist/cdp/instance-discovery.js.map +1 -1
- package/dist/cdp/instance-discovery.test.js +2 -0
- package/dist/cdp/instance-discovery.test.js.map +1 -1
- package/dist/cdp/testing/launch-chromium.d.ts.map +1 -1
- package/dist/cdp/testing/launch-chromium.js +4 -1
- package/dist/cdp/testing/launch-chromium.js.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/data/action-types.d.ts +39 -0
- package/dist/data/action-types.d.ts.map +1 -0
- package/dist/data/action-types.js +497 -0
- package/dist/data/action-types.js.map +1 -0
- package/dist/data/action-types.test.d.ts +2 -0
- package/dist/data/action-types.test.d.ts.map +1 -0
- package/dist/data/action-types.test.js +544 -0
- package/dist/data/action-types.test.js.map +1 -0
- package/dist/data/index.d.ts +3 -0
- package/dist/data/index.d.ts.map +1 -0
- package/dist/data/index.js +4 -0
- package/dist/data/index.js.map +1 -0
- package/dist/db/client.d.ts +19 -5
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.integration.test.js +5 -1
- package/dist/db/client.integration.test.js.map +1 -1
- package/dist/db/client.js +11 -5
- package/dist/db/client.js.map +1 -1
- package/dist/db/client.test.js +2 -0
- package/dist/db/client.test.js.map +1 -1
- package/dist/db/discovery.d.ts.map +1 -1
- package/dist/db/discovery.integration.test.js +2 -0
- package/dist/db/discovery.integration.test.js.map +1 -1
- package/dist/db/discovery.js +2 -0
- package/dist/db/discovery.js.map +1 -1
- package/dist/db/discovery.test.js +2 -0
- package/dist/db/discovery.test.js.map +1 -1
- package/dist/db/errors.d.ts +31 -0
- package/dist/db/errors.d.ts.map +1 -1
- package/dist/db/errors.js +49 -0
- package/dist/db/errors.js.map +1 -1
- package/dist/db/errors.test.js +2 -0
- package/dist/db/errors.test.js.map +1 -1
- package/dist/db/escape-like.d.ts +8 -0
- package/dist/db/escape-like.d.ts.map +1 -0
- package/dist/db/escape-like.js +12 -0
- package/dist/db/escape-like.js.map +1 -0
- package/dist/db/escape-like.test.d.ts +2 -0
- package/dist/db/escape-like.test.d.ts.map +1 -0
- package/dist/db/escape-like.test.js +25 -0
- package/dist/db/escape-like.test.js.map +1 -0
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +4 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/repositories/campaign-exclude-list.d.ts +89 -0
- package/dist/db/repositories/campaign-exclude-list.d.ts.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.js +204 -0
- package/dist/db/repositories/campaign-exclude-list.js.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.test.d.ts +2 -0
- package/dist/db/repositories/campaign-exclude-list.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign-exclude-list.test.js +132 -0
- package/dist/db/repositories/campaign-exclude-list.test.js.map +1 -0
- package/dist/db/repositories/campaign-statistics.d.ts +58 -0
- package/dist/db/repositories/campaign-statistics.d.ts.map +1 -0
- package/dist/db/repositories/campaign-statistics.js +278 -0
- package/dist/db/repositories/campaign-statistics.js.map +1 -0
- package/dist/db/repositories/campaign-statistics.test.d.ts +2 -0
- package/dist/db/repositories/campaign-statistics.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign-statistics.test.js +266 -0
- package/dist/db/repositories/campaign-statistics.test.js.map +1 -0
- package/dist/db/repositories/campaign.d.ts +103 -0
- package/dist/db/repositories/campaign.d.ts.map +1 -0
- package/dist/db/repositories/campaign.js +388 -0
- package/dist/db/repositories/campaign.js.map +1 -0
- package/dist/db/repositories/campaign.test.d.ts +2 -0
- package/dist/db/repositories/campaign.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign.test.js +392 -0
- package/dist/db/repositories/campaign.test.js.map +1 -0
- package/dist/db/repositories/index.d.ts +4 -0
- package/dist/db/repositories/index.d.ts.map +1 -1
- package/dist/db/repositories/index.js +6 -0
- package/dist/db/repositories/index.js.map +1 -1
- package/dist/db/repositories/message.d.ts +57 -0
- package/dist/db/repositories/message.d.ts.map +1 -0
- package/dist/db/repositories/message.integration.test.d.ts +2 -0
- package/dist/db/repositories/message.integration.test.d.ts.map +1 -0
- package/dist/db/repositories/message.integration.test.js +137 -0
- package/dist/db/repositories/message.integration.test.js.map +1 -0
- package/dist/db/repositories/message.js +308 -0
- package/dist/db/repositories/message.js.map +1 -0
- package/dist/db/repositories/message.test.d.ts +2 -0
- package/dist/db/repositories/message.test.d.ts.map +1 -0
- package/dist/db/repositories/message.test.js +179 -0
- package/dist/db/repositories/message.test.js.map +1 -0
- package/dist/db/repositories/profile.d.ts +11 -1
- package/dist/db/repositories/profile.d.ts.map +1 -1
- package/dist/db/repositories/profile.integration.test.js +103 -0
- package/dist/db/repositories/profile.integration.test.js.map +1 -1
- package/dist/db/repositories/profile.js +52 -15
- package/dist/db/repositories/profile.js.map +1 -1
- package/dist/db/repositories/profile.test.js +90 -0
- package/dist/db/repositories/profile.test.js.map +1 -1
- package/dist/db/testing/create-fixture.d.ts +0 -6
- package/dist/db/testing/create-fixture.d.ts.map +1 -1
- package/dist/db/testing/create-fixture.js +463 -4
- package/dist/db/testing/create-fixture.js.map +1 -1
- package/dist/db/testing/open-fixture.d.ts +5 -4
- package/dist/db/testing/open-fixture.d.ts.map +1 -1
- package/dist/db/testing/open-fixture.js +24 -6
- package/dist/db/testing/open-fixture.js.map +1 -1
- package/dist/formats/campaign-format.d.ts +31 -0
- package/dist/formats/campaign-format.d.ts.map +1 -0
- package/dist/formats/campaign-format.js +225 -0
- package/dist/formats/campaign-format.js.map +1 -0
- package/dist/formats/campaign-format.test.d.ts +2 -0
- package/dist/formats/campaign-format.test.d.ts.map +1 -0
- package/dist/formats/campaign-format.test.js +442 -0
- package/dist/formats/campaign-format.test.js.map +1 -0
- package/dist/formats/errors.d.ts +7 -0
- package/dist/formats/errors.d.ts.map +1 -0
- package/dist/formats/errors.js +12 -0
- package/dist/formats/errors.js.map +1 -0
- package/dist/formats/index.d.ts +3 -0
- package/dist/formats/index.d.ts.map +1 -0
- package/dist/formats/index.js +5 -0
- package/dist/formats/index.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/operations/campaign-add-action.d.ts +14 -0
- package/dist/operations/campaign-add-action.d.ts.map +1 -0
- package/dist/operations/campaign-add-action.js +33 -0
- package/dist/operations/campaign-add-action.js.map +1 -0
- package/dist/operations/campaign-add-action.test.d.ts +2 -0
- package/dist/operations/campaign-add-action.test.d.ts.map +1 -0
- package/dist/operations/campaign-add-action.test.js +122 -0
- package/dist/operations/campaign-add-action.test.js.map +1 -0
- package/dist/operations/campaign-create.d.ts +17 -0
- package/dist/operations/campaign-create.d.ts.map +1 -0
- package/dist/operations/campaign-create.js +21 -0
- package/dist/operations/campaign-create.js.map +1 -0
- package/dist/operations/campaign-create.test.d.ts +2 -0
- package/dist/operations/campaign-create.test.d.ts.map +1 -0
- package/dist/operations/campaign-create.test.js +121 -0
- package/dist/operations/campaign-create.test.js.map +1 -0
- package/dist/operations/campaign-delete.d.ts +20 -0
- package/dist/operations/campaign-delete.d.ts.map +1 -0
- package/dist/operations/campaign-delete.js +22 -0
- package/dist/operations/campaign-delete.js.map +1 -0
- package/dist/operations/campaign-delete.test.d.ts +2 -0
- package/dist/operations/campaign-delete.test.d.ts.map +1 -0
- package/dist/operations/campaign-delete.test.js +92 -0
- package/dist/operations/campaign-delete.test.js.map +1 -0
- package/dist/operations/campaign-exclude-add.d.ts +16 -0
- package/dist/operations/campaign-exclude-add.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-add.js +27 -0
- package/dist/operations/campaign-exclude-add.js.map +1 -0
- package/dist/operations/campaign-exclude-add.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-add.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-add.test.js +114 -0
- package/dist/operations/campaign-exclude-add.test.js.map +1 -0
- package/dist/operations/campaign-exclude-list.d.ts +14 -0
- package/dist/operations/campaign-exclude-list.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-list.js +26 -0
- package/dist/operations/campaign-exclude-list.js.map +1 -0
- package/dist/operations/campaign-exclude-list.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-list.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-list.test.js +113 -0
- package/dist/operations/campaign-exclude-list.test.js.map +1 -0
- package/dist/operations/campaign-exclude-remove.d.ts +16 -0
- package/dist/operations/campaign-exclude-remove.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-remove.js +27 -0
- package/dist/operations/campaign-exclude-remove.js.map +1 -0
- package/dist/operations/campaign-exclude-remove.test.d.ts +2 -0
- package/dist/operations/campaign-exclude-remove.test.d.ts.map +1 -0
- package/dist/operations/campaign-exclude-remove.test.js +114 -0
- package/dist/operations/campaign-exclude-remove.test.js.map +1 -0
- package/dist/operations/campaign-export.d.ts +12 -0
- package/dist/operations/campaign-export.d.ts.map +1 -0
- package/dist/operations/campaign-export.js +24 -0
- package/dist/operations/campaign-export.js.map +1 -0
- package/dist/operations/campaign-export.test.d.ts +2 -0
- package/dist/operations/campaign-export.test.d.ts.map +1 -0
- package/dist/operations/campaign-export.test.js +134 -0
- package/dist/operations/campaign-export.test.js.map +1 -0
- package/dist/operations/campaign-get.d.ts +19 -0
- package/dist/operations/campaign-get.d.ts.map +1 -0
- package/dist/operations/campaign-get.js +23 -0
- package/dist/operations/campaign-get.js.map +1 -0
- package/dist/operations/campaign-get.test.d.ts +2 -0
- package/dist/operations/campaign-get.test.d.ts.map +1 -0
- package/dist/operations/campaign-get.test.js +99 -0
- package/dist/operations/campaign-get.test.js.map +1 -0
- package/dist/operations/campaign-list.d.ts +20 -0
- package/dist/operations/campaign-list.d.ts.map +1 -0
- package/dist/operations/campaign-list.js +23 -0
- package/dist/operations/campaign-list.js.map +1 -0
- package/dist/operations/campaign-list.test.d.ts +2 -0
- package/dist/operations/campaign-list.test.d.ts.map +1 -0
- package/dist/operations/campaign-list.test.js +106 -0
- package/dist/operations/campaign-list.test.js.map +1 -0
- package/dist/operations/campaign-move-next.d.ts +15 -0
- package/dist/operations/campaign-move-next.d.ts.map +1 -0
- package/dist/operations/campaign-move-next.js +25 -0
- package/dist/operations/campaign-move-next.js.map +1 -0
- package/dist/operations/campaign-move-next.test.d.ts +2 -0
- package/dist/operations/campaign-move-next.test.d.ts.map +1 -0
- package/dist/operations/campaign-move-next.test.js +105 -0
- package/dist/operations/campaign-move-next.test.js.map +1 -0
- package/dist/operations/campaign-remove-action.d.ts +12 -0
- package/dist/operations/campaign-remove-action.d.ts.map +1 -0
- package/dist/operations/campaign-remove-action.js +23 -0
- package/dist/operations/campaign-remove-action.js.map +1 -0
- package/dist/operations/campaign-remove-action.test.d.ts +2 -0
- package/dist/operations/campaign-remove-action.test.d.ts.map +1 -0
- package/dist/operations/campaign-remove-action.test.js +95 -0
- package/dist/operations/campaign-remove-action.test.js.map +1 -0
- package/dist/operations/campaign-reorder-actions.d.ts +13 -0
- package/dist/operations/campaign-reorder-actions.d.ts.map +1 -0
- package/dist/operations/campaign-reorder-actions.js +19 -0
- package/dist/operations/campaign-reorder-actions.js.map +1 -0
- package/dist/operations/campaign-reorder-actions.test.d.ts +2 -0
- package/dist/operations/campaign-reorder-actions.test.d.ts.map +1 -0
- package/dist/operations/campaign-reorder-actions.test.js +103 -0
- package/dist/operations/campaign-reorder-actions.test.js.map +1 -0
- package/dist/operations/campaign-retry.d.ts +13 -0
- package/dist/operations/campaign-retry.d.ts.map +1 -0
- package/dist/operations/campaign-retry.js +24 -0
- package/dist/operations/campaign-retry.js.map +1 -0
- package/dist/operations/campaign-retry.test.d.ts +2 -0
- package/dist/operations/campaign-retry.test.d.ts.map +1 -0
- package/dist/operations/campaign-retry.test.js +100 -0
- package/dist/operations/campaign-retry.test.js.map +1 -0
- package/dist/operations/campaign-start.d.ts +13 -0
- package/dist/operations/campaign-start.d.ts.map +1 -0
- package/dist/operations/campaign-start.js +24 -0
- package/dist/operations/campaign-start.js.map +1 -0
- package/dist/operations/campaign-start.test.d.ts +2 -0
- package/dist/operations/campaign-start.test.d.ts.map +1 -0
- package/dist/operations/campaign-start.test.js +105 -0
- package/dist/operations/campaign-start.test.js.map +1 -0
- package/dist/operations/campaign-statistics.d.ts +10 -0
- package/dist/operations/campaign-statistics.d.ts.map +1 -0
- package/dist/operations/campaign-statistics.js +23 -0
- package/dist/operations/campaign-statistics.js.map +1 -0
- package/dist/operations/campaign-statistics.test.d.ts +2 -0
- package/dist/operations/campaign-statistics.test.d.ts.map +1 -0
- package/dist/operations/campaign-statistics.test.js +120 -0
- package/dist/operations/campaign-statistics.test.js.map +1 -0
- package/dist/operations/campaign-status.d.ts +26 -0
- package/dist/operations/campaign-status.d.ts.map +1 -0
- package/dist/operations/campaign-status.js +32 -0
- package/dist/operations/campaign-status.js.map +1 -0
- package/dist/operations/campaign-status.test.d.ts +2 -0
- package/dist/operations/campaign-status.test.d.ts.map +1 -0
- package/dist/operations/campaign-status.test.js +142 -0
- package/dist/operations/campaign-status.test.js.map +1 -0
- package/dist/operations/campaign-stop.d.ts +11 -0
- package/dist/operations/campaign-stop.d.ts.map +1 -0
- package/dist/operations/campaign-stop.js +23 -0
- package/dist/operations/campaign-stop.js.map +1 -0
- package/dist/operations/campaign-stop.test.d.ts +2 -0
- package/dist/operations/campaign-stop.test.d.ts.map +1 -0
- package/dist/operations/campaign-stop.test.js +92 -0
- package/dist/operations/campaign-stop.test.js.map +1 -0
- package/dist/operations/campaign-update.d.ts +18 -0
- package/dist/operations/campaign-update.d.ts.map +1 -0
- package/dist/operations/campaign-update.js +21 -0
- package/dist/operations/campaign-update.js.map +1 -0
- package/dist/operations/campaign-update.test.d.ts +2 -0
- package/dist/operations/campaign-update.test.d.ts.map +1 -0
- package/dist/operations/campaign-update.test.js +105 -0
- package/dist/operations/campaign-update.test.js.map +1 -0
- package/dist/operations/check-replies.d.ts +12 -0
- package/dist/operations/check-replies.d.ts.map +1 -0
- package/dist/operations/check-replies.js +26 -0
- package/dist/operations/check-replies.js.map +1 -0
- package/dist/operations/check-replies.test.d.ts +2 -0
- package/dist/operations/check-replies.test.d.ts.map +1 -0
- package/dist/operations/check-replies.test.js +118 -0
- package/dist/operations/check-replies.test.js.map +1 -0
- package/dist/operations/import-people-from-urls.d.ts +16 -0
- package/dist/operations/import-people-from-urls.d.ts.map +1 -0
- package/dist/operations/import-people-from-urls.js +27 -0
- package/dist/operations/import-people-from-urls.js.map +1 -0
- package/dist/operations/import-people-from-urls.test.d.ts +2 -0
- package/dist/operations/import-people-from-urls.test.d.ts.map +1 -0
- package/dist/operations/import-people-from-urls.test.js +118 -0
- package/dist/operations/import-people-from-urls.test.js.map +1 -0
- package/dist/operations/index.d.ts +24 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +30 -0
- package/dist/operations/index.js.map +1 -0
- package/dist/operations/query-messages.d.ts +23 -0
- package/dist/operations/query-messages.d.ts.map +1 -0
- package/dist/operations/query-messages.js +33 -0
- package/dist/operations/query-messages.js.map +1 -0
- package/dist/operations/query-messages.test.d.ts +2 -0
- package/dist/operations/query-messages.test.d.ts.map +1 -0
- package/dist/operations/query-messages.test.js +134 -0
- package/dist/operations/query-messages.test.js.map +1 -0
- package/dist/operations/scrape-messaging-history.d.ts +10 -0
- package/dist/operations/scrape-messaging-history.d.ts.map +1 -0
- package/dist/operations/scrape-messaging-history.js +24 -0
- package/dist/operations/scrape-messaging-history.js.map +1 -0
- package/dist/operations/scrape-messaging-history.test.d.ts +2 -0
- package/dist/operations/scrape-messaging-history.test.d.ts.map +1 -0
- package/dist/operations/scrape-messaging-history.test.js +112 -0
- package/dist/operations/scrape-messaging-history.test.js.map +1 -0
- package/dist/operations/types.d.ts +10 -0
- package/dist/operations/types.d.ts.map +1 -0
- package/dist/operations/types.js +4 -0
- package/dist/operations/types.js.map +1 -0
- package/dist/services/account-resolution.d.ts +22 -0
- package/dist/services/account-resolution.d.ts.map +1 -0
- package/dist/services/account-resolution.js +45 -0
- package/dist/services/account-resolution.js.map +1 -0
- package/dist/services/account-resolution.test.d.ts +2 -0
- package/dist/services/account-resolution.test.d.ts.map +1 -0
- package/dist/services/account-resolution.test.js +91 -0
- package/dist/services/account-resolution.test.js.map +1 -0
- package/dist/services/app.d.ts.map +1 -1
- package/dist/services/app.js +2 -0
- package/dist/services/app.js.map +1 -1
- package/dist/services/app.test.js +2 -0
- package/dist/services/app.test.js.map +1 -1
- package/dist/services/campaign.d.ts +143 -0
- package/dist/services/campaign.d.ts.map +1 -0
- package/dist/services/campaign.js +409 -0
- package/dist/services/campaign.js.map +1 -0
- package/dist/services/campaign.test.d.ts +2 -0
- package/dist/services/campaign.test.d.ts.map +1 -0
- package/dist/services/campaign.test.js +481 -0
- package/dist/services/campaign.test.js.map +1 -0
- package/dist/services/errors.d.ts +38 -0
- package/dist/services/errors.d.ts.map +1 -1
- package/dist/services/errors.js +60 -0
- package/dist/services/errors.js.map +1 -1
- package/dist/services/errors.test.js +53 -1
- package/dist/services/errors.test.js.map +1 -1
- package/dist/services/index.d.ts +5 -3
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +6 -2
- package/dist/services/index.js.map +1 -1
- package/dist/services/instance-context.d.ts +37 -0
- package/dist/services/instance-context.d.ts.map +1 -0
- package/dist/services/instance-context.js +49 -0
- package/dist/services/instance-context.js.map +1 -0
- package/dist/services/instance-context.test.d.ts +2 -0
- package/dist/services/instance-context.test.d.ts.map +1 -0
- package/dist/services/instance-context.test.js +203 -0
- package/dist/services/instance-context.test.js.map +1 -0
- package/dist/services/instance-lifecycle.d.ts.map +1 -1
- package/dist/services/instance-lifecycle.js +6 -6
- package/dist/services/instance-lifecycle.js.map +1 -1
- package/dist/services/instance-lifecycle.test.js +8 -2
- package/dist/services/instance-lifecycle.test.js.map +1 -1
- package/dist/services/instance.d.ts +40 -0
- package/dist/services/instance.d.ts.map +1 -1
- package/dist/services/instance.js +66 -9
- package/dist/services/instance.js.map +1 -1
- package/dist/services/instance.test.js +116 -6
- package/dist/services/instance.test.js.map +1 -1
- package/dist/services/launcher.d.ts +3 -0
- package/dist/services/launcher.d.ts.map +1 -1
- package/dist/services/launcher.js +25 -10
- package/dist/services/launcher.js.map +1 -1
- package/dist/services/launcher.test.js +39 -2
- package/dist/services/launcher.test.js.map +1 -1
- package/dist/services/status.d.ts +5 -1
- package/dist/services/status.d.ts.map +1 -1
- package/dist/services/status.js +24 -15
- package/dist/services/status.js.map +1 -1
- package/dist/services/status.test.js +42 -1
- package/dist/services/status.test.js.map +1 -1
- package/dist/testing/e2e-helpers.d.ts.map +1 -1
- package/dist/testing/e2e-helpers.js +7 -4
- package/dist/testing/e2e-helpers.js.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types/account.d.ts.map +1 -1
- package/dist/types/account.js +2 -0
- package/dist/types/account.js.map +1 -1
- package/dist/types/account.test.js +2 -0
- package/dist/types/account.test.js.map +1 -1
- package/dist/types/campaign.d.ts +267 -0
- package/dist/types/campaign.d.ts.map +1 -0
- package/dist/types/campaign.js +4 -0
- package/dist/types/campaign.js.map +1 -0
- package/dist/types/cdp.d.ts.map +1 -1
- package/dist/types/cdp.js +2 -0
- package/dist/types/cdp.js.map +1 -1
- package/dist/types/cdp.test.js +2 -0
- package/dist/types/cdp.test.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/instance.d.ts.map +1 -1
- package/dist/types/instance.js +2 -6
- package/dist/types/instance.js.map +1 -1
- package/dist/types/instance.test.js +2 -0
- package/dist/types/instance.test.js.map +1 -1
- package/dist/types/messaging.d.ts +51 -0
- package/dist/types/messaging.d.ts.map +1 -0
- package/dist/types/messaging.js +4 -0
- package/dist/types/messaging.js.map +1 -0
- package/dist/types/profile.d.ts +31 -0
- package/dist/types/profile.d.ts.map +1 -1
- package/dist/types/profile.js +2 -6
- package/dist/types/profile.js.map +1 -1
- package/dist/types/profile.test.js +2 -0
- package/dist/types/profile.test.js.map +1 -1
- package/dist/utils/cdp-port.d.ts +5 -0
- package/dist/utils/cdp-port.d.ts.map +1 -0
- package/dist/utils/cdp-port.js +15 -0
- package/dist/utils/cdp-port.js.map +1 -0
- package/dist/utils/cdp-port.test.d.ts +2 -0
- package/dist/utils/cdp-port.test.d.ts.map +1 -0
- package/dist/utils/cdp-port.test.js +23 -0
- package/dist/utils/cdp-port.test.js.map +1 -0
- package/dist/utils/delay.d.ts +5 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/delay.test.d.ts +2 -0
- package/dist/utils/delay.test.d.ts.map +1 -0
- package/dist/utils/delay.test.js +17 -0
- package/dist/utils/delay.test.js.map +1 -0
- package/dist/utils/error-message.d.ts +5 -0
- package/dist/utils/error-message.d.ts.map +1 -0
- package/dist/utils/error-message.js +9 -0
- package/dist/utils/error-message.js.map +1 -0
- package/dist/utils/error-message.test.d.ts +2 -0
- package/dist/utils/error-message.test.d.ts.map +1 -0
- package/dist/utils/error-message.test.js +28 -0
- package/dist/utils/error-message.test.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/loopback.d.ts +10 -0
- package/dist/utils/loopback.d.ts.map +1 -0
- package/dist/utils/loopback.js +28 -0
- package/dist/utils/loopback.js.map +1 -0
- package/dist/utils/loopback.test.d.ts +2 -0
- package/dist/utils/loopback.test.d.ts.map +1 -0
- package/dist/utils/loopback.test.js +34 -0
- package/dist/utils/loopback.test.js.map +1 -0
- package/package.json +13 -8
- package/dist/services/profile.d.ts +0 -44
- package/dist/services/profile.d.ts.map +0 -1
- package/dist/services/profile.js +0 -83
- package/dist/services/profile.js.map +0 -1
- package/dist/services/profile.test.d.ts +0 -2
- package/dist/services/profile.test.d.ts.map +0 -1
- package/dist/services/profile.test.js +0 -145
- package/dist/services/profile.test.js.map +0 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
4
|
+
import { DatabaseClient } from "../client.js";
|
|
5
|
+
import { ChatNotFoundError } from "../errors.js";
|
|
6
|
+
import { FIXTURE_PATH } from "../testing/open-fixture.js";
|
|
7
|
+
import { MessageRepository } from "./message.js";
|
|
8
|
+
describe("MessageRepository (integration)", () => {
|
|
9
|
+
let client;
|
|
10
|
+
let repo;
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
client = new DatabaseClient(FIXTURE_PATH);
|
|
13
|
+
repo = new MessageRepository(client);
|
|
14
|
+
});
|
|
15
|
+
afterAll(() => {
|
|
16
|
+
client.close();
|
|
17
|
+
});
|
|
18
|
+
describe("listChats", () => {
|
|
19
|
+
it("lists all chats with participants and last message", () => {
|
|
20
|
+
const chats = repo.listChats();
|
|
21
|
+
expect(chats.length).toBeGreaterThanOrEqual(3);
|
|
22
|
+
const chat1 = chats.find((c) => c.id === 1);
|
|
23
|
+
expect(chat1).toBeDefined();
|
|
24
|
+
expect(chat1?.type).toBe("MEMBER_TO_MEMBER");
|
|
25
|
+
expect(chat1?.platform).toBe("LINKEDIN");
|
|
26
|
+
expect(chat1?.participants.length).toBeGreaterThanOrEqual(2);
|
|
27
|
+
expect(chat1?.messageCount).toBe(3);
|
|
28
|
+
expect(chat1?.lastMessage).not.toBeNull();
|
|
29
|
+
});
|
|
30
|
+
it("filters chats by person", () => {
|
|
31
|
+
// Person 1 (Ada) participates in chat 1, chat 2, and chat 4
|
|
32
|
+
const chats = repo.listChats({ personId: 1 });
|
|
33
|
+
expect(chats).toHaveLength(3);
|
|
34
|
+
const chatIds = chats.map((c) => c.id);
|
|
35
|
+
expect(chatIds).toContain(1);
|
|
36
|
+
expect(chatIds).toContain(2);
|
|
37
|
+
expect(chatIds).toContain(4);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("getThread", () => {
|
|
41
|
+
it("retrieves a full conversation thread from the real schema", () => {
|
|
42
|
+
const thread = repo.getThread(1);
|
|
43
|
+
expect(thread.chat.id).toBe(1);
|
|
44
|
+
expect(thread.chat.participants.length).toBeGreaterThanOrEqual(2);
|
|
45
|
+
expect(thread.messages.length).toBeGreaterThanOrEqual(3);
|
|
46
|
+
// Messages should be in chronological order
|
|
47
|
+
const sendTimes = thread.messages.map((m) => m.sendAt);
|
|
48
|
+
const sorted = [...sendTimes].sort();
|
|
49
|
+
expect(sendTimes).toEqual(sorted);
|
|
50
|
+
});
|
|
51
|
+
it("includes sender information from person_mini_profile", () => {
|
|
52
|
+
const thread = repo.getThread(1);
|
|
53
|
+
const adaMessage = thread.messages.find((m) => m.senderPersonId === 1);
|
|
54
|
+
expect(adaMessage).toBeDefined();
|
|
55
|
+
expect(adaMessage?.senderFirstName).toBe("Ada");
|
|
56
|
+
expect(adaMessage?.senderLastName).toBe("Lovelace");
|
|
57
|
+
});
|
|
58
|
+
it("throws ChatNotFoundError for a nonexistent chat", () => {
|
|
59
|
+
expect(() => repo.getThread(999)).toThrow(ChatNotFoundError);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe("searchMessages", () => {
|
|
63
|
+
it("searches across all chats", () => {
|
|
64
|
+
const results = repo.searchMessages("compiler");
|
|
65
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
66
|
+
for (const msg of results) {
|
|
67
|
+
expect(msg.text.toLowerCase()).toContain("compiler");
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it("returns empty for no matches", () => {
|
|
71
|
+
const results = repo.searchMessages("zzz-no-match-zzz");
|
|
72
|
+
expect(results).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe("getMessageStats", () => {
|
|
76
|
+
it("returns stats across all messaging data", () => {
|
|
77
|
+
const stats = repo.getMessageStats();
|
|
78
|
+
expect(stats.totalMessages).toBeGreaterThanOrEqual(6);
|
|
79
|
+
expect(stats.totalChats).toBeGreaterThanOrEqual(3);
|
|
80
|
+
expect(stats.earliestMessage).toBeTruthy();
|
|
81
|
+
expect(stats.latestMessage).toBeTruthy();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe("getMessagesSince", () => {
|
|
85
|
+
it("returns messages after a given timestamp grouped by conversation", () => {
|
|
86
|
+
// Fixture has messages at 2025-01-10, 2025-01-11, 2025-01-12, 2025-01-13, 2025-01-14
|
|
87
|
+
const conversations = repo.getMessagesSince("2025-01-12T00:00:00.000Z");
|
|
88
|
+
// Should include: msg 4 (2025-01-12), msg 5 (2025-01-13), msg 6 (2025-01-13),
|
|
89
|
+
// msg 7 (2025-01-14), msg 8 (2025-01-14)
|
|
90
|
+
const totalMessages = conversations.reduce((sum, c) => sum + c.messages.length, 0);
|
|
91
|
+
expect(totalMessages).toBe(5);
|
|
92
|
+
// Each conversation should have chatId, personId, personName
|
|
93
|
+
for (const conv of conversations) {
|
|
94
|
+
expect(conv.chatId).toBeGreaterThan(0);
|
|
95
|
+
expect(conv.personId).toBeGreaterThan(0);
|
|
96
|
+
expect(conv.personName).toBeTruthy();
|
|
97
|
+
expect(conv.messages.length).toBeGreaterThan(0);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
it("returns empty array when no messages after the cutoff", () => {
|
|
101
|
+
const conversations = repo.getMessagesSince("2099-01-01T00:00:00.000Z");
|
|
102
|
+
expect(conversations).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
it("returns all messages when cutoff is before earliest message", () => {
|
|
105
|
+
const conversations = repo.getMessagesSince("2000-01-01T00:00:00.000Z");
|
|
106
|
+
const totalMessages = conversations.reduce((sum, c) => sum + c.messages.length, 0);
|
|
107
|
+
// Fixture has 8 messages total
|
|
108
|
+
expect(totalMessages).toBe(8);
|
|
109
|
+
});
|
|
110
|
+
it("groups messages by chat and sender", () => {
|
|
111
|
+
// Get messages including chat 1 (Ada ↔ Grace, 3 messages from 2 senders)
|
|
112
|
+
const conversations = repo.getMessagesSince("2025-01-09T00:00:00.000Z");
|
|
113
|
+
// Chat 1 should have 2 groups (Ada sent 2, Grace sent 1)
|
|
114
|
+
const chat1Groups = conversations.filter((c) => c.chatId === 1);
|
|
115
|
+
expect(chat1Groups).toHaveLength(2);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe("cross-table consistency", () => {
|
|
119
|
+
it("chat participants reference valid people with mini profiles", () => {
|
|
120
|
+
const chats = repo.listChats();
|
|
121
|
+
for (const chat of chats) {
|
|
122
|
+
for (const participant of chat.participants) {
|
|
123
|
+
expect(participant.personId).toBeGreaterThan(0);
|
|
124
|
+
expect(participant.firstName).toBeTruthy();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
it("thread messages reference valid senders from chat participants", () => {
|
|
129
|
+
const thread = repo.getThread(1);
|
|
130
|
+
const participantIds = thread.chat.participants.map((p) => p.personId);
|
|
131
|
+
for (const msg of thread.messages) {
|
|
132
|
+
expect(participantIds).toContain(msg.senderPersonId);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=message.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.integration.test.js","sourceRoot":"","sources":["../../../src/db/repositories/message.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { ChatNotFoundError } from "../errors.js";
|
|
4
|
+
import { escapeLike } from "../escape-like.js";
|
|
5
|
+
/**
|
|
6
|
+
* Read-only repository for querying messaging data from
|
|
7
|
+
* LinkedHelper's SQLite database.
|
|
8
|
+
*/
|
|
9
|
+
export class MessageRepository {
|
|
10
|
+
stmtChatById;
|
|
11
|
+
stmtChatParticipants;
|
|
12
|
+
stmtChatMessageCount;
|
|
13
|
+
stmtChatLastMessage;
|
|
14
|
+
stmtListChats;
|
|
15
|
+
stmtListChatsByPerson;
|
|
16
|
+
stmtThreadMessages;
|
|
17
|
+
stmtThreadMessagesBefore;
|
|
18
|
+
stmtSearchMessages;
|
|
19
|
+
stmtMessagesSince;
|
|
20
|
+
stmtStats;
|
|
21
|
+
constructor(client) {
|
|
22
|
+
const { db } = client;
|
|
23
|
+
this.stmtChatById = db.prepare("SELECT id, type, platform FROM chats WHERE id = ?");
|
|
24
|
+
this.stmtChatParticipants = db.prepare(`SELECT cp.person_id, mp.first_name, mp.last_name
|
|
25
|
+
FROM chat_participants cp
|
|
26
|
+
JOIN person_mini_profile mp ON cp.person_id = mp.person_id
|
|
27
|
+
WHERE cp.chat_id = ?`);
|
|
28
|
+
this.stmtChatMessageCount = db.prepare(`SELECT COUNT(DISTINCT pm.message_id) AS cnt
|
|
29
|
+
FROM chat_participants cp
|
|
30
|
+
JOIN participant_messages pm ON cp.id = pm.chat_participant_id
|
|
31
|
+
WHERE cp.chat_id = ?`);
|
|
32
|
+
this.stmtChatLastMessage = db.prepare(`SELECT m.message_text, m.send_at
|
|
33
|
+
FROM messages m
|
|
34
|
+
JOIN participant_messages pm ON m.id = pm.message_id
|
|
35
|
+
JOIN chat_participants cp ON pm.chat_participant_id = cp.id
|
|
36
|
+
WHERE cp.chat_id = ?
|
|
37
|
+
ORDER BY m.send_at DESC
|
|
38
|
+
LIMIT 1`);
|
|
39
|
+
this.stmtListChats = db.prepare(`SELECT
|
|
40
|
+
c.id AS chat_id,
|
|
41
|
+
c.type,
|
|
42
|
+
c.platform,
|
|
43
|
+
latest_msg.message_text AS last_message,
|
|
44
|
+
latest_msg.send_at AS last_message_at,
|
|
45
|
+
COALESCE(msg_count.cnt, 0) AS message_count
|
|
46
|
+
FROM chats c
|
|
47
|
+
LEFT JOIN (
|
|
48
|
+
SELECT cp2.chat_id,
|
|
49
|
+
COUNT(DISTINCT pm2.message_id) AS cnt
|
|
50
|
+
FROM chat_participants cp2
|
|
51
|
+
JOIN participant_messages pm2 ON cp2.id = pm2.chat_participant_id
|
|
52
|
+
GROUP BY cp2.chat_id
|
|
53
|
+
) msg_count ON c.id = msg_count.chat_id
|
|
54
|
+
LEFT JOIN (
|
|
55
|
+
SELECT cp3.chat_id,
|
|
56
|
+
m3.message_text,
|
|
57
|
+
m3.send_at,
|
|
58
|
+
ROW_NUMBER() OVER (PARTITION BY cp3.chat_id ORDER BY m3.send_at DESC) AS rn
|
|
59
|
+
FROM messages m3
|
|
60
|
+
JOIN participant_messages pm3 ON m3.id = pm3.message_id
|
|
61
|
+
JOIN chat_participants cp3 ON pm3.chat_participant_id = cp3.id
|
|
62
|
+
) latest_msg ON c.id = latest_msg.chat_id AND latest_msg.rn = 1
|
|
63
|
+
ORDER BY latest_msg.send_at DESC
|
|
64
|
+
LIMIT ? OFFSET ?`);
|
|
65
|
+
this.stmtListChatsByPerson = db.prepare(`SELECT
|
|
66
|
+
c.id AS chat_id,
|
|
67
|
+
c.type,
|
|
68
|
+
c.platform,
|
|
69
|
+
latest_msg.message_text AS last_message,
|
|
70
|
+
latest_msg.send_at AS last_message_at,
|
|
71
|
+
COALESCE(msg_count.cnt, 0) AS message_count
|
|
72
|
+
FROM chats c
|
|
73
|
+
JOIN chat_participants cp_filter ON c.id = cp_filter.chat_id
|
|
74
|
+
LEFT JOIN (
|
|
75
|
+
SELECT cp2.chat_id,
|
|
76
|
+
COUNT(DISTINCT pm2.message_id) AS cnt
|
|
77
|
+
FROM chat_participants cp2
|
|
78
|
+
JOIN participant_messages pm2 ON cp2.id = pm2.chat_participant_id
|
|
79
|
+
GROUP BY cp2.chat_id
|
|
80
|
+
) msg_count ON c.id = msg_count.chat_id
|
|
81
|
+
LEFT JOIN (
|
|
82
|
+
SELECT cp3.chat_id,
|
|
83
|
+
m3.message_text,
|
|
84
|
+
m3.send_at,
|
|
85
|
+
ROW_NUMBER() OVER (PARTITION BY cp3.chat_id ORDER BY m3.send_at DESC) AS rn
|
|
86
|
+
FROM messages m3
|
|
87
|
+
JOIN participant_messages pm3 ON m3.id = pm3.message_id
|
|
88
|
+
JOIN chat_participants cp3 ON pm3.chat_participant_id = cp3.id
|
|
89
|
+
) latest_msg ON c.id = latest_msg.chat_id AND latest_msg.rn = 1
|
|
90
|
+
WHERE cp_filter.person_id = ?
|
|
91
|
+
ORDER BY latest_msg.send_at DESC
|
|
92
|
+
LIMIT ? OFFSET ?`);
|
|
93
|
+
this.stmtThreadMessages = db.prepare(`SELECT
|
|
94
|
+
m.id,
|
|
95
|
+
m.message_text,
|
|
96
|
+
m.type,
|
|
97
|
+
m.subject,
|
|
98
|
+
m.send_at,
|
|
99
|
+
m.attachments_count,
|
|
100
|
+
cp.person_id AS sender_person_id,
|
|
101
|
+
mp.first_name AS sender_first_name,
|
|
102
|
+
mp.last_name AS sender_last_name
|
|
103
|
+
FROM messages m
|
|
104
|
+
JOIN participant_messages pm ON m.id = pm.message_id
|
|
105
|
+
JOIN chat_participants cp ON pm.chat_participant_id = cp.id
|
|
106
|
+
JOIN person_mini_profile mp ON cp.person_id = mp.person_id
|
|
107
|
+
WHERE cp.chat_id = ?
|
|
108
|
+
ORDER BY m.send_at ASC
|
|
109
|
+
LIMIT ?`);
|
|
110
|
+
this.stmtThreadMessagesBefore = db.prepare(`SELECT
|
|
111
|
+
m.id,
|
|
112
|
+
m.message_text,
|
|
113
|
+
m.type,
|
|
114
|
+
m.subject,
|
|
115
|
+
m.send_at,
|
|
116
|
+
m.attachments_count,
|
|
117
|
+
cp.person_id AS sender_person_id,
|
|
118
|
+
mp.first_name AS sender_first_name,
|
|
119
|
+
mp.last_name AS sender_last_name
|
|
120
|
+
FROM messages m
|
|
121
|
+
JOIN participant_messages pm ON m.id = pm.message_id
|
|
122
|
+
JOIN chat_participants cp ON pm.chat_participant_id = cp.id
|
|
123
|
+
JOIN person_mini_profile mp ON cp.person_id = mp.person_id
|
|
124
|
+
WHERE cp.chat_id = ? AND m.send_at < ?
|
|
125
|
+
ORDER BY m.send_at ASC
|
|
126
|
+
LIMIT ?`);
|
|
127
|
+
this.stmtSearchMessages = db.prepare(`SELECT
|
|
128
|
+
m.id,
|
|
129
|
+
m.message_text,
|
|
130
|
+
m.type,
|
|
131
|
+
m.subject,
|
|
132
|
+
m.send_at,
|
|
133
|
+
m.attachments_count,
|
|
134
|
+
cp.person_id AS sender_person_id,
|
|
135
|
+
mp.first_name AS sender_first_name,
|
|
136
|
+
mp.last_name AS sender_last_name
|
|
137
|
+
FROM messages m
|
|
138
|
+
JOIN participant_messages pm ON m.id = pm.message_id
|
|
139
|
+
JOIN chat_participants cp ON pm.chat_participant_id = cp.id
|
|
140
|
+
JOIN person_mini_profile mp ON cp.person_id = mp.person_id
|
|
141
|
+
WHERE m.message_text LIKE ? ESCAPE '\\'
|
|
142
|
+
ORDER BY m.send_at DESC
|
|
143
|
+
LIMIT ?`);
|
|
144
|
+
this.stmtMessagesSince = db.prepare(`SELECT
|
|
145
|
+
m.id,
|
|
146
|
+
m.message_text,
|
|
147
|
+
m.type,
|
|
148
|
+
m.subject,
|
|
149
|
+
m.send_at,
|
|
150
|
+
m.attachments_count,
|
|
151
|
+
cp.person_id AS sender_person_id,
|
|
152
|
+
mp.first_name AS sender_first_name,
|
|
153
|
+
mp.last_name AS sender_last_name,
|
|
154
|
+
cp.chat_id
|
|
155
|
+
FROM messages m
|
|
156
|
+
JOIN participant_messages pm ON m.id = pm.message_id
|
|
157
|
+
JOIN chat_participants cp ON pm.chat_participant_id = cp.id
|
|
158
|
+
JOIN person_mini_profile mp ON cp.person_id = mp.person_id
|
|
159
|
+
WHERE m.send_at > ?
|
|
160
|
+
ORDER BY m.send_at ASC`);
|
|
161
|
+
this.stmtStats = db.prepare(`SELECT
|
|
162
|
+
COUNT(DISTINCT m.id) AS total_messages,
|
|
163
|
+
COUNT(DISTINCT c.id) AS total_chats,
|
|
164
|
+
MIN(m.send_at) AS earliest_message,
|
|
165
|
+
MAX(m.send_at) AS latest_message
|
|
166
|
+
FROM chats c
|
|
167
|
+
LEFT JOIN chat_participants cp ON c.id = cp.chat_id
|
|
168
|
+
LEFT JOIN participant_messages pm ON cp.id = pm.chat_participant_id
|
|
169
|
+
LEFT JOIN messages m ON pm.message_id = m.id`);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Lists conversations, optionally filtered by a participant's person ID.
|
|
173
|
+
*/
|
|
174
|
+
listChats(options) {
|
|
175
|
+
const limit = options?.limit ?? 50;
|
|
176
|
+
const offset = options?.offset ?? 0;
|
|
177
|
+
let rows;
|
|
178
|
+
if (options?.personId != null) {
|
|
179
|
+
rows = this.stmtListChatsByPerson.all(options.personId, limit, offset);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
rows = this.stmtListChats.all(limit, offset);
|
|
183
|
+
}
|
|
184
|
+
return rows.map((r) => this.assembleChatFromListRow(r));
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Gets the full conversation thread for a chat.
|
|
188
|
+
*
|
|
189
|
+
* @throws {ChatNotFoundError} if no chat exists with the given ID.
|
|
190
|
+
*/
|
|
191
|
+
getThread(chatId, options) {
|
|
192
|
+
const chatRow = this.stmtChatById.get(chatId);
|
|
193
|
+
if (!chatRow)
|
|
194
|
+
throw new ChatNotFoundError(chatId);
|
|
195
|
+
const chat = this.assembleChat(chatRow);
|
|
196
|
+
const limit = options?.limit ?? 100;
|
|
197
|
+
let messageRows;
|
|
198
|
+
if (options?.before != null) {
|
|
199
|
+
messageRows = this.stmtThreadMessagesBefore.all(chatId, options.before, limit);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
messageRows = this.stmtThreadMessages.all(chatId, limit);
|
|
203
|
+
}
|
|
204
|
+
const messages = messageRows.map((r) => mapMessageRow(r));
|
|
205
|
+
return { chat, messages };
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Searches messages by text content using SQL LIKE.
|
|
209
|
+
*/
|
|
210
|
+
searchMessages(query, options) {
|
|
211
|
+
const limit = options?.limit ?? 50;
|
|
212
|
+
const pattern = `%${escapeLike(query)}%`;
|
|
213
|
+
const rows = this.stmtSearchMessages.all(pattern, limit);
|
|
214
|
+
return rows.map((r) => mapMessageRow(r));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Returns messages received after the given ISO timestamp, grouped
|
|
218
|
+
* by conversation. Each group identifies the sender (person) and
|
|
219
|
+
* includes the list of new messages in chronological order.
|
|
220
|
+
*/
|
|
221
|
+
getMessagesSince(since) {
|
|
222
|
+
const rows = this.stmtMessagesSince.all(since);
|
|
223
|
+
// Group by (chatId, senderPersonId)
|
|
224
|
+
const groups = new Map();
|
|
225
|
+
for (const r of rows) {
|
|
226
|
+
const key = `${String(r.chat_id)}:${String(r.sender_person_id)}`;
|
|
227
|
+
let group = groups.get(key);
|
|
228
|
+
if (!group) {
|
|
229
|
+
const name = r.sender_last_name
|
|
230
|
+
? `${r.sender_first_name} ${r.sender_last_name}`
|
|
231
|
+
: r.sender_first_name;
|
|
232
|
+
group = {
|
|
233
|
+
chatId: r.chat_id,
|
|
234
|
+
personId: r.sender_person_id,
|
|
235
|
+
personName: name,
|
|
236
|
+
messages: [],
|
|
237
|
+
};
|
|
238
|
+
groups.set(key, group);
|
|
239
|
+
}
|
|
240
|
+
group.messages.push(mapMessageRow(r));
|
|
241
|
+
}
|
|
242
|
+
return [...groups.values()];
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Returns aggregate statistics across all messaging data.
|
|
246
|
+
*/
|
|
247
|
+
getMessageStats() {
|
|
248
|
+
const row = this.stmtStats.get();
|
|
249
|
+
return {
|
|
250
|
+
totalMessages: row.total_messages,
|
|
251
|
+
totalChats: row.total_chats,
|
|
252
|
+
earliestMessage: row.earliest_message,
|
|
253
|
+
latestMessage: row.latest_message,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
assembleChatFromListRow(row) {
|
|
257
|
+
const participants = this.getChatParticipants(row.chat_id);
|
|
258
|
+
const lastMessage = row.last_message != null && row.last_message_at != null
|
|
259
|
+
? { text: row.last_message, sendAt: row.last_message_at }
|
|
260
|
+
: null;
|
|
261
|
+
return {
|
|
262
|
+
id: row.chat_id,
|
|
263
|
+
type: row.type,
|
|
264
|
+
platform: row.platform,
|
|
265
|
+
participants,
|
|
266
|
+
messageCount: row.message_count,
|
|
267
|
+
lastMessage,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
assembleChat(chatRow) {
|
|
271
|
+
const participants = this.getChatParticipants(chatRow.id);
|
|
272
|
+
const countRow = this.stmtChatMessageCount.get(chatRow.id);
|
|
273
|
+
const lastMsgRow = this.stmtChatLastMessage.get(chatRow.id);
|
|
274
|
+
const lastMessage = lastMsgRow
|
|
275
|
+
? { text: lastMsgRow.message_text, sendAt: lastMsgRow.send_at }
|
|
276
|
+
: null;
|
|
277
|
+
return {
|
|
278
|
+
id: chatRow.id,
|
|
279
|
+
type: chatRow.type,
|
|
280
|
+
platform: chatRow.platform,
|
|
281
|
+
participants,
|
|
282
|
+
messageCount: countRow.cnt,
|
|
283
|
+
lastMessage,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
getChatParticipants(chatId) {
|
|
287
|
+
const rows = this.stmtChatParticipants.all(chatId);
|
|
288
|
+
return rows.map((r) => ({
|
|
289
|
+
personId: r.person_id,
|
|
290
|
+
firstName: r.first_name,
|
|
291
|
+
lastName: r.last_name,
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function mapMessageRow(r) {
|
|
296
|
+
return {
|
|
297
|
+
id: r.id,
|
|
298
|
+
type: r.type,
|
|
299
|
+
text: r.message_text,
|
|
300
|
+
subject: r.subject,
|
|
301
|
+
sendAt: r.send_at,
|
|
302
|
+
attachmentsCount: r.attachments_count,
|
|
303
|
+
senderPersonId: r.sender_person_id,
|
|
304
|
+
senderFirstName: r.sender_first_name,
|
|
305
|
+
senderLastName: r.sender_last_name,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/db/repositories/message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.test.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/message.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { DatabaseClient } from "../client.js";
|
|
5
|
+
import { ChatNotFoundError } from "../errors.js";
|
|
6
|
+
import { openFixture } from "../testing/open-fixture.js";
|
|
7
|
+
import { MessageRepository } from "./message.js";
|
|
8
|
+
describe("MessageRepository", () => {
|
|
9
|
+
let db;
|
|
10
|
+
let client;
|
|
11
|
+
let repo;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
db = openFixture();
|
|
14
|
+
client = { db };
|
|
15
|
+
repo = new MessageRepository(client);
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
db.close();
|
|
19
|
+
});
|
|
20
|
+
describe("listChats", () => {
|
|
21
|
+
it("returns all chats ordered by latest message", () => {
|
|
22
|
+
const chats = repo.listChats();
|
|
23
|
+
expect(chats).toHaveLength(4);
|
|
24
|
+
// Chat 4 has latest message (2025-01-14), then Chat 3 (2025-01-13), then Chat 2 (2025-01-12), then Chat 1 (2025-01-11)
|
|
25
|
+
expect(chats.map((c) => c.id)).toEqual([4, 3, 2, 1]);
|
|
26
|
+
});
|
|
27
|
+
it("includes participants for each chat", () => {
|
|
28
|
+
const chats = repo.listChats();
|
|
29
|
+
const chat1 = chats.find((c) => c.id === 1);
|
|
30
|
+
expect(chat1).toBeDefined();
|
|
31
|
+
expect(chat1?.participants).toHaveLength(2);
|
|
32
|
+
expect(chat1?.participants).toContainEqual({
|
|
33
|
+
personId: 1,
|
|
34
|
+
firstName: "Ada",
|
|
35
|
+
lastName: "Lovelace",
|
|
36
|
+
});
|
|
37
|
+
expect(chat1?.participants).toContainEqual({
|
|
38
|
+
personId: 3,
|
|
39
|
+
firstName: "Grace",
|
|
40
|
+
lastName: "Hopper",
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it("includes last message summary", () => {
|
|
44
|
+
const chats = repo.listChats();
|
|
45
|
+
const chat1 = chats.find((c) => c.id === 1);
|
|
46
|
+
expect(chat1).toBeDefined();
|
|
47
|
+
expect(chat1?.lastMessage).toEqual({
|
|
48
|
+
text: "Let us schedule a meeting next week.",
|
|
49
|
+
sendAt: "2025-01-11T14:30:00.000Z",
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
it("includes message count", () => {
|
|
53
|
+
const chats = repo.listChats();
|
|
54
|
+
const chat1 = chats.find((c) => c.id === 1);
|
|
55
|
+
expect(chat1).toBeDefined();
|
|
56
|
+
expect(chat1?.messageCount).toBe(3);
|
|
57
|
+
});
|
|
58
|
+
it("filters by personId", () => {
|
|
59
|
+
// Person 2 (Charlie) is in chat 2, chat 3, and chat 4
|
|
60
|
+
const chats = repo.listChats({ personId: 2 });
|
|
61
|
+
expect(chats).toHaveLength(3);
|
|
62
|
+
const chatIds = chats.map((c) => c.id);
|
|
63
|
+
expect(chatIds).toContain(2);
|
|
64
|
+
expect(chatIds).toContain(3);
|
|
65
|
+
expect(chatIds).toContain(4);
|
|
66
|
+
});
|
|
67
|
+
it("respects limit parameter", () => {
|
|
68
|
+
const chats = repo.listChats({ limit: 1 });
|
|
69
|
+
expect(chats).toHaveLength(1);
|
|
70
|
+
});
|
|
71
|
+
it("respects offset parameter", () => {
|
|
72
|
+
const chats = repo.listChats({ limit: 1, offset: 1 });
|
|
73
|
+
expect(chats).toHaveLength(1);
|
|
74
|
+
expect(chats.map((c) => c.id)).toEqual([3]);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("getThread", () => {
|
|
78
|
+
it("returns messages in chronological order", () => {
|
|
79
|
+
const thread = repo.getThread(1);
|
|
80
|
+
expect(thread.messages).toHaveLength(3);
|
|
81
|
+
expect(thread.messages.map((m) => m.text)).toEqual([
|
|
82
|
+
"Hello Grace, I enjoyed your talk on compilers.",
|
|
83
|
+
"Thank you Ada! Would love to discuss analytical engines sometime.",
|
|
84
|
+
"Let us schedule a meeting next week.",
|
|
85
|
+
]);
|
|
86
|
+
});
|
|
87
|
+
it("includes sender information", () => {
|
|
88
|
+
const thread = repo.getThread(1);
|
|
89
|
+
const adaMsg = thread.messages.find((m) => m.senderPersonId === 1);
|
|
90
|
+
const graceMsg = thread.messages.find((m) => m.senderPersonId === 3);
|
|
91
|
+
expect(adaMsg).toBeDefined();
|
|
92
|
+
expect(adaMsg?.senderFirstName).toBe("Ada");
|
|
93
|
+
expect(adaMsg?.senderLastName).toBe("Lovelace");
|
|
94
|
+
expect(graceMsg).toBeDefined();
|
|
95
|
+
expect(graceMsg?.senderFirstName).toBe("Grace");
|
|
96
|
+
});
|
|
97
|
+
it("includes chat metadata", () => {
|
|
98
|
+
const thread = repo.getThread(1);
|
|
99
|
+
expect(thread.chat.id).toBe(1);
|
|
100
|
+
expect(thread.chat.type).toBe("MEMBER_TO_MEMBER");
|
|
101
|
+
expect(thread.chat.platform).toBe("LINKEDIN");
|
|
102
|
+
expect(thread.chat.participants).toHaveLength(2);
|
|
103
|
+
expect(thread.chat.messageCount).toBe(3);
|
|
104
|
+
});
|
|
105
|
+
it("includes attachments count", () => {
|
|
106
|
+
const thread = repo.getThread(1);
|
|
107
|
+
const msgWithAttachment = thread.messages.find((m) => m.text === "Let us schedule a meeting next week.");
|
|
108
|
+
expect(msgWithAttachment).toBeDefined();
|
|
109
|
+
expect(msgWithAttachment?.attachmentsCount).toBe(1);
|
|
110
|
+
});
|
|
111
|
+
it("includes subject for InMail-style messages", () => {
|
|
112
|
+
const thread = repo.getThread(2);
|
|
113
|
+
const msg = thread.messages.find((m) => m.text === "Hi Charlie, we have an opening on our team.");
|
|
114
|
+
expect(msg).toBeDefined();
|
|
115
|
+
expect(msg?.subject).toBe("Job Opportunity");
|
|
116
|
+
});
|
|
117
|
+
it("respects limit parameter", () => {
|
|
118
|
+
const thread = repo.getThread(1, { limit: 2 });
|
|
119
|
+
expect(thread.messages).toHaveLength(2);
|
|
120
|
+
});
|
|
121
|
+
it("supports before parameter for pagination", () => {
|
|
122
|
+
const thread = repo.getThread(1, {
|
|
123
|
+
before: "2025-01-11T00:00:00.000Z",
|
|
124
|
+
});
|
|
125
|
+
expect(thread.messages).toHaveLength(2);
|
|
126
|
+
expect(thread.messages.map((m) => m.text)).toEqual([
|
|
127
|
+
"Hello Grace, I enjoyed your talk on compilers.",
|
|
128
|
+
"Thank you Ada! Would love to discuss analytical engines sometime.",
|
|
129
|
+
]);
|
|
130
|
+
});
|
|
131
|
+
it("throws ChatNotFoundError for a missing chat", () => {
|
|
132
|
+
expect(() => repo.getThread(999)).toThrow(ChatNotFoundError);
|
|
133
|
+
expect(() => repo.getThread(999)).toThrow("Chat not found for id 999");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("searchMessages", () => {
|
|
137
|
+
it("finds messages containing search text", () => {
|
|
138
|
+
const results = repo.searchMessages("compiler");
|
|
139
|
+
expect(results).toHaveLength(2);
|
|
140
|
+
// Results are ordered by send_at DESC
|
|
141
|
+
expect(results.map((m) => m.text)).toEqual([
|
|
142
|
+
"Charlie, have you tried the new COBOL compiler?",
|
|
143
|
+
"Hello Grace, I enjoyed your talk on compilers.",
|
|
144
|
+
]);
|
|
145
|
+
});
|
|
146
|
+
it("returns empty array for no matches", () => {
|
|
147
|
+
const results = repo.searchMessages("nonexistent-query-xyz");
|
|
148
|
+
expect(results).toEqual([]);
|
|
149
|
+
});
|
|
150
|
+
it("respects limit parameter", () => {
|
|
151
|
+
const results = repo.searchMessages("compiler", { limit: 1 });
|
|
152
|
+
expect(results).toHaveLength(1);
|
|
153
|
+
});
|
|
154
|
+
it("is case-insensitive via LIKE", () => {
|
|
155
|
+
const results = repo.searchMessages("COBOL");
|
|
156
|
+
expect(results.length).toBeGreaterThanOrEqual(1);
|
|
157
|
+
});
|
|
158
|
+
it("escapes percent wildcard in search query", () => {
|
|
159
|
+
const results = repo.searchMessages("100%");
|
|
160
|
+
expect(results).toHaveLength(1);
|
|
161
|
+
expect(results[0]?.text).toBe("We achieved 100% coverage on the test suite!");
|
|
162
|
+
});
|
|
163
|
+
it("escapes underscore wildcard in search query", () => {
|
|
164
|
+
const results = repo.searchMessages("field_name");
|
|
165
|
+
expect(results).toHaveLength(1);
|
|
166
|
+
expect(results[0]?.text).toBe("The field_name parameter needs updating.");
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe("getMessageStats", () => {
|
|
170
|
+
it("returns aggregate statistics", () => {
|
|
171
|
+
const stats = repo.getMessageStats();
|
|
172
|
+
expect(stats.totalMessages).toBe(8);
|
|
173
|
+
expect(stats.totalChats).toBe(4);
|
|
174
|
+
expect(stats.earliestMessage).toBe("2025-01-10T09:00:00.000Z");
|
|
175
|
+
expect(stats.latestMessage).toBe("2025-01-14T09:30:00.000Z");
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=message.test.js.map
|