sweetlink 0.2.0 → 0.2.2
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/CHANGELOG.md +21 -2
- package/LICENSE +1 -1
- package/README.md +6 -6
- package/dist/daemon/src/cli.d.ts +3 -0
- package/dist/daemon/src/cli.d.ts.map +1 -0
- package/dist/daemon/src/cli.js +14 -0
- package/dist/daemon/src/cli.js.map +1 -0
- package/dist/daemon/src/codename.d.ts.map +1 -1
- package/dist/daemon/src/codename.js +11 -11
- package/dist/daemon/src/codename.js.map +1 -1
- package/dist/daemon/src/index.d.ts +1 -1
- package/dist/daemon/src/index.js +143 -128
- package/dist/daemon/src/index.js.map +1 -1
- package/dist/shared/src/env.d.ts.map +1 -1
- package/dist/shared/src/env.js +12 -12
- package/dist/shared/src/env.js.map +1 -1
- package/dist/shared/src/index.d.ts +30 -30
- package/dist/shared/src/index.d.ts.map +1 -1
- package/dist/shared/src/index.js +17 -17
- package/dist/shared/src/index.js.map +1 -1
- package/dist/shared/src/node.d.ts +1 -1
- package/dist/shared/src/node.d.ts.map +1 -1
- package/dist/shared/src/node.js +18 -18
- package/dist/shared/src/node.js.map +1 -1
- package/dist/src/codex.d.ts +1 -1
- package/dist/src/codex.js +19 -19
- package/dist/src/codex.js.map +1 -1
- package/dist/src/commands/click.d.ts +1 -1
- package/dist/src/commands/click.d.ts.map +1 -1
- package/dist/src/commands/click.js +32 -24
- package/dist/src/commands/click.js.map +1 -1
- package/dist/src/commands/run-js.d.ts +1 -1
- package/dist/src/commands/run-js.d.ts.map +1 -1
- package/dist/src/commands/run-js.js +10 -10
- package/dist/src/commands/run-js.js.map +1 -1
- package/dist/src/commands/trust-ca.d.ts +1 -1
- package/dist/src/commands/trust-ca.js +15 -15
- package/dist/src/core/config-file.d.ts.map +1 -1
- package/dist/src/core/config-file.js +49 -41
- package/dist/src/core/config-file.js.map +1 -1
- package/dist/src/core/config.d.ts +2 -2
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +22 -18
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/dev-bootstrap.d.ts +1 -1
- package/dist/src/core/dev-bootstrap.d.ts.map +1 -1
- package/dist/src/core/dev-bootstrap.js +12 -12
- package/dist/src/core/dev-bootstrap.js.map +1 -1
- package/dist/src/core/env.d.ts +1 -1
- package/dist/src/core/env.d.ts.map +1 -1
- package/dist/src/core/env.js +3 -3
- package/dist/src/core/env.js.map +1 -1
- package/dist/src/devtools-registry.d.ts.map +1 -1
- package/dist/src/devtools-registry.js +48 -46
- package/dist/src/devtools-registry.js.map +1 -1
- package/dist/src/env.d.ts +1 -1
- package/dist/src/env.js +1 -1
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +7 -6
- package/dist/src/http.js.map +1 -1
- package/dist/src/index.d.ts +7 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +399 -367
- package/dist/src/index.js.map +1 -1
- package/dist/src/runtime/browser/client.d.ts +5 -4
- package/dist/src/runtime/browser/client.d.ts.map +1 -1
- package/dist/src/runtime/browser/client.js +79 -72
- package/dist/src/runtime/browser/client.js.map +1 -1
- package/dist/src/runtime/browser/commands/index.d.ts +2 -2
- package/dist/src/runtime/browser/commands/index.js +17 -17
- package/dist/src/runtime/browser/commands/index.js.map +1 -1
- package/dist/src/runtime/browser/dom-to-image-loader.d.ts.map +1 -1
- package/dist/src/runtime/browser/dom-to-image-loader.js +7 -7
- package/dist/src/runtime/browser/dom-to-image-loader.js.map +1 -1
- package/dist/src/runtime/browser/index.d.ts +3 -3
- package/dist/src/runtime/browser/index.js +2 -2
- package/dist/src/runtime/browser/module-loader.js +2 -2
- package/dist/src/runtime/browser/screenshot/hooks.d.ts +5 -5
- package/dist/src/runtime/browser/screenshot/hooks.d.ts.map +1 -1
- package/dist/src/runtime/browser/screenshot/hooks.js +32 -29
- package/dist/src/runtime/browser/screenshot/hooks.js.map +1 -1
- package/dist/src/runtime/browser/screenshot/index.d.ts +3 -3
- package/dist/src/runtime/browser/screenshot/index.d.ts.map +1 -1
- package/dist/src/runtime/browser/screenshot/index.js +17 -15
- package/dist/src/runtime/browser/screenshot/index.js.map +1 -1
- package/dist/src/runtime/browser/screenshot/renderers/dom-to-image.d.ts +1 -1
- package/dist/src/runtime/browser/screenshot/renderers/dom-to-image.js +13 -13
- package/dist/src/runtime/browser/screenshot/renderers/dom-to-image.js.map +1 -1
- package/dist/src/runtime/browser/screenshot/renderers/html2canvas.d.ts +1 -1
- package/dist/src/runtime/browser/screenshot/renderers/html2canvas.d.ts.map +1 -1
- package/dist/src/runtime/browser/screenshot/renderers/html2canvas.js +24 -24
- package/dist/src/runtime/browser/screenshot/renderers/html2canvas.js.map +1 -1
- package/dist/src/runtime/browser/screenshot/targets.d.ts +2 -2
- package/dist/src/runtime/browser/screenshot/targets.js +9 -9
- package/dist/src/runtime/browser/screenshot/utils.d.ts +1 -1
- package/dist/src/runtime/browser/screenshot/utils.d.ts.map +1 -1
- package/dist/src/runtime/browser/screenshot/utils.js +73 -71
- package/dist/src/runtime/browser/screenshot/utils.js.map +1 -1
- package/dist/src/runtime/browser/selector-discovery.d.ts +1 -1
- package/dist/src/runtime/browser/selector-discovery.d.ts.map +1 -1
- package/dist/src/runtime/browser/selector-discovery.js +24 -22
- package/dist/src/runtime/browser/selector-discovery.js.map +1 -1
- package/dist/src/runtime/browser/storage/session-storage.d.ts +10 -5
- package/dist/src/runtime/browser/storage/session-storage.d.ts.map +1 -1
- package/dist/src/runtime/browser/storage/session-storage.js +12 -10
- package/dist/src/runtime/browser/storage/session-storage.js.map +1 -1
- package/dist/src/runtime/browser/types.d.ts +7 -7
- package/dist/src/runtime/browser/types.js +1 -1
- package/dist/src/runtime/browser/utils/console.d.ts +1 -1
- package/dist/src/runtime/browser/utils/console.js +16 -16
- package/dist/src/runtime/browser/utils/console.js.map +1 -1
- package/dist/src/runtime/browser/utils/environment.js +2 -2
- package/dist/src/runtime/browser/utils/errors.d.ts.map +1 -1
- package/dist/src/runtime/browser/utils/errors.js +11 -11
- package/dist/src/runtime/browser/utils/number.d.ts.map +1 -1
- package/dist/src/runtime/browser/utils/number.js.map +1 -1
- package/dist/src/runtime/browser/utils/object.d.ts.map +1 -1
- package/dist/src/runtime/browser/utils/object.js +2 -2
- package/dist/src/runtime/browser/utils/object.js.map +1 -1
- package/dist/src/runtime/browser/utils/sanitize.js +2 -2
- package/dist/src/runtime/browser/utils/time.d.ts.map +1 -1
- package/dist/src/runtime/browser/utils/time.js +1 -1
- package/dist/src/runtime/chrome/cookies.d.ts +4 -4
- package/dist/src/runtime/chrome/cookies.d.ts.map +1 -1
- package/dist/src/runtime/chrome/cookies.js +31 -31
- package/dist/src/runtime/chrome/cookies.js.map +1 -1
- package/dist/src/runtime/chrome/deep-link.d.ts +1 -1
- package/dist/src/runtime/chrome/deep-link.d.ts.map +1 -1
- package/dist/src/runtime/chrome/deep-link.js +46 -36
- package/dist/src/runtime/chrome/deep-link.js.map +1 -1
- package/dist/src/runtime/chrome/diagnostics.d.ts.map +1 -1
- package/dist/src/runtime/chrome/diagnostics.js +13 -11
- package/dist/src/runtime/chrome/diagnostics.js.map +1 -1
- package/dist/src/runtime/chrome/focus.d.ts.map +1 -1
- package/dist/src/runtime/chrome/focus.js +5 -5
- package/dist/src/runtime/chrome/focus.js.map +1 -1
- package/dist/src/runtime/chrome/launch.d.ts.map +1 -1
- package/dist/src/runtime/chrome/launch.js +30 -30
- package/dist/src/runtime/chrome/launch.js.map +1 -1
- package/dist/src/runtime/chrome/puppeteer.d.ts +2 -2
- package/dist/src/runtime/chrome/puppeteer.d.ts.map +1 -1
- package/dist/src/runtime/chrome/puppeteer.js +16 -11
- package/dist/src/runtime/chrome/puppeteer.js.map +1 -1
- package/dist/src/runtime/chrome/reuse.d.ts.map +1 -1
- package/dist/src/runtime/chrome/reuse.js +38 -35
- package/dist/src/runtime/chrome/reuse.js.map +1 -1
- package/dist/src/runtime/chrome/session.d.ts +1 -1
- package/dist/src/runtime/chrome/session.d.ts.map +1 -1
- package/dist/src/runtime/chrome/session.js +12 -10
- package/dist/src/runtime/chrome/session.js.map +1 -1
- package/dist/src/runtime/chrome.d.ts +8 -8
- package/dist/src/runtime/chrome.js +8 -8
- package/dist/src/runtime/cookies.d.ts +1 -16
- package/dist/src/runtime/cookies.d.ts.map +1 -1
- package/dist/src/runtime/cookies.js +175 -286
- package/dist/src/runtime/cookies.js.map +1 -1
- package/dist/src/runtime/devstack.d.ts +1 -1
- package/dist/src/runtime/devstack.d.ts.map +1 -1
- package/dist/src/runtime/devstack.js +31 -28
- package/dist/src/runtime/devstack.js.map +1 -1
- package/dist/src/runtime/devtools/background.js +22 -22
- package/dist/src/runtime/devtools/cdp.d.ts +3 -3
- package/dist/src/runtime/devtools/cdp.d.ts.map +1 -1
- package/dist/src/runtime/devtools/cdp.js +59 -55
- package/dist/src/runtime/devtools/cdp.js.map +1 -1
- package/dist/src/runtime/devtools/config.d.ts.map +1 -1
- package/dist/src/runtime/devtools/config.js +15 -15
- package/dist/src/runtime/devtools/config.js.map +1 -1
- package/dist/src/runtime/devtools/constants.d.ts.map +1 -1
- package/dist/src/runtime/devtools/constants.js +18 -10
- package/dist/src/runtime/devtools/constants.js.map +1 -1
- package/dist/src/runtime/devtools/diagnostics.d.ts +4 -4
- package/dist/src/runtime/devtools/diagnostics.d.ts.map +1 -1
- package/dist/src/runtime/devtools/diagnostics.js +40 -38
- package/dist/src/runtime/devtools/diagnostics.js.map +1 -1
- package/dist/src/runtime/devtools/oauth.d.ts +1 -1
- package/dist/src/runtime/devtools/oauth.d.ts.map +1 -1
- package/dist/src/runtime/devtools/oauth.js +35 -28
- package/dist/src/runtime/devtools/oauth.js.map +1 -1
- package/dist/src/runtime/devtools/types.d.ts +3 -3
- package/dist/src/runtime/devtools/types.d.ts.map +1 -1
- package/dist/src/runtime/devtools.d.ts +7 -7
- package/dist/src/runtime/devtools.js +7 -7
- package/dist/src/runtime/next-devtools.d.ts.map +1 -1
- package/dist/src/runtime/next-devtools.js +12 -12
- package/dist/src/runtime/next-devtools.js.map +1 -1
- package/dist/src/runtime/screenshot.d.ts +9 -9
- package/dist/src/runtime/screenshot.d.ts.map +1 -1
- package/dist/src/runtime/screenshot.js +65 -46
- package/dist/src/runtime/screenshot.js.map +1 -1
- package/dist/src/runtime/scripts.d.ts +1 -1
- package/dist/src/runtime/scripts.d.ts.map +1 -1
- package/dist/src/runtime/scripts.js +28 -28
- package/dist/src/runtime/scripts.js.map +1 -1
- package/dist/src/runtime/session.d.ts +6 -6
- package/dist/src/runtime/session.d.ts.map +1 -1
- package/dist/src/runtime/session.js +35 -35
- package/dist/src/runtime/session.js.map +1 -1
- package/dist/src/runtime/smoke.d.ts +3 -3
- package/dist/src/runtime/smoke.d.ts.map +1 -1
- package/dist/src/runtime/smoke.js +85 -79
- package/dist/src/runtime/smoke.js.map +1 -1
- package/dist/src/runtime/url.d.ts +2 -2
- package/dist/src/runtime/url.d.ts.map +1 -1
- package/dist/src/runtime/url.js +20 -20
- package/dist/src/runtime/url.js.map +1 -1
- package/dist/src/screenshot-hooks.d.ts +1 -1
- package/dist/src/screenshot-hooks.d.ts.map +1 -1
- package/dist/src/screenshot-hooks.js +12 -12
- package/dist/src/screenshot-hooks.js.map +1 -1
- package/dist/src/shared/env.d.ts.map +1 -1
- package/dist/src/shared/env.js +11 -11
- package/dist/src/shared/env.js.map +1 -1
- package/dist/src/shared/index.d.ts +30 -30
- package/dist/src/shared/index.d.ts.map +1 -1
- package/dist/src/shared/index.js +17 -17
- package/dist/src/shared/index.js.map +1 -1
- package/dist/src/shared/node.d.ts +1 -1
- package/dist/src/shared/node.d.ts.map +1 -1
- package/dist/src/shared/node.js +18 -18
- package/dist/src/shared/node.js.map +1 -1
- package/dist/src/token.d.ts +1 -1
- package/dist/src/token.d.ts.map +1 -1
- package/dist/src/token.js +16 -16
- package/dist/src/token.js.map +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/util/app-label.js +4 -4
- package/dist/src/util/errors.d.ts.map +1 -1
- package/dist/src/util/errors.js +12 -10
- package/dist/src/util/errors.js.map +1 -1
- package/dist/src/util/path.js +2 -2
- package/dist/src/util/regex.js +4 -4
- package/package.json +53 -45
package/dist/daemon/src/index.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import { spawnSync } from
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync } from
|
|
5
|
-
import { createServer as createHttpsServer, request as httpsRequest } from
|
|
6
|
-
import os from
|
|
7
|
-
import path from
|
|
8
|
-
import { URL } from
|
|
9
|
-
import { createSweetLinkCommandId, SWEETLINK_DEFAULT_PORT, SWEETLINK_HEARTBEAT_INTERVAL_MS, SWEETLINK_HEARTBEAT_TOLERANCE_MS, SWEETLINK_WS_PATH, verifySweetLinkToken, } from
|
|
10
|
-
import { readSweetLinkEnv } from
|
|
11
|
-
import { getDefaultSweetLinkSecretPath, resolveSweetLinkSecret, } from
|
|
12
|
-
import WebSocket, { WebSocketServer } from
|
|
13
|
-
import { z } from
|
|
14
|
-
import {
|
|
2
|
+
import "dotenv/config";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
5
|
+
import { createServer as createHttpsServer, request as httpsRequest } from "node:https";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { URL } from "node:url";
|
|
9
|
+
import { createSweetLinkCommandId, SWEETLINK_DEFAULT_PORT, SWEETLINK_HEARTBEAT_INTERVAL_MS, SWEETLINK_HEARTBEAT_TOLERANCE_MS, SWEETLINK_WS_PATH, verifySweetLinkToken, } from "../../shared/src/index.js";
|
|
10
|
+
import { readSweetLinkEnv } from "../../shared/src/env.js";
|
|
11
|
+
import { getDefaultSweetLinkSecretPath, resolveSweetLinkSecret, } from "../../shared/src/node.js";
|
|
12
|
+
import WebSocket, { WebSocketServer } from "ws";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import { formatDaemonHelp, isDaemonHelpRequest } from "./cli.js";
|
|
15
|
+
import { generateSessionCodename } from "./codename.js";
|
|
15
16
|
const SHUTDOWN_GRACE_MS = 1000;
|
|
16
17
|
const unrefTimer = (handle) => {
|
|
17
18
|
const candidate = handle;
|
|
18
|
-
if (typeof candidate ===
|
|
19
|
+
if (typeof candidate === "object" && candidate !== null && "unref" in candidate) {
|
|
19
20
|
const unref = candidate.unref;
|
|
20
|
-
if (typeof unref ===
|
|
21
|
+
if (typeof unref === "function") {
|
|
21
22
|
unref.call(candidate);
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -26,31 +27,31 @@ const toError = (value) => {
|
|
|
26
27
|
if (value instanceof Error) {
|
|
27
28
|
return value;
|
|
28
29
|
}
|
|
29
|
-
if (typeof value ===
|
|
30
|
+
if (typeof value === "string") {
|
|
30
31
|
return Object.assign(new Error(value), { cause: value });
|
|
31
32
|
}
|
|
32
|
-
if (value && typeof value ===
|
|
33
|
+
if (value && typeof value === "object" && "message" in value) {
|
|
33
34
|
const candidate = value.message;
|
|
34
|
-
if (typeof candidate ===
|
|
35
|
+
if (typeof candidate === "string" && candidate.trim().length > 0) {
|
|
35
36
|
return Object.assign(new Error(candidate.trim()), { cause: value });
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
return Object.assign(new Error(
|
|
39
|
+
return Object.assign(new Error("Unknown error"), { cause: value });
|
|
39
40
|
};
|
|
40
41
|
const getErrorMessage = (value) => {
|
|
41
42
|
const error = toError(value);
|
|
42
|
-
return error.message ||
|
|
43
|
+
return error.message || "Unknown error";
|
|
43
44
|
};
|
|
44
|
-
const CERT_DIR = path.join(os.homedir(),
|
|
45
|
-
const CERT_PATH = path.join(CERT_DIR,
|
|
46
|
-
const KEY_PATH = path.join(CERT_DIR,
|
|
45
|
+
const CERT_DIR = path.join(os.homedir(), ".sweetlink", "certs");
|
|
46
|
+
const CERT_PATH = path.join(CERT_DIR, "localhost-cert.pem");
|
|
47
|
+
const KEY_PATH = path.join(CERT_DIR, "localhost-key.pem");
|
|
47
48
|
const SOCKET_STATE_LABEL = {
|
|
48
|
-
0:
|
|
49
|
-
1:
|
|
50
|
-
2:
|
|
51
|
-
3:
|
|
49
|
+
0: "connecting",
|
|
50
|
+
1: "open",
|
|
51
|
+
2: "closing",
|
|
52
|
+
3: "closed",
|
|
52
53
|
};
|
|
53
|
-
const SweetLinkConsoleLevelSchema = z.enum([
|
|
54
|
+
const SweetLinkConsoleLevelSchema = z.enum(["log", "info", "warn", "error", "debug"]);
|
|
54
55
|
const consoleEventSchema = z
|
|
55
56
|
.object({
|
|
56
57
|
id: z.string(),
|
|
@@ -59,7 +60,7 @@ const consoleEventSchema = z
|
|
|
59
60
|
args: z.array(z.unknown()),
|
|
60
61
|
})
|
|
61
62
|
.passthrough();
|
|
62
|
-
const commandResultSchema = z.discriminatedUnion(
|
|
63
|
+
const commandResultSchema = z.discriminatedUnion("ok", [
|
|
63
64
|
z
|
|
64
65
|
.object({
|
|
65
66
|
ok: z.literal(true),
|
|
@@ -82,7 +83,7 @@ const commandResultSchema = z.discriminatedUnion('ok', [
|
|
|
82
83
|
]);
|
|
83
84
|
const registerMessageSchema = z
|
|
84
85
|
.object({
|
|
85
|
-
kind: z.literal(
|
|
86
|
+
kind: z.literal("register"),
|
|
86
87
|
token: z.string(),
|
|
87
88
|
sessionId: z.string(),
|
|
88
89
|
url: z.string(),
|
|
@@ -93,25 +94,25 @@ const registerMessageSchema = z
|
|
|
93
94
|
.passthrough();
|
|
94
95
|
const heartbeatMessageSchema = z
|
|
95
96
|
.object({
|
|
96
|
-
kind: z.literal(
|
|
97
|
+
kind: z.literal("heartbeat"),
|
|
97
98
|
sessionId: z.string(),
|
|
98
99
|
})
|
|
99
100
|
.passthrough();
|
|
100
101
|
const commandResultMessageSchema = z
|
|
101
102
|
.object({
|
|
102
|
-
kind: z.literal(
|
|
103
|
+
kind: z.literal("commandResult"),
|
|
103
104
|
sessionId: z.string(),
|
|
104
105
|
result: commandResultSchema,
|
|
105
106
|
})
|
|
106
107
|
.passthrough();
|
|
107
108
|
const consoleMessageSchema = z
|
|
108
109
|
.object({
|
|
109
|
-
kind: z.literal(
|
|
110
|
+
kind: z.literal("console"),
|
|
110
111
|
sessionId: z.string(),
|
|
111
112
|
events: z.array(consoleEventSchema),
|
|
112
113
|
})
|
|
113
114
|
.passthrough();
|
|
114
|
-
const clientMessageSchema = z.discriminatedUnion(
|
|
115
|
+
const clientMessageSchema = z.discriminatedUnion("kind", [
|
|
115
116
|
registerMessageSchema,
|
|
116
117
|
heartbeatMessageSchema,
|
|
117
118
|
commandResultMessageSchema,
|
|
@@ -119,7 +120,7 @@ const clientMessageSchema = z.discriminatedUnion('kind', [
|
|
|
119
120
|
]);
|
|
120
121
|
const runScriptCommandSchema = z
|
|
121
122
|
.object({
|
|
122
|
-
type: z.literal(
|
|
123
|
+
type: z.literal("runScript"),
|
|
123
124
|
code: z.string(),
|
|
124
125
|
timeoutMs: z.number().finite().positive().optional(),
|
|
125
126
|
captureConsole: z.boolean().optional(),
|
|
@@ -127,44 +128,49 @@ const runScriptCommandSchema = z
|
|
|
127
128
|
.passthrough();
|
|
128
129
|
const getDomCommandSchema = z
|
|
129
130
|
.object({
|
|
130
|
-
type: z.literal(
|
|
131
|
+
type: z.literal("getDom"),
|
|
131
132
|
selector: z.string().optional(),
|
|
132
133
|
includeShadowDom: z.boolean().optional(),
|
|
133
134
|
})
|
|
134
135
|
.passthrough();
|
|
135
136
|
const navigateCommandSchema = z
|
|
136
137
|
.object({
|
|
137
|
-
type: z.literal(
|
|
138
|
+
type: z.literal("navigate"),
|
|
138
139
|
url: z.string(),
|
|
139
140
|
})
|
|
140
141
|
.passthrough();
|
|
141
142
|
const pingCommandSchema = z
|
|
142
143
|
.object({
|
|
143
|
-
type: z.literal(
|
|
144
|
+
type: z.literal("ping"),
|
|
144
145
|
})
|
|
145
146
|
.passthrough();
|
|
146
147
|
const screenshotCommandSchema = z
|
|
147
148
|
.object({
|
|
148
|
-
type: z.literal(
|
|
149
|
-
mode: z.union([z.literal(
|
|
149
|
+
type: z.literal("screenshot"),
|
|
150
|
+
mode: z.union([z.literal("full"), z.literal("element")]).default("full"),
|
|
150
151
|
selector: z.union([z.string(), z.null()]).optional(),
|
|
151
152
|
quality: z.number().finite().min(0).max(100).optional(),
|
|
152
153
|
timeoutMs: z.number().finite().positive().optional(),
|
|
153
154
|
renderer: z
|
|
154
|
-
.union([
|
|
155
|
+
.union([
|
|
156
|
+
z.literal("auto"),
|
|
157
|
+
z.literal("puppeteer"),
|
|
158
|
+
z.literal("html2canvas"),
|
|
159
|
+
z.literal("html-to-image"),
|
|
160
|
+
])
|
|
155
161
|
.optional(),
|
|
156
162
|
hooks: z.array(z.unknown()).optional(),
|
|
157
163
|
})
|
|
158
164
|
.passthrough();
|
|
159
165
|
const discoverSelectorsCommandSchema = z
|
|
160
166
|
.object({
|
|
161
|
-
type: z.literal(
|
|
167
|
+
type: z.literal("discoverSelectors"),
|
|
162
168
|
scopeSelector: z.union([z.string(), z.null()]).optional(),
|
|
163
169
|
limit: z.number().int().positive().optional(),
|
|
164
170
|
includeHidden: z.boolean().optional(),
|
|
165
171
|
})
|
|
166
172
|
.passthrough();
|
|
167
|
-
const commandSchema = z.discriminatedUnion(
|
|
173
|
+
const commandSchema = z.discriminatedUnion("type", [
|
|
168
174
|
runScriptCommandSchema,
|
|
169
175
|
getDomCommandSchema,
|
|
170
176
|
navigateCommandSchema,
|
|
@@ -174,33 +180,35 @@ const commandSchema = z.discriminatedUnion('type', [
|
|
|
174
180
|
]);
|
|
175
181
|
const timeoutOverrideSchema = z.number().finite().positive().optional();
|
|
176
182
|
const resolveDaemonPort = (value) => {
|
|
177
|
-
if (value && typeof value ===
|
|
183
|
+
if (value && typeof value === "object" && value !== null) {
|
|
178
184
|
const portCandidate = value.port;
|
|
179
|
-
if (typeof portCandidate ===
|
|
185
|
+
if (typeof portCandidate === "number" && Number.isFinite(portCandidate) && portCandidate > 0) {
|
|
180
186
|
return portCandidate;
|
|
181
187
|
}
|
|
182
188
|
}
|
|
183
189
|
return SWEETLINK_DEFAULT_PORT;
|
|
184
190
|
};
|
|
185
191
|
const isSecretResolution = (value) => {
|
|
186
|
-
if (!value || typeof value !==
|
|
192
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
187
193
|
return false;
|
|
188
194
|
}
|
|
189
195
|
const candidate = value;
|
|
190
|
-
if (typeof candidate.secret !==
|
|
196
|
+
if (typeof candidate.secret !== "string" || candidate.secret.length === 0) {
|
|
191
197
|
return false;
|
|
192
198
|
}
|
|
193
|
-
if (candidate.source !==
|
|
199
|
+
if (candidate.source !== "env" &&
|
|
200
|
+
candidate.source !== "file" &&
|
|
201
|
+
candidate.source !== "generated") {
|
|
194
202
|
return false;
|
|
195
203
|
}
|
|
196
|
-
if (candidate.path !== undefined && typeof candidate.path !==
|
|
204
|
+
if (candidate.path !== undefined && typeof candidate.path !== "string") {
|
|
197
205
|
return false;
|
|
198
206
|
}
|
|
199
207
|
return true;
|
|
200
208
|
};
|
|
201
209
|
const assertSecretResolution = (value) => {
|
|
202
210
|
if (!isSecretResolution(value)) {
|
|
203
|
-
throw new TypeError(
|
|
211
|
+
throw new TypeError("SweetLink secret resolution payload is invalid");
|
|
204
212
|
}
|
|
205
213
|
return value;
|
|
206
214
|
};
|
|
@@ -213,24 +221,24 @@ async function main() {
|
|
|
213
221
|
}
|
|
214
222
|
const rawSecretResolution = await resolveSweetLinkSecret({ autoCreate: true });
|
|
215
223
|
const { secret, source, path: secretPath } = assertSecretResolution(rawSecretResolution);
|
|
216
|
-
log(`SweetLink secret source: ${source}${secretPath ? ` (${secretPath})` :
|
|
224
|
+
log(`SweetLink secret source: ${source}${secretPath ? ` (${secretPath})` : ""}`);
|
|
217
225
|
ensureCertificates();
|
|
218
226
|
const { cert, key } = loadCertificates();
|
|
219
227
|
const state = new SweetLinkState(secret);
|
|
220
228
|
const server = createHttpsServer({ key, cert }, (req, res) => {
|
|
221
229
|
handleHttpRequest(state, req, res).catch((error) => {
|
|
222
|
-
console.warn(
|
|
230
|
+
console.warn("SweetLink daemon request handler failed:", getErrorMessage(error));
|
|
223
231
|
});
|
|
224
232
|
});
|
|
225
233
|
const wsServer = new WebSocketServer({ server, path: SWEETLINK_WS_PATH });
|
|
226
|
-
wsServer.on(
|
|
227
|
-
server.listen(daemonPort,
|
|
234
|
+
wsServer.on("connection", (socket) => state.handleSocket(socket));
|
|
235
|
+
server.listen(daemonPort, "127.0.0.1", () => {
|
|
228
236
|
log(`SweetLink daemon listening on https://localhost:${daemonPort}`);
|
|
229
237
|
log(`WebSocket endpoint ready at wss://localhost:${daemonPort}${SWEETLINK_WS_PATH}`);
|
|
230
|
-
log(
|
|
238
|
+
log("Press Ctrl+C to stop.");
|
|
231
239
|
});
|
|
232
|
-
process.on(
|
|
233
|
-
process.on(
|
|
240
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
241
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
234
242
|
function shutdown(signal) {
|
|
235
243
|
log(`Received ${signal}, shutting down SweetLink daemon...`);
|
|
236
244
|
wsServer.close();
|
|
@@ -248,18 +256,18 @@ async function main() {
|
|
|
248
256
|
async function isDaemonAlreadyRunning(port) {
|
|
249
257
|
return await new Promise((resolve) => {
|
|
250
258
|
const request = httpsRequest({
|
|
251
|
-
hostname:
|
|
259
|
+
hostname: "127.0.0.1",
|
|
252
260
|
port,
|
|
253
|
-
path:
|
|
254
|
-
method:
|
|
261
|
+
path: "/healthz",
|
|
262
|
+
method: "GET",
|
|
255
263
|
rejectUnauthorized: false,
|
|
256
264
|
timeout: 750,
|
|
257
265
|
}, (response) => {
|
|
258
266
|
response.resume();
|
|
259
267
|
resolve(response.statusCode === 200);
|
|
260
268
|
});
|
|
261
|
-
request.on(
|
|
262
|
-
request.on(
|
|
269
|
+
request.on("error", () => resolve(false));
|
|
270
|
+
request.on("timeout", () => {
|
|
263
271
|
request.destroy();
|
|
264
272
|
resolve(false);
|
|
265
273
|
});
|
|
@@ -275,29 +283,29 @@ class SweetLinkState {
|
|
|
275
283
|
unrefTimer(expiryInterval);
|
|
276
284
|
}
|
|
277
285
|
verifyCliToken(token) {
|
|
278
|
-
return verifySweetLinkToken({ secret: this.#secret, token, expectedScope:
|
|
286
|
+
return verifySweetLinkToken({ secret: this.#secret, token, expectedScope: "cli" });
|
|
279
287
|
}
|
|
280
288
|
handleSocket(socket) {
|
|
281
289
|
let sessionId = null;
|
|
282
|
-
socket.on(
|
|
290
|
+
socket.on("message", (data) => {
|
|
283
291
|
try {
|
|
284
292
|
const raw = decodeSocketPayload(data);
|
|
285
293
|
const parsedMessage = parseClientMessage(JSON.parse(raw));
|
|
286
294
|
const message = parsedMessage;
|
|
287
295
|
switch (message.kind) {
|
|
288
|
-
case
|
|
296
|
+
case "register": {
|
|
289
297
|
sessionId = this.#handleRegister(socket, message);
|
|
290
298
|
break;
|
|
291
299
|
}
|
|
292
|
-
case
|
|
300
|
+
case "heartbeat": {
|
|
293
301
|
this.#touchSession(message.sessionId);
|
|
294
302
|
break;
|
|
295
303
|
}
|
|
296
|
-
case
|
|
304
|
+
case "commandResult": {
|
|
297
305
|
this.#handleCommandResult(message.sessionId, message.result);
|
|
298
306
|
break;
|
|
299
307
|
}
|
|
300
|
-
case
|
|
308
|
+
case "console": {
|
|
301
309
|
this.#handleConsoleEvents(message.sessionId, message.events);
|
|
302
310
|
break;
|
|
303
311
|
}
|
|
@@ -314,10 +322,12 @@ class SweetLinkState {
|
|
|
314
322
|
console.warn(`SweetLink socket error: ${errorMessage}`);
|
|
315
323
|
}
|
|
316
324
|
});
|
|
317
|
-
socket.once(
|
|
325
|
+
socket.once("close", (code, reasonBuffer) => {
|
|
318
326
|
if (sessionId) {
|
|
319
|
-
const reasonText = reasonBuffer?.toString?.(
|
|
320
|
-
const closeDetail = reasonText && reasonText.length > 0
|
|
327
|
+
const reasonText = reasonBuffer?.toString?.("utf8") ?? "";
|
|
328
|
+
const closeDetail = reasonText && reasonText.length > 0
|
|
329
|
+
? `socket closed (${code}: ${reasonText})`
|
|
330
|
+
: `socket closed (${code})`;
|
|
321
331
|
this.#removeSession(sessionId, closeDetail);
|
|
322
332
|
}
|
|
323
333
|
});
|
|
@@ -328,7 +338,7 @@ class SweetLinkState {
|
|
|
328
338
|
const consoleEventsBuffered = entry.consoleBuffer.length;
|
|
329
339
|
let consoleErrorsBuffered = 0;
|
|
330
340
|
for (const event of entry.consoleBuffer) {
|
|
331
|
-
if (event.level ===
|
|
341
|
+
if (event.level === "error") {
|
|
332
342
|
consoleErrorsBuffered += 1;
|
|
333
343
|
}
|
|
334
344
|
}
|
|
@@ -354,15 +364,15 @@ class SweetLinkState {
|
|
|
354
364
|
sendCommand(sessionId, rawCommand, timeoutMs = 15_000) {
|
|
355
365
|
const session = this.#sessions.get(sessionId);
|
|
356
366
|
if (!session) {
|
|
357
|
-
throw new Error(
|
|
367
|
+
throw new Error("Session not found or offline");
|
|
358
368
|
}
|
|
359
369
|
if (session.socket.readyState !== WebSocket.OPEN) {
|
|
360
|
-
throw new Error(
|
|
370
|
+
throw new Error("Session socket is not open");
|
|
361
371
|
}
|
|
362
372
|
const commandId = createSweetLinkCommandId();
|
|
363
373
|
const command = { ...rawCommand, id: commandId };
|
|
364
374
|
const payload = {
|
|
365
|
-
kind:
|
|
375
|
+
kind: "command",
|
|
366
376
|
sessionId: session.metadata.sessionId,
|
|
367
377
|
command,
|
|
368
378
|
};
|
|
@@ -370,7 +380,7 @@ class SweetLinkState {
|
|
|
370
380
|
return new Promise((resolve, reject) => {
|
|
371
381
|
const timeout = setTimeout(() => {
|
|
372
382
|
session.pending.delete(commandId);
|
|
373
|
-
reject(new Error(
|
|
383
|
+
reject(new Error("Command timed out"));
|
|
374
384
|
}, timeoutMs);
|
|
375
385
|
session.pending.set(commandId, {
|
|
376
386
|
commandId,
|
|
@@ -400,9 +410,9 @@ class SweetLinkState {
|
|
|
400
410
|
#handleRegister(socket, message) {
|
|
401
411
|
const token = message.token;
|
|
402
412
|
const sessionId = message.sessionId;
|
|
403
|
-
const payload = verifySweetLinkToken({ secret: this.#secret, token, expectedScope:
|
|
413
|
+
const payload = verifySweetLinkToken({ secret: this.#secret, token, expectedScope: "session" });
|
|
404
414
|
if (!payload.sessionId || payload.sessionId !== sessionId) {
|
|
405
|
-
throw new Error(
|
|
415
|
+
throw new Error("Session token mismatch");
|
|
406
416
|
}
|
|
407
417
|
const metadata = {
|
|
408
418
|
sessionId,
|
|
@@ -429,7 +439,7 @@ class SweetLinkState {
|
|
|
429
439
|
this.#sessions.set(sessionId, entry);
|
|
430
440
|
try {
|
|
431
441
|
const metadataMessage = {
|
|
432
|
-
kind:
|
|
442
|
+
kind: "metadata",
|
|
433
443
|
sessionId,
|
|
434
444
|
codename: metadata.codename,
|
|
435
445
|
};
|
|
@@ -476,7 +486,7 @@ class SweetLinkState {
|
|
|
476
486
|
}
|
|
477
487
|
}
|
|
478
488
|
#socketStateToString(readyState) {
|
|
479
|
-
return SOCKET_STATE_LABEL[readyState] ??
|
|
489
|
+
return SOCKET_STATE_LABEL[readyState] ?? "unknown";
|
|
480
490
|
}
|
|
481
491
|
#removeSession(sessionId, reason) {
|
|
482
492
|
const session = this.#sessions.get(sessionId);
|
|
@@ -505,24 +515,24 @@ async function handleHttpRequest(state, req, res) {
|
|
|
505
515
|
const basePort = daemonPort;
|
|
506
516
|
const requestUrl = req.url ? new URL(req.url, `https://localhost:${basePort}`) : null;
|
|
507
517
|
if (!requestUrl) {
|
|
508
|
-
respondJson(res, 400, { error:
|
|
518
|
+
respondJson(res, 400, { error: "Invalid request URL" });
|
|
509
519
|
return;
|
|
510
520
|
}
|
|
511
|
-
if (req.method ===
|
|
521
|
+
if (req.method === "OPTIONS") {
|
|
512
522
|
respondCors(res);
|
|
513
523
|
return;
|
|
514
524
|
}
|
|
515
|
-
if (requestUrl.pathname ===
|
|
516
|
-
respondJson(res, 200, { status:
|
|
525
|
+
if (requestUrl.pathname === "/healthz") {
|
|
526
|
+
respondJson(res, 200, { status: "ok" });
|
|
517
527
|
return;
|
|
518
528
|
}
|
|
519
529
|
const authorization = req.headers.authorization;
|
|
520
|
-
if (!authorization?.startsWith(
|
|
521
|
-
respondJson(res, 401, { error:
|
|
530
|
+
if (!authorization?.startsWith("Bearer ")) {
|
|
531
|
+
respondJson(res, 401, { error: "Missing SweetLink token" });
|
|
522
532
|
return;
|
|
523
533
|
}
|
|
524
534
|
try {
|
|
525
|
-
const token = authorization.slice(
|
|
535
|
+
const token = authorization.slice("Bearer ".length).trim();
|
|
526
536
|
state.verifyCliToken(token);
|
|
527
537
|
}
|
|
528
538
|
catch (error) {
|
|
@@ -530,29 +540,29 @@ async function handleHttpRequest(state, req, res) {
|
|
|
530
540
|
respondJson(res, 401, { error: message });
|
|
531
541
|
return;
|
|
532
542
|
}
|
|
533
|
-
if (req.method ===
|
|
543
|
+
if (req.method === "GET" && requestUrl.pathname === "/sessions") {
|
|
534
544
|
const sessions = state.listSessions();
|
|
535
545
|
respondJson(res, 200, { sessions });
|
|
536
546
|
return;
|
|
537
547
|
}
|
|
538
|
-
if (req.method ===
|
|
539
|
-
requestUrl.pathname.startsWith(
|
|
540
|
-
requestUrl.pathname.endsWith(
|
|
541
|
-
const sessionId = requestUrl.pathname.split(
|
|
548
|
+
if (req.method === "GET" &&
|
|
549
|
+
requestUrl.pathname.startsWith("/sessions/") &&
|
|
550
|
+
requestUrl.pathname.endsWith("/console")) {
|
|
551
|
+
const sessionId = requestUrl.pathname.split("/")[2];
|
|
542
552
|
if (sessionId == null) {
|
|
543
|
-
respondJson(res, 400, { error:
|
|
553
|
+
respondJson(res, 400, { error: "Session id missing" });
|
|
544
554
|
return;
|
|
545
555
|
}
|
|
546
556
|
const events = state.getSessionConsole(sessionId);
|
|
547
557
|
respondJson(res, 200, { sessionId, events });
|
|
548
558
|
return;
|
|
549
559
|
}
|
|
550
|
-
if (req.method ===
|
|
551
|
-
requestUrl.pathname.startsWith(
|
|
552
|
-
requestUrl.pathname.endsWith(
|
|
553
|
-
const sessionId = requestUrl.pathname.split(
|
|
560
|
+
if (req.method === "POST" &&
|
|
561
|
+
requestUrl.pathname.startsWith("/sessions/") &&
|
|
562
|
+
requestUrl.pathname.endsWith("/command")) {
|
|
563
|
+
const sessionId = requestUrl.pathname.split("/")[2];
|
|
554
564
|
if (sessionId == null) {
|
|
555
|
-
respondJson(res, 400, { error:
|
|
565
|
+
respondJson(res, 400, { error: "Session id missing" });
|
|
556
566
|
return;
|
|
557
567
|
}
|
|
558
568
|
try {
|
|
@@ -567,18 +577,18 @@ async function handleHttpRequest(state, req, res) {
|
|
|
567
577
|
}
|
|
568
578
|
return;
|
|
569
579
|
}
|
|
570
|
-
respondJson(res, 404, { error:
|
|
580
|
+
respondJson(res, 404, { error: "Not Found" });
|
|
571
581
|
}
|
|
572
582
|
async function readJson(req) {
|
|
573
583
|
const chunks = [];
|
|
574
584
|
for await (const chunk of req) {
|
|
575
|
-
const bufferChunk = typeof chunk ===
|
|
585
|
+
const bufferChunk = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
|
|
576
586
|
chunks.push(bufferChunk);
|
|
577
587
|
}
|
|
578
588
|
if (chunks.length === 0) {
|
|
579
589
|
return {};
|
|
580
590
|
}
|
|
581
|
-
const text = Buffer.concat(chunks).toString(
|
|
591
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
582
592
|
if (!text) {
|
|
583
593
|
return {};
|
|
584
594
|
}
|
|
@@ -587,38 +597,38 @@ async function readJson(req) {
|
|
|
587
597
|
function respondJson(res, status, body) {
|
|
588
598
|
const payload = JSON.stringify(body ?? {}, null, 2);
|
|
589
599
|
res.statusCode = status;
|
|
590
|
-
res.setHeader(
|
|
591
|
-
res.setHeader(
|
|
592
|
-
res.setHeader(
|
|
593
|
-
res.setHeader(
|
|
600
|
+
res.setHeader("Content-Type", "application/json");
|
|
601
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
602
|
+
res.setHeader("Access-Control-Allow-Headers", "authorization, content-type");
|
|
603
|
+
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
|
|
594
604
|
res.end(payload);
|
|
595
605
|
}
|
|
596
606
|
function respondCors(res) {
|
|
597
607
|
res.statusCode = 204;
|
|
598
|
-
res.setHeader(
|
|
599
|
-
res.setHeader(
|
|
600
|
-
res.setHeader(
|
|
608
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
609
|
+
res.setHeader("Access-Control-Allow-Headers", "authorization, content-type");
|
|
610
|
+
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
|
|
601
611
|
res.end();
|
|
602
612
|
}
|
|
603
613
|
function decodeSocketPayload(data) {
|
|
604
|
-
if (typeof data ===
|
|
614
|
+
if (typeof data === "string") {
|
|
605
615
|
return data;
|
|
606
616
|
}
|
|
607
617
|
if (Buffer.isBuffer(data)) {
|
|
608
|
-
return data.toString(
|
|
618
|
+
return data.toString("utf8");
|
|
609
619
|
}
|
|
610
620
|
if (Array.isArray(data)) {
|
|
611
621
|
const buffers = data.map((chunk) => (Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
612
|
-
return Buffer.concat(buffers).toString(
|
|
622
|
+
return Buffer.concat(buffers).toString("utf8");
|
|
613
623
|
}
|
|
614
624
|
if (ArrayBuffer.isView(data)) {
|
|
615
625
|
const view = data;
|
|
616
|
-
return Buffer.from(view.buffer, view.byteOffset, view.byteLength).toString(
|
|
626
|
+
return Buffer.from(view.buffer, view.byteOffset, view.byteLength).toString("utf8");
|
|
617
627
|
}
|
|
618
628
|
if (data instanceof ArrayBuffer) {
|
|
619
|
-
return Buffer.from(data).toString(
|
|
629
|
+
return Buffer.from(data).toString("utf8");
|
|
620
630
|
}
|
|
621
|
-
return Buffer.from([]).toString(
|
|
631
|
+
return Buffer.from([]).toString("utf8");
|
|
622
632
|
}
|
|
623
633
|
function parseClientMessage(raw) {
|
|
624
634
|
return clientMessageSchema.parse(raw);
|
|
@@ -630,8 +640,8 @@ function parseCommandRequest(raw) {
|
|
|
630
640
|
return { command, timeoutMs };
|
|
631
641
|
}
|
|
632
642
|
function ensureObject(value) {
|
|
633
|
-
if (!value || typeof value !==
|
|
634
|
-
throw new Error(
|
|
643
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
644
|
+
throw new Error("Request body must be a JSON object");
|
|
635
645
|
}
|
|
636
646
|
return value;
|
|
637
647
|
}
|
|
@@ -639,21 +649,21 @@ function ensureCertificates() {
|
|
|
639
649
|
if (existsSync(CERT_PATH) && existsSync(KEY_PATH)) {
|
|
640
650
|
return;
|
|
641
651
|
}
|
|
642
|
-
log(
|
|
652
|
+
log("Generating SweetLink TLS certificates via mkcert...");
|
|
643
653
|
mkdirSync(CERT_DIR, { recursive: true });
|
|
644
|
-
const mkcertLookup = spawnSync(
|
|
654
|
+
const mkcertLookup = spawnSync("which", ["mkcert"], { stdio: "pipe" });
|
|
645
655
|
if (mkcertLookup.status !== 0) {
|
|
646
656
|
const secretPath = getDefaultSweetLinkSecretPath();
|
|
647
657
|
throw new Error('mkcert is required but not found. Install via "brew install mkcert nss" and rerun pnpm sweetlink. ' +
|
|
648
658
|
`Generated SweetLink secret saved at ${secretPath}.`);
|
|
649
659
|
}
|
|
650
|
-
const install = spawnSync(
|
|
660
|
+
const install = spawnSync("mkcert", ["-install"], { stdio: "inherit" });
|
|
651
661
|
if (install.status !== 0) {
|
|
652
|
-
throw new Error(
|
|
662
|
+
throw new Error("Failed to run mkcert -install");
|
|
653
663
|
}
|
|
654
|
-
const create = spawnSync(
|
|
664
|
+
const create = spawnSync("mkcert", ["-cert-file", CERT_PATH, "-key-file", KEY_PATH, "localhost", "127.0.0.1", "::1"], { stdio: "inherit" });
|
|
655
665
|
if (create.status !== 0) {
|
|
656
|
-
throw new Error(
|
|
666
|
+
throw new Error("Failed to generate mkcert certificates");
|
|
657
667
|
}
|
|
658
668
|
}
|
|
659
669
|
function loadCertificates() {
|
|
@@ -664,12 +674,17 @@ function loadCertificates() {
|
|
|
664
674
|
function log(message) {
|
|
665
675
|
console.log(`[SweetLink] ${message}`);
|
|
666
676
|
}
|
|
667
|
-
|
|
668
|
-
|
|
677
|
+
if (isDaemonHelpRequest(process.argv.slice(2))) {
|
|
678
|
+
console.log(formatDaemonHelp());
|
|
669
679
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
680
|
+
else {
|
|
681
|
+
try {
|
|
682
|
+
await main();
|
|
683
|
+
}
|
|
684
|
+
catch (error) {
|
|
685
|
+
const message = getErrorMessage(error);
|
|
686
|
+
console.error(`[SweetLink] Daemon failed: ${message}`);
|
|
687
|
+
process.exit(1);
|
|
688
|
+
}
|
|
674
689
|
}
|
|
675
690
|
//# sourceMappingURL=index.js.map
|