@lhremote/cli 0.0.0 → 0.2.0
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/LICENSE +661 -0
- package/README.md +58 -2
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/handlers/campaign-add-action.d.ts +14 -0
- package/dist/handlers/campaign-add-action.d.ts.map +1 -0
- package/dist/handlers/campaign-add-action.js +51 -0
- package/dist/handlers/campaign-add-action.js.map +1 -0
- package/dist/handlers/campaign-add-action.test.d.ts +2 -0
- package/dist/handlers/campaign-add-action.test.d.ts.map +1 -0
- package/dist/handlers/campaign-add-action.test.js +121 -0
- package/dist/handlers/campaign-add-action.test.js.map +1 -0
- package/dist/handlers/campaign-create.d.ts +11 -0
- package/dist/handlers/campaign-create.d.ts.map +1 -0
- package/dist/handlers/campaign-create.js +79 -0
- package/dist/handlers/campaign-create.js.map +1 -0
- package/dist/handlers/campaign-create.test.d.ts +2 -0
- package/dist/handlers/campaign-create.test.d.ts.map +1 -0
- package/dist/handlers/campaign-create.test.js +139 -0
- package/dist/handlers/campaign-create.test.js.map +1 -0
- package/dist/handlers/campaign-delete.d.ts +8 -0
- package/dist/handlers/campaign-delete.d.ts.map +1 -0
- package/dist/handlers/campaign-delete.js +39 -0
- package/dist/handlers/campaign-delete.js.map +1 -0
- package/dist/handlers/campaign-delete.test.d.ts +2 -0
- package/dist/handlers/campaign-delete.test.d.ts.map +1 -0
- package/dist/handlers/campaign-delete.test.js +73 -0
- package/dist/handlers/campaign-delete.test.js.map +1 -0
- package/dist/handlers/campaign-exclude-add.d.ts +11 -0
- package/dist/handlers/campaign-exclude-add.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-add.js +58 -0
- package/dist/handlers/campaign-exclude-add.js.map +1 -0
- package/dist/handlers/campaign-exclude-add.test.d.ts +2 -0
- package/dist/handlers/campaign-exclude-add.test.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-add.test.js +144 -0
- package/dist/handlers/campaign-exclude-add.test.js.map +1 -0
- package/dist/handlers/campaign-exclude-list.d.ts +9 -0
- package/dist/handlers/campaign-exclude-list.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-list.js +46 -0
- package/dist/handlers/campaign-exclude-list.js.map +1 -0
- package/dist/handlers/campaign-exclude-list.test.d.ts +2 -0
- package/dist/handlers/campaign-exclude-list.test.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-list.test.js +109 -0
- package/dist/handlers/campaign-exclude-list.test.js.map +1 -0
- package/dist/handlers/campaign-exclude-remove.d.ts +11 -0
- package/dist/handlers/campaign-exclude-remove.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-remove.js +58 -0
- package/dist/handlers/campaign-exclude-remove.js.map +1 -0
- package/dist/handlers/campaign-exclude-remove.test.d.ts +2 -0
- package/dist/handlers/campaign-exclude-remove.test.d.ts.map +1 -0
- package/dist/handlers/campaign-exclude-remove.test.js +147 -0
- package/dist/handlers/campaign-exclude-remove.test.js.map +1 -0
- package/dist/handlers/campaign-export.d.ts +9 -0
- package/dist/handlers/campaign-export.d.ts.map +1 -0
- package/dist/handlers/campaign-export.js +42 -0
- package/dist/handlers/campaign-export.js.map +1 -0
- package/dist/handlers/campaign-export.test.d.ts +2 -0
- package/dist/handlers/campaign-export.test.d.ts.map +1 -0
- package/dist/handlers/campaign-export.test.js +84 -0
- package/dist/handlers/campaign-export.test.js.map +1 -0
- package/dist/handlers/campaign-get.d.ts +8 -0
- package/dist/handlers/campaign-get.d.ts.map +1 -0
- package/dist/handlers/campaign-get.js +46 -0
- package/dist/handlers/campaign-get.js.map +1 -0
- package/dist/handlers/campaign-get.test.d.ts +2 -0
- package/dist/handlers/campaign-get.test.d.ts.map +1 -0
- package/dist/handlers/campaign-get.test.js +131 -0
- package/dist/handlers/campaign-get.test.js.map +1 -0
- package/dist/handlers/campaign-list.d.ts +6 -0
- package/dist/handlers/campaign-list.d.ts.map +1 -0
- package/dist/handlers/campaign-list.js +55 -0
- package/dist/handlers/campaign-list.js.map +1 -0
- package/dist/handlers/campaign-list.test.d.ts +2 -0
- package/dist/handlers/campaign-list.test.d.ts.map +1 -0
- package/dist/handlers/campaign-list.test.js +129 -0
- package/dist/handlers/campaign-list.test.js.map +1 -0
- package/dist/handlers/campaign-move-next.d.ts +10 -0
- package/dist/handlers/campaign-move-next.d.ts.map +1 -0
- package/dist/handlers/campaign-move-next.js +52 -0
- package/dist/handlers/campaign-move-next.js.map +1 -0
- package/dist/handlers/campaign-move-next.test.d.ts +2 -0
- package/dist/handlers/campaign-move-next.test.d.ts.map +1 -0
- package/dist/handlers/campaign-move-next.test.js +127 -0
- package/dist/handlers/campaign-move-next.test.js.map +1 -0
- package/dist/handlers/campaign-remove-action.d.ts +8 -0
- package/dist/handlers/campaign-remove-action.d.ts.map +1 -0
- package/dist/handlers/campaign-remove-action.js +43 -0
- package/dist/handlers/campaign-remove-action.js.map +1 -0
- package/dist/handlers/campaign-remove-action.test.d.ts +2 -0
- package/dist/handlers/campaign-remove-action.test.d.ts.map +1 -0
- package/dist/handlers/campaign-remove-action.test.js +79 -0
- package/dist/handlers/campaign-remove-action.test.js.map +1 -0
- package/dist/handlers/campaign-reorder-actions.d.ts +9 -0
- package/dist/handlers/campaign-reorder-actions.d.ts.map +1 -0
- package/dist/handlers/campaign-reorder-actions.js +66 -0
- package/dist/handlers/campaign-reorder-actions.js.map +1 -0
- package/dist/handlers/campaign-reorder-actions.test.d.ts +2 -0
- package/dist/handlers/campaign-reorder-actions.test.d.ts.map +1 -0
- package/dist/handlers/campaign-reorder-actions.test.js +118 -0
- package/dist/handlers/campaign-reorder-actions.test.js.map +1 -0
- package/dist/handlers/campaign-retry.d.ts +10 -0
- package/dist/handlers/campaign-retry.d.ts.map +1 -0
- package/dist/handlers/campaign-retry.js +45 -0
- package/dist/handlers/campaign-retry.js.map +1 -0
- package/dist/handlers/campaign-retry.test.d.ts +2 -0
- package/dist/handlers/campaign-retry.test.d.ts.map +1 -0
- package/dist/handlers/campaign-retry.test.js +111 -0
- package/dist/handlers/campaign-retry.test.js.map +1 -0
- package/dist/handlers/campaign-start.d.ts +10 -0
- package/dist/handlers/campaign-start.d.ts.map +1 -0
- package/dist/handlers/campaign-start.js +54 -0
- package/dist/handlers/campaign-start.js.map +1 -0
- package/dist/handlers/campaign-start.test.d.ts +2 -0
- package/dist/handlers/campaign-start.test.d.ts.map +1 -0
- package/dist/handlers/campaign-start.test.js +119 -0
- package/dist/handlers/campaign-start.test.js.map +1 -0
- package/dist/handlers/campaign-statistics.d.ts +10 -0
- package/dist/handlers/campaign-statistics.d.ts.map +1 -0
- package/dist/handlers/campaign-statistics.js +63 -0
- package/dist/handlers/campaign-statistics.js.map +1 -0
- package/dist/handlers/campaign-statistics.test.d.ts +2 -0
- package/dist/handlers/campaign-statistics.test.d.ts.map +1 -0
- package/dist/handlers/campaign-statistics.test.js +141 -0
- package/dist/handlers/campaign-statistics.test.js.map +1 -0
- package/dist/handlers/campaign-status.d.ts +10 -0
- package/dist/handlers/campaign-status.d.ts.map +1 -0
- package/dist/handlers/campaign-status.js +62 -0
- package/dist/handlers/campaign-status.js.map +1 -0
- package/dist/handlers/campaign-status.test.d.ts +2 -0
- package/dist/handlers/campaign-status.test.d.ts.map +1 -0
- package/dist/handlers/campaign-status.test.js +123 -0
- package/dist/handlers/campaign-status.test.js.map +1 -0
- package/dist/handlers/campaign-stop.d.ts +8 -0
- package/dist/handlers/campaign-stop.d.ts.map +1 -0
- package/dist/handlers/campaign-stop.js +39 -0
- package/dist/handlers/campaign-stop.js.map +1 -0
- package/dist/handlers/campaign-stop.test.d.ts +2 -0
- package/dist/handlers/campaign-stop.test.d.ts.map +1 -0
- package/dist/handlers/campaign-stop.test.js +73 -0
- package/dist/handlers/campaign-stop.test.js.map +1 -0
- package/dist/handlers/campaign-update.d.ts +11 -0
- package/dist/handlers/campaign-update.d.ts.map +1 -0
- package/dist/handlers/campaign-update.js +51 -0
- package/dist/handlers/campaign-update.js.map +1 -0
- package/dist/handlers/campaign-update.test.d.ts +2 -0
- package/dist/handlers/campaign-update.test.d.ts.map +1 -0
- package/dist/handlers/campaign-update.test.js +95 -0
- package/dist/handlers/campaign-update.test.js.map +1 -0
- package/dist/handlers/check-replies.d.ts +9 -0
- package/dist/handlers/check-replies.d.ts.map +1 -0
- package/dist/handlers/check-replies.js +49 -0
- package/dist/handlers/check-replies.js.map +1 -0
- package/dist/handlers/check-replies.test.d.ts +2 -0
- package/dist/handlers/check-replies.test.d.ts.map +1 -0
- package/dist/handlers/check-replies.test.js +138 -0
- package/dist/handlers/check-replies.test.js.map +1 -0
- package/dist/handlers/check-status.d.ts +8 -0
- package/dist/handlers/check-status.d.ts.map +1 -0
- package/dist/handlers/check-status.js +50 -0
- package/dist/handlers/check-status.js.map +1 -0
- package/dist/handlers/check-status.test.d.ts +2 -0
- package/dist/handlers/check-status.test.d.ts.map +1 -0
- package/dist/handlers/check-status.test.js +112 -0
- package/dist/handlers/check-status.test.js.map +1 -0
- package/dist/handlers/describe-actions.d.ts +7 -0
- package/dist/handlers/describe-actions.d.ts.map +1 -0
- package/dist/handlers/describe-actions.js +74 -0
- package/dist/handlers/describe-actions.js.map +1 -0
- package/dist/handlers/describe-actions.test.d.ts +2 -0
- package/dist/handlers/describe-actions.test.d.ts.map +1 -0
- package/dist/handlers/describe-actions.test.js +95 -0
- package/dist/handlers/describe-actions.test.js.map +1 -0
- package/dist/handlers/find-app.d.ts +5 -0
- package/dist/handlers/find-app.d.ts.map +1 -0
- package/dist/handlers/find-app.js +28 -0
- package/dist/handlers/find-app.js.map +1 -0
- package/dist/handlers/find-app.test.d.ts +2 -0
- package/dist/handlers/find-app.test.d.ts.map +1 -0
- package/dist/handlers/find-app.test.js +75 -0
- package/dist/handlers/find-app.test.js.map +1 -0
- package/dist/handlers/import-people-from-urls.d.ts +10 -0
- package/dist/handlers/import-people-from-urls.d.ts.map +1 -0
- package/dist/handlers/import-people-from-urls.js +96 -0
- package/dist/handlers/import-people-from-urls.js.map +1 -0
- package/dist/handlers/import-people-from-urls.test.d.ts +2 -0
- package/dist/handlers/import-people-from-urls.test.d.ts.map +1 -0
- package/dist/handlers/import-people-from-urls.test.js +166 -0
- package/dist/handlers/import-people-from-urls.test.js.map +1 -0
- package/dist/handlers/index.d.ts +33 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +35 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/launch-app.d.ts +3 -0
- package/dist/handlers/launch-app.d.ts.map +1 -0
- package/dist/handlers/launch-app.js +18 -0
- package/dist/handlers/launch-app.js.map +1 -0
- package/dist/handlers/launch-app.test.d.ts +2 -0
- package/dist/handlers/launch-app.test.d.ts.map +1 -0
- package/dist/handlers/launch-app.test.js +64 -0
- package/dist/handlers/launch-app.test.js.map +1 -0
- package/dist/handlers/list-accounts.d.ts +8 -0
- package/dist/handlers/list-accounts.d.ts.map +1 -0
- package/dist/handlers/list-accounts.js +43 -0
- package/dist/handlers/list-accounts.js.map +1 -0
- package/dist/handlers/list-accounts.test.d.ts +2 -0
- package/dist/handlers/list-accounts.test.d.ts.map +1 -0
- package/dist/handlers/list-accounts.test.js +87 -0
- package/dist/handlers/list-accounts.test.js.map +1 -0
- package/dist/handlers/person-ids.d.ts +7 -0
- package/dist/handlers/person-ids.d.ts.map +1 -0
- package/dist/handlers/person-ids.js +50 -0
- package/dist/handlers/person-ids.js.map +1 -0
- package/dist/handlers/query-messages.d.ts +10 -0
- package/dist/handlers/query-messages.d.ts.map +1 -0
- package/dist/handlers/query-messages.integration.test.d.ts +2 -0
- package/dist/handlers/query-messages.integration.test.d.ts.map +1 -0
- package/dist/handlers/query-messages.integration.test.js +106 -0
- package/dist/handlers/query-messages.integration.test.js.map +1 -0
- package/dist/handlers/query-messages.js +113 -0
- package/dist/handlers/query-messages.js.map +1 -0
- package/dist/handlers/query-messages.test.d.ts +2 -0
- package/dist/handlers/query-messages.test.d.ts.map +1 -0
- package/dist/handlers/query-messages.test.js +231 -0
- package/dist/handlers/query-messages.test.js.map +1 -0
- package/dist/handlers/query-profile.d.ts +7 -0
- package/dist/handlers/query-profile.d.ts.map +1 -0
- package/dist/handlers/query-profile.js +79 -0
- package/dist/handlers/query-profile.js.map +1 -0
- package/dist/handlers/query-profile.test.d.ts +2 -0
- package/dist/handlers/query-profile.test.d.ts.map +1 -0
- package/dist/handlers/query-profile.test.js +221 -0
- package/dist/handlers/query-profile.test.js.map +1 -0
- package/dist/handlers/query-profiles.d.ts +9 -0
- package/dist/handlers/query-profiles.d.ts.map +1 -0
- package/dist/handlers/query-profiles.js +83 -0
- package/dist/handlers/query-profiles.js.map +1 -0
- package/dist/handlers/query-profiles.test.d.ts +2 -0
- package/dist/handlers/query-profiles.test.d.ts.map +1 -0
- package/dist/handlers/query-profiles.test.js +286 -0
- package/dist/handlers/query-profiles.test.js.map +1 -0
- package/dist/handlers/quit-app.d.ts +3 -0
- package/dist/handlers/quit-app.d.ts.map +1 -0
- package/dist/handlers/quit-app.js +18 -0
- package/dist/handlers/quit-app.js.map +1 -0
- package/dist/handlers/quit-app.test.d.ts +2 -0
- package/dist/handlers/quit-app.test.d.ts.map +1 -0
- package/dist/handlers/quit-app.test.js +60 -0
- package/dist/handlers/quit-app.test.js.map +1 -0
- package/dist/handlers/scrape-messaging-history.d.ts +8 -0
- package/dist/handlers/scrape-messaging-history.d.ts.map +1 -0
- package/dist/handlers/scrape-messaging-history.js +45 -0
- package/dist/handlers/scrape-messaging-history.js.map +1 -0
- package/dist/handlers/scrape-messaging-history.test.d.ts +2 -0
- package/dist/handlers/scrape-messaging-history.test.d.ts.map +1 -0
- package/dist/handlers/scrape-messaging-history.test.js +101 -0
- package/dist/handlers/scrape-messaging-history.test.js.map +1 -0
- package/dist/handlers/start-instance.d.ts +7 -0
- package/dist/handlers/start-instance.d.ts.map +1 -0
- package/dist/handlers/start-instance.js +42 -0
- package/dist/handlers/start-instance.js.map +1 -0
- package/dist/handlers/start-instance.test.d.ts +2 -0
- package/dist/handlers/start-instance.test.d.ts.map +1 -0
- package/dist/handlers/start-instance.test.js +97 -0
- package/dist/handlers/start-instance.test.js.map +1 -0
- package/dist/handlers/stop-instance.d.ts +7 -0
- package/dist/handlers/stop-instance.d.ts.map +1 -0
- package/dist/handlers/stop-instance.js +34 -0
- package/dist/handlers/stop-instance.js.map +1 -0
- package/dist/handlers/stop-instance.test.d.ts +2 -0
- package/dist/handlers/stop-instance.test.d.ts.map +1 -0
- package/dist/handlers/stop-instance.test.js +66 -0
- package/dist/handlers/stop-instance.test.js.map +1 -0
- package/dist/handlers/testing/mock-helpers.d.ts +56 -0
- package/dist/handlers/testing/mock-helpers.d.ts.map +1 -0
- package/dist/handlers/testing/mock-helpers.js +95 -0
- package/dist/handlers/testing/mock-helpers.js.map +1 -0
- package/dist/program.d.ts +6 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +341 -0
- package/dist/program.js.map +1 -0
- package/dist/program.test.d.ts +2 -0
- package/dist/program.test.d.ts.map +1 -0
- package/dist/program.test.js +154 -0
- package/dist/program.test.js.map +1 -0
- package/package.json +27 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-app.d.ts","sourceRoot":"","sources":["../../src/handlers/launch-app.ts"],"names":[],"mappings":"AAKA,4GAA4G;AAC5G,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAerD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { AppService, errorMessage } from "@lhremote/core";
|
|
4
|
+
/** Handle the {@link https://github.com/alexey-pelykh/lhremote#app-management | launch-app} CLI command. */
|
|
5
|
+
export async function handleLaunchApp() {
|
|
6
|
+
const app = new AppService();
|
|
7
|
+
try {
|
|
8
|
+
await app.launch();
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
const message = errorMessage(error);
|
|
12
|
+
process.stderr.write(`${message}\n`);
|
|
13
|
+
process.exitCode = 1;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
process.stdout.write(`LinkedHelper launched on CDP port ${String(app.cdpPort)}\n`);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=launch-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-app.js","sourceRoot":"","sources":["../../src/handlers/launch-app.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE1D,4GAA4G;AAC5G,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,GAAG,GAAG,IAAI,UAAU,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qCAAqC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAC7D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-app.test.d.ts","sourceRoot":"","sources":["../../src/handlers/launch-app.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
vi.mock("@lhremote/core", async (importOriginal) => {
|
|
5
|
+
const actual = await importOriginal();
|
|
6
|
+
return {
|
|
7
|
+
...actual,
|
|
8
|
+
AppService: vi.fn(),
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
import { AppNotFoundError, AppService } from "@lhremote/core";
|
|
12
|
+
import { handleLaunchApp } from "./launch-app.js";
|
|
13
|
+
describe("handleLaunchApp", () => {
|
|
14
|
+
const originalExitCode = process.exitCode;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
process.exitCode = undefined;
|
|
17
|
+
vi.clearAllMocks();
|
|
18
|
+
});
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
process.exitCode = originalExitCode;
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
});
|
|
23
|
+
it("prints port on successful launch", async () => {
|
|
24
|
+
const stdoutSpy = vi
|
|
25
|
+
.spyOn(process.stdout, "write")
|
|
26
|
+
.mockReturnValue(true);
|
|
27
|
+
vi.mocked(AppService).mockImplementation(function () {
|
|
28
|
+
return {
|
|
29
|
+
launch: vi.fn().mockResolvedValue(undefined),
|
|
30
|
+
cdpPort: 9222,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
await handleLaunchApp();
|
|
34
|
+
expect(stdoutSpy).toHaveBeenCalledWith("LinkedHelper launched on CDP port 9222\n");
|
|
35
|
+
expect(process.exitCode).toBeUndefined();
|
|
36
|
+
});
|
|
37
|
+
it("creates AppService without explicit port", async () => {
|
|
38
|
+
vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
39
|
+
vi.mocked(AppService).mockImplementation(function () {
|
|
40
|
+
return {
|
|
41
|
+
launch: vi.fn().mockResolvedValue(undefined),
|
|
42
|
+
cdpPort: 9222,
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
await handleLaunchApp();
|
|
46
|
+
expect(AppService).toHaveBeenCalledWith();
|
|
47
|
+
});
|
|
48
|
+
it("sets exitCode 1 on error", async () => {
|
|
49
|
+
const stderrSpy = vi
|
|
50
|
+
.spyOn(process.stderr, "write")
|
|
51
|
+
.mockReturnValue(true);
|
|
52
|
+
vi.mocked(AppService).mockImplementation(function () {
|
|
53
|
+
return {
|
|
54
|
+
launch: vi
|
|
55
|
+
.fn()
|
|
56
|
+
.mockRejectedValue(new AppNotFoundError("Binary not found at /foo")),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
await handleLaunchApp();
|
|
60
|
+
expect(process.exitCode).toBe(1);
|
|
61
|
+
expect(stderrSpy).toHaveBeenCalledWith("Binary not found at /foo\n");
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=launch-app.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-app.test.js","sourceRoot":"","sources":["../../src/handlers/launch-app.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Handle the {@link https://github.com/alexey-pelykh/lhremote#account--instance | list-accounts} CLI command. */
|
|
2
|
+
export declare function handleListAccounts(options: {
|
|
3
|
+
cdpPort?: number;
|
|
4
|
+
cdpHost?: string;
|
|
5
|
+
allowRemote?: boolean;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=list-accounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.d.ts","sourceRoot":"","sources":["../../src/handlers/list-accounts.ts"],"names":[],"mappings":"AAKA,kHAAkH;AAClH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { errorMessage, LauncherService } from "@lhremote/core";
|
|
4
|
+
/** Handle the {@link https://github.com/alexey-pelykh/lhremote#account--instance | list-accounts} CLI command. */
|
|
5
|
+
export async function handleListAccounts(options) {
|
|
6
|
+
const launcher = new LauncherService(options.cdpPort, {
|
|
7
|
+
...(options.cdpHost !== undefined && { host: options.cdpHost }),
|
|
8
|
+
...(options.allowRemote !== undefined && { allowRemote: options.allowRemote }),
|
|
9
|
+
});
|
|
10
|
+
try {
|
|
11
|
+
await launcher.connect();
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
const message = errorMessage(error);
|
|
15
|
+
process.stderr.write(`${message}\n`);
|
|
16
|
+
process.exitCode = 1;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const accounts = await launcher.listAccounts();
|
|
21
|
+
if (options.json) {
|
|
22
|
+
process.stdout.write(JSON.stringify(accounts, null, 2) + "\n");
|
|
23
|
+
}
|
|
24
|
+
else if (accounts.length === 0) {
|
|
25
|
+
process.stdout.write("No accounts found\n");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
for (const account of accounts) {
|
|
29
|
+
const email = account.email ? ` <${account.email}>` : "";
|
|
30
|
+
process.stdout.write(`${String(account.id)}\t${account.name}${email}\n`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = errorMessage(error);
|
|
36
|
+
process.stderr.write(`${message}\n`);
|
|
37
|
+
process.exitCode = 1;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
launcher.disconnect();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=list-accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.js","sourceRoot":"","sources":["../../src/handlers/list-accounts.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/D,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAKxC;IACC,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE;QACpD,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/D,GAAG,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;KAC/E,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;QAE/C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG,KAAK,IAAI,CACnD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,UAAU,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.test.d.ts","sourceRoot":"","sources":["../../src/handlers/list-accounts.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
vi.mock("@lhremote/core", async (importOriginal) => {
|
|
5
|
+
const actual = await importOriginal();
|
|
6
|
+
return {
|
|
7
|
+
...actual,
|
|
8
|
+
LauncherService: vi.fn(),
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
import { LauncherService, LinkedHelperNotRunningError, } from "@lhremote/core";
|
|
12
|
+
import { handleListAccounts } from "./list-accounts.js";
|
|
13
|
+
import { mockLauncher } from "./testing/mock-helpers.js";
|
|
14
|
+
describe("handleListAccounts", () => {
|
|
15
|
+
const originalExitCode = process.exitCode;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
process.exitCode = undefined;
|
|
18
|
+
vi.clearAllMocks();
|
|
19
|
+
});
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
process.exitCode = originalExitCode;
|
|
22
|
+
vi.restoreAllMocks();
|
|
23
|
+
});
|
|
24
|
+
it("prints JSON array with --json", async () => {
|
|
25
|
+
const stdoutSpy = vi
|
|
26
|
+
.spyOn(process.stdout, "write")
|
|
27
|
+
.mockReturnValue(true);
|
|
28
|
+
const accounts = [
|
|
29
|
+
{ id: 1, liId: 100, name: "Alice" },
|
|
30
|
+
{ id: 2, liId: 200, name: "Bob", email: "bob@example.com" },
|
|
31
|
+
];
|
|
32
|
+
mockLauncher({ listAccounts: vi.fn().mockResolvedValue(accounts) });
|
|
33
|
+
await handleListAccounts({ json: true });
|
|
34
|
+
const firstCall = stdoutSpy.mock.calls[0];
|
|
35
|
+
expect(JSON.parse(firstCall[0])).toEqual(accounts);
|
|
36
|
+
});
|
|
37
|
+
it("prints formatted table by default", async () => {
|
|
38
|
+
const stdoutSpy = vi
|
|
39
|
+
.spyOn(process.stdout, "write")
|
|
40
|
+
.mockReturnValue(true);
|
|
41
|
+
const accounts = [
|
|
42
|
+
{ id: 1, liId: 100, name: "Alice" },
|
|
43
|
+
{ id: 2, liId: 200, name: "Bob", email: "bob@example.com" },
|
|
44
|
+
];
|
|
45
|
+
mockLauncher({ listAccounts: vi.fn().mockResolvedValue(accounts) });
|
|
46
|
+
await handleListAccounts({});
|
|
47
|
+
expect(stdoutSpy).toHaveBeenCalledWith("1\tAlice\n");
|
|
48
|
+
expect(stdoutSpy).toHaveBeenCalledWith("2\tBob <bob@example.com>\n");
|
|
49
|
+
});
|
|
50
|
+
it("prints message when no accounts", async () => {
|
|
51
|
+
const stdoutSpy = vi
|
|
52
|
+
.spyOn(process.stdout, "write")
|
|
53
|
+
.mockReturnValue(true);
|
|
54
|
+
mockLauncher({ listAccounts: vi.fn().mockResolvedValue([]) });
|
|
55
|
+
await handleListAccounts({});
|
|
56
|
+
expect(stdoutSpy).toHaveBeenCalledWith("No accounts found\n");
|
|
57
|
+
});
|
|
58
|
+
it("sets exitCode 1 when not running", async () => {
|
|
59
|
+
const stderrSpy = vi
|
|
60
|
+
.spyOn(process.stderr, "write")
|
|
61
|
+
.mockReturnValue(true);
|
|
62
|
+
vi.mocked(LauncherService).mockImplementation(function () {
|
|
63
|
+
return {
|
|
64
|
+
connect: vi
|
|
65
|
+
.fn()
|
|
66
|
+
.mockRejectedValue(new LinkedHelperNotRunningError(9222)),
|
|
67
|
+
disconnect: vi.fn(),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
await handleListAccounts({});
|
|
71
|
+
expect(process.exitCode).toBe(1);
|
|
72
|
+
expect(stderrSpy).toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
it("passes cdpPort to LauncherService", async () => {
|
|
75
|
+
vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
76
|
+
mockLauncher();
|
|
77
|
+
await handleListAccounts({ cdpPort: 4567 });
|
|
78
|
+
expect(LauncherService).toHaveBeenCalledWith(4567, {});
|
|
79
|
+
});
|
|
80
|
+
it("disconnects after successful call", async () => {
|
|
81
|
+
vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
82
|
+
const { disconnect } = mockLauncher();
|
|
83
|
+
await handleListAccounts({});
|
|
84
|
+
expect(disconnect).toHaveBeenCalledOnce();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=list-accounts.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-accounts.test.js","sourceRoot":"","sources":["../../src/handlers/list-accounts.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function parsePersonIds(raw: string): number[];
|
|
2
|
+
export declare function readPersonIdsFile(filePath: string): number[];
|
|
3
|
+
export declare function resolvePersonIds(options: {
|
|
4
|
+
personIds?: string;
|
|
5
|
+
personIdsFile?: string;
|
|
6
|
+
}): number[];
|
|
7
|
+
//# sourceMappingURL=person-ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"person-ids.d.ts","sourceRoot":"","sources":["../../src/handlers/person-ids.ts"],"names":[],"mappings":"AAKA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAYpD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAa5D;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,MAAM,EAAE,CAmBX"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
export function parsePersonIds(raw) {
|
|
5
|
+
return raw
|
|
6
|
+
.split(",")
|
|
7
|
+
.map((s) => s.trim())
|
|
8
|
+
.filter((s) => s.length > 0)
|
|
9
|
+
.map((s) => {
|
|
10
|
+
const n = Number(s);
|
|
11
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
12
|
+
throw new Error(`Invalid person ID: "${s}"`);
|
|
13
|
+
}
|
|
14
|
+
return n;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function readPersonIdsFile(filePath) {
|
|
18
|
+
const content = readFileSync(filePath, "utf-8");
|
|
19
|
+
return content
|
|
20
|
+
.split(/[\n,]/)
|
|
21
|
+
.map((s) => s.trim())
|
|
22
|
+
.filter((s) => s.length > 0)
|
|
23
|
+
.map((s) => {
|
|
24
|
+
const n = Number(s);
|
|
25
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
26
|
+
throw new Error(`Invalid person ID in file: "${s}"`);
|
|
27
|
+
}
|
|
28
|
+
return n;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function resolvePersonIds(options) {
|
|
32
|
+
if (options.personIds && options.personIdsFile) {
|
|
33
|
+
throw new Error("Use only one of --person-ids or --person-ids-file.");
|
|
34
|
+
}
|
|
35
|
+
let personIds;
|
|
36
|
+
if (options.personIds) {
|
|
37
|
+
personIds = parsePersonIds(options.personIds);
|
|
38
|
+
}
|
|
39
|
+
else if (options.personIdsFile) {
|
|
40
|
+
personIds = readPersonIdsFile(options.personIdsFile);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error("Either --person-ids or --person-ids-file is required.");
|
|
44
|
+
}
|
|
45
|
+
if (personIds.length === 0) {
|
|
46
|
+
throw new Error("No person IDs provided.");
|
|
47
|
+
}
|
|
48
|
+
return personIds;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=person-ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"person-ids.js","sourceRoot":"","sources":["../../src/handlers/person-ids.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,OAAO;SACX,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAGhC;IACC,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,SAAmB,CAAC;IACxB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QACjC,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Handle the {@link https://github.com/alexey-pelykh/lhremote#profiles--messaging | query-messages} CLI command. */
|
|
2
|
+
export declare function handleQueryMessages(options: {
|
|
3
|
+
personId?: number;
|
|
4
|
+
chatId?: number;
|
|
5
|
+
search?: string;
|
|
6
|
+
limit?: number;
|
|
7
|
+
offset?: number;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=query-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-messages.d.ts","sourceRoot":"","sources":["../../src/handlers/query-messages.ts"],"names":[],"mappings":"AAcA,qHAAqH;AACrH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyEhB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-messages.integration.test.d.ts","sourceRoot":"","sources":["../../src/handlers/query-messages.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const FIXTURE_PATH = join(__dirname, "../../../core/src/db/testing/fixture.db");
|
|
8
|
+
vi.mock("@lhremote/core", async (importOriginal) => {
|
|
9
|
+
const actual = await importOriginal();
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
discoverAllDatabases: vi.fn(),
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
import { discoverAllDatabases } from "@lhremote/core";
|
|
16
|
+
import { handleQueryMessages } from "./query-messages.js";
|
|
17
|
+
describe("handleQueryMessages (integration)", () => {
|
|
18
|
+
const originalExitCode = process.exitCode;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
process.exitCode = undefined;
|
|
21
|
+
vi.mocked(discoverAllDatabases).mockReturnValue(new Map([[1, FIXTURE_PATH]]));
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
process.exitCode = originalExitCode;
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
it("outputs JSON conversation list from fixture", async () => {
|
|
28
|
+
const stdoutSpy = vi
|
|
29
|
+
.spyOn(process.stdout, "write")
|
|
30
|
+
.mockReturnValue(true);
|
|
31
|
+
await handleQueryMessages({ json: true });
|
|
32
|
+
expect(process.exitCode).toBeUndefined();
|
|
33
|
+
const output = stdoutSpy.mock.calls
|
|
34
|
+
.map((call) => String(call[0]))
|
|
35
|
+
.join("");
|
|
36
|
+
const body = JSON.parse(output);
|
|
37
|
+
expect(body.conversations.length).toBeGreaterThanOrEqual(3);
|
|
38
|
+
});
|
|
39
|
+
it("outputs JSON thread from fixture", async () => {
|
|
40
|
+
const stdoutSpy = vi
|
|
41
|
+
.spyOn(process.stdout, "write")
|
|
42
|
+
.mockReturnValue(true);
|
|
43
|
+
await handleQueryMessages({ chatId: 1, json: true });
|
|
44
|
+
expect(process.exitCode).toBeUndefined();
|
|
45
|
+
const output = stdoutSpy.mock.calls
|
|
46
|
+
.map((call) => String(call[0]))
|
|
47
|
+
.join("");
|
|
48
|
+
const body = JSON.parse(output);
|
|
49
|
+
expect(body.chat.id).toBe(1);
|
|
50
|
+
expect(body.messages.length).toBeGreaterThanOrEqual(3);
|
|
51
|
+
});
|
|
52
|
+
it("outputs JSON search results from fixture", async () => {
|
|
53
|
+
const stdoutSpy = vi
|
|
54
|
+
.spyOn(process.stdout, "write")
|
|
55
|
+
.mockReturnValue(true);
|
|
56
|
+
await handleQueryMessages({ search: "compiler", json: true });
|
|
57
|
+
expect(process.exitCode).toBeUndefined();
|
|
58
|
+
const output = stdoutSpy.mock.calls
|
|
59
|
+
.map((call) => String(call[0]))
|
|
60
|
+
.join("");
|
|
61
|
+
const body = JSON.parse(output);
|
|
62
|
+
expect(body.messages.length).toBeGreaterThanOrEqual(1);
|
|
63
|
+
});
|
|
64
|
+
it("prints human-readable conversation list from fixture", async () => {
|
|
65
|
+
const stdoutSpy = vi
|
|
66
|
+
.spyOn(process.stdout, "write")
|
|
67
|
+
.mockReturnValue(true);
|
|
68
|
+
await handleQueryMessages({});
|
|
69
|
+
expect(process.exitCode).toBeUndefined();
|
|
70
|
+
const output = stdoutSpy.mock.calls
|
|
71
|
+
.map((call) => String(call[0]))
|
|
72
|
+
.join("");
|
|
73
|
+
expect(output).toContain("Conversations (");
|
|
74
|
+
expect(output).toContain("messages)");
|
|
75
|
+
});
|
|
76
|
+
it("prints human-readable thread from fixture", async () => {
|
|
77
|
+
const stdoutSpy = vi
|
|
78
|
+
.spyOn(process.stdout, "write")
|
|
79
|
+
.mockReturnValue(true);
|
|
80
|
+
await handleQueryMessages({ chatId: 1 });
|
|
81
|
+
expect(process.exitCode).toBeUndefined();
|
|
82
|
+
const output = stdoutSpy.mock.calls
|
|
83
|
+
.map((call) => String(call[0]))
|
|
84
|
+
.join("");
|
|
85
|
+
expect(output).toContain("Conversation #1 with");
|
|
86
|
+
expect(output).toContain("Ada");
|
|
87
|
+
});
|
|
88
|
+
it("sets exitCode 1 for nonexistent chatId", async () => {
|
|
89
|
+
vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
90
|
+
await handleQueryMessages({ chatId: 999 });
|
|
91
|
+
expect(process.exitCode).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
it("filters by personId from fixture", async () => {
|
|
94
|
+
const stdoutSpy = vi
|
|
95
|
+
.spyOn(process.stdout, "write")
|
|
96
|
+
.mockReturnValue(true);
|
|
97
|
+
await handleQueryMessages({ personId: 1, json: true });
|
|
98
|
+
expect(process.exitCode).toBeUndefined();
|
|
99
|
+
const output = stdoutSpy.mock.calls
|
|
100
|
+
.map((call) => String(call[0]))
|
|
101
|
+
.join("");
|
|
102
|
+
const body = JSON.parse(output);
|
|
103
|
+
expect(body.conversations).toHaveLength(3);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=query-messages.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-messages.integration.test.js","sourceRoot":"","sources":["../../src/handlers/query-messages.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { ChatNotFoundError, DatabaseClient, discoverAllDatabases, errorMessage, MessageRepository, } from "@lhremote/core";
|
|
4
|
+
/** Handle the {@link https://github.com/alexey-pelykh/lhremote#profiles--messaging | query-messages} CLI command. */
|
|
5
|
+
export async function handleQueryMessages(options) {
|
|
6
|
+
const databases = discoverAllDatabases();
|
|
7
|
+
if (databases.size === 0) {
|
|
8
|
+
process.stderr.write("No LinkedHelper databases found.\n");
|
|
9
|
+
process.exitCode = 1;
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const limit = options.limit ?? 20;
|
|
13
|
+
const offset = options.offset ?? 0;
|
|
14
|
+
for (const [, dbPath] of databases) {
|
|
15
|
+
const db = new DatabaseClient(dbPath);
|
|
16
|
+
try {
|
|
17
|
+
const repo = new MessageRepository(db);
|
|
18
|
+
if (options.chatId != null) {
|
|
19
|
+
const thread = repo.getThread(options.chatId, { limit });
|
|
20
|
+
if (options.json) {
|
|
21
|
+
process.stdout.write(JSON.stringify(thread, null, 2) + "\n");
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
printThread(thread);
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (options.search != null) {
|
|
29
|
+
const messages = repo.searchMessages(options.search, { limit });
|
|
30
|
+
if (options.json) {
|
|
31
|
+
process.stdout.write(JSON.stringify({ messages, total: messages.length }, null, 2) + "\n");
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
printSearchResults(messages, options.search);
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const conversations = repo.listChats({
|
|
39
|
+
...(options.personId != null && { personId: options.personId }),
|
|
40
|
+
limit,
|
|
41
|
+
offset,
|
|
42
|
+
});
|
|
43
|
+
if (options.json) {
|
|
44
|
+
process.stdout.write(JSON.stringify({ conversations, total: conversations.length }, null, 2) + "\n");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
printConversationList(conversations);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof ChatNotFoundError) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const message = errorMessage(error);
|
|
56
|
+
process.stderr.write(`${message}\n`);
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
db.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
process.stderr.write("Chat not found.\n");
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
}
|
|
67
|
+
function printConversationList(conversations) {
|
|
68
|
+
if (conversations.length === 0) {
|
|
69
|
+
process.stdout.write("No conversations found.\n");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
process.stdout.write(`Conversations (${String(conversations.length)}):\n`);
|
|
73
|
+
for (const chat of conversations) {
|
|
74
|
+
const names = chat.participants
|
|
75
|
+
.map((p) => [p.firstName, p.lastName].filter(Boolean).join(" "))
|
|
76
|
+
.join(", ");
|
|
77
|
+
process.stdout.write(`\n#${String(chat.id)} with ${names} (${String(chat.messageCount)} messages)\n`);
|
|
78
|
+
if (chat.lastMessage) {
|
|
79
|
+
const date = chat.lastMessage.sendAt.slice(0, 10);
|
|
80
|
+
process.stdout.write(` Last: "${chat.lastMessage.text}" — ${date}\n`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function printThread(thread) {
|
|
85
|
+
const names = thread.chat.participants
|
|
86
|
+
.map((p) => [p.firstName, p.lastName].filter(Boolean).join(" "))
|
|
87
|
+
.join(", ");
|
|
88
|
+
process.stdout.write(`Conversation #${String(thread.chat.id)} with ${names} (${String(thread.chat.messageCount)} messages):\n`);
|
|
89
|
+
for (const msg of thread.messages) {
|
|
90
|
+
const senderName = [msg.senderFirstName, msg.senderLastName]
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.join(" ");
|
|
93
|
+
const ts = msg.sendAt.replace("T", " ").slice(0, 16);
|
|
94
|
+
process.stdout.write(`\n[${ts}] ${senderName}:\n`);
|
|
95
|
+
process.stdout.write(` ${msg.text}\n`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function printSearchResults(messages, query) {
|
|
99
|
+
if (messages.length === 0) {
|
|
100
|
+
process.stdout.write(`No messages matching "${query}".\n`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
process.stdout.write(`Messages matching "${query}" (${String(messages.length)}):\n`);
|
|
104
|
+
for (const msg of messages) {
|
|
105
|
+
const senderName = [msg.senderFirstName, msg.senderLastName]
|
|
106
|
+
.filter(Boolean)
|
|
107
|
+
.join(" ");
|
|
108
|
+
const ts = msg.sendAt.replace("T", " ").slice(0, 16);
|
|
109
|
+
process.stdout.write(`\n[${ts}] ${senderName}:\n`);
|
|
110
|
+
process.stdout.write(` ${msg.text}\n`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=query-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-messages.js","sourceRoot":"","sources":["../../src/handlers/query-messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-messages.test.d.ts","sourceRoot":"","sources":["../../src/handlers/query-messages.test.ts"],"names":[],"mappings":""}
|