@openclaw/crabline 0.1.9 → 0.1.11
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 +47 -22
- package/assets/crabline-banner.svg +20 -0
- package/dist/src/bin/crabline.js.map +1 -1
- package/dist/src/cli/program.d.ts +25 -1
- package/dist/src/cli/program.js +579 -82
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/load.js +59 -6
- package/dist/src/config/load.js.map +1 -1
- package/dist/src/config/schema.d.ts +116 -92
- package/dist/src/config/schema.js +179 -73
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/errors.js +9 -2
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/exit-codes.js.map +1 -1
- package/dist/src/core/matcher.js +7 -6
- package/dist/src/core/matcher.js.map +1 -1
- package/dist/src/core/message-template.js.map +1 -1
- package/dist/src/core/nonces.d.ts +1 -0
- package/dist/src/core/nonces.js +4 -2
- package/dist/src/core/nonces.js.map +1 -1
- package/dist/src/core/reporters.d.ts +1 -0
- package/dist/src/core/reporters.js +42 -4
- package/dist/src/core/reporters.js.map +1 -1
- package/dist/src/core/run.d.ts +3 -0
- package/dist/src/core/run.js +415 -107
- package/dist/src/core/run.js.map +1 -1
- package/dist/src/core/safe-regex.d.ts +3 -0
- package/dist/src/core/safe-regex.js +21 -0
- package/dist/src/core/safe-regex.js.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/openclaw/artifact-generation.d.ts +43 -0
- package/dist/src/openclaw/artifact-generation.js +363 -0
- package/dist/src/openclaw/artifact-generation.js.map +1 -0
- package/dist/src/openclaw/bridges/matrix.js +97 -12
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +32 -10
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/signal.js +55 -18
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +85 -7
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +124 -30
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +78 -17
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +14 -5
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/outbound-contract.d.ts +5 -0
- package/dist/src/openclaw/outbound-contract.js +40 -0
- package/dist/src/openclaw/outbound-contract.js.map +1 -0
- package/dist/src/openclaw/private-file.d.ts +28 -0
- package/dist/src/openclaw/private-file.js +465 -0
- package/dist/src/openclaw/private-file.js.map +1 -0
- package/dist/src/openclaw/shared.d.ts +21 -2
- package/dist/src/openclaw/shared.js +115 -18
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw/smoke-lock.d.ts +63 -0
- package/dist/src/openclaw/smoke-lock.js +1004 -0
- package/dist/src/openclaw/smoke-lock.js.map +1 -0
- package/dist/src/openclaw.d.ts +16 -8
- package/dist/src/openclaw.js +334 -52
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/providers/builtin/discord.d.ts +10 -1
- package/dist/src/providers/builtin/discord.js +144 -18
- package/dist/src/providers/builtin/discord.js.map +1 -1
- package/dist/src/providers/builtin/external-webhook-auth.d.ts +11 -0
- package/dist/src/providers/builtin/external-webhook-auth.js +10 -0
- package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -0
- package/dist/src/providers/builtin/feishu.d.ts +19 -2
- package/dist/src/providers/builtin/feishu.js +307 -25
- package/dist/src/providers/builtin/feishu.js.map +1 -1
- package/dist/src/providers/builtin/googlechat.d.ts +20 -1
- package/dist/src/providers/builtin/googlechat.js +178 -19
- package/dist/src/providers/builtin/googlechat.js.map +1 -1
- package/dist/src/providers/builtin/imessage.d.ts +4 -0
- package/dist/src/providers/builtin/imessage.js +26 -11
- package/dist/src/providers/builtin/imessage.js.map +1 -1
- package/dist/src/providers/builtin/loopback.js +92 -30
- package/dist/src/providers/builtin/loopback.js.map +1 -1
- package/dist/src/providers/builtin/matrix.d.ts +11 -1
- package/dist/src/providers/builtin/matrix.js +53 -29
- package/dist/src/providers/builtin/matrix.js.map +1 -1
- package/dist/src/providers/builtin/mattermost.d.ts +10 -0
- package/dist/src/providers/builtin/mattermost.js +38 -15
- package/dist/src/providers/builtin/mattermost.js.map +1 -1
- package/dist/src/providers/builtin/msteams.d.ts +17 -1
- package/dist/src/providers/builtin/msteams.js +113 -14
- package/dist/src/providers/builtin/msteams.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.d.ts +2 -9
- package/dist/src/providers/builtin/native-local-mock.js +12 -35
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/script.d.ts +11 -15
- package/dist/src/providers/builtin/script.js +566 -104
- package/dist/src/providers/builtin/script.js.map +1 -1
- package/dist/src/providers/builtin/slack.d.ts +6 -0
- package/dist/src/providers/builtin/slack.js +99 -40
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/builtin/telegram.d.ts +6 -0
- package/dist/src/providers/builtin/telegram.js +64 -43
- package/dist/src/providers/builtin/telegram.js.map +1 -1
- package/dist/src/providers/builtin/whatsapp.d.ts +28 -8
- package/dist/src/providers/builtin/whatsapp.js +567 -30
- package/dist/src/providers/builtin/whatsapp.js.map +1 -1
- package/dist/src/providers/builtin/zalo.js +30 -19
- package/dist/src/providers/builtin/zalo.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +3 -3
- package/dist/src/providers/catalog.js +3 -3
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/providers/local-mock.d.ts +11 -2
- package/dist/src/providers/local-mock.js +322 -96
- package/dist/src/providers/local-mock.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +1 -0
- package/dist/src/providers/native-ids.js +6 -1
- package/dist/src/providers/native-ids.js.map +1 -1
- package/dist/src/providers/recorder.d.ts +30 -2
- package/dist/src/providers/recorder.js +549 -70
- package/dist/src/providers/recorder.js.map +1 -1
- package/dist/src/providers/registry.d.ts +25 -1
- package/dist/src/providers/registry.js +280 -40
- package/dist/src/providers/registry.js.map +1 -1
- package/dist/src/providers/signed-jwt.d.ts +29 -0
- package/dist/src/providers/signed-jwt.js +202 -0
- package/dist/src/providers/signed-jwt.js.map +1 -0
- package/dist/src/providers/slack-ids.js.map +1 -1
- package/dist/src/providers/target-normalizers.d.ts +26 -0
- package/dist/src/providers/target-normalizers.js +276 -0
- package/dist/src/providers/target-normalizers.js.map +1 -0
- package/dist/src/providers/types.d.ts +5 -0
- package/dist/src/providers/types.js.map +1 -1
- package/dist/src/providers/webhook-server.d.ts +2 -0
- package/dist/src/providers/webhook-server.js +72 -25
- package/dist/src/providers/webhook-server.js.map +1 -1
- package/dist/src/servers/http.d.ts +23 -3
- package/dist/src/servers/http.js +213 -20
- package/dist/src/servers/http.js.map +1 -1
- package/dist/src/servers/index.js +20 -21
- package/dist/src/servers/index.js.map +1 -1
- package/dist/src/servers/matrix.js +465 -51
- package/dist/src/servers/matrix.js.map +1 -1
- package/dist/src/servers/mattermost.d.ts +5 -0
- package/dist/src/servers/mattermost.js +306 -58
- package/dist/src/servers/mattermost.js.map +1 -1
- package/dist/src/servers/pending-events.d.ts +2 -0
- package/dist/src/servers/pending-events.js +11 -0
- package/dist/src/servers/pending-events.js.map +1 -0
- package/dist/src/servers/recorder.d.ts +5 -0
- package/dist/src/servers/recorder.js +262 -3
- package/dist/src/servers/recorder.js.map +1 -1
- package/dist/src/servers/signal.d.ts +2 -0
- package/dist/src/servers/signal.js +444 -56
- package/dist/src/servers/signal.js.map +1 -1
- package/dist/src/servers/slack.d.ts +5 -0
- package/dist/src/servers/slack.js +515 -49
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram.d.ts +111 -0
- package/dist/src/servers/telegram.js +830 -158
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/webhook-target.d.ts +40 -0
- package/dist/src/servers/webhook-target.js +349 -0
- package/dist/src/servers/webhook-target.js.map +1 -0
- package/dist/src/servers/websocket.d.ts +2 -0
- package/dist/src/servers/websocket.js +29 -0
- package/dist/src/servers/websocket.js.map +1 -0
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +65 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +723 -99
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-jid.d.ts +5 -0
- package/dist/src/servers/whatsapp-jid.js +32 -0
- package/dist/src/servers/whatsapp-jid.js.map +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +5 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +87 -20
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +6 -1
- package/dist/src/servers/whatsapp-wire/crypto.js +99 -45
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/handshake.js +39 -4
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +12 -7
- package/dist/src/servers/whatsapp.js +269 -107
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/dist/src/servers/zalo.d.ts +14 -0
- package/dist/src/servers/zalo.js +521 -88
- package/dist/src/servers/zalo.js.map +1 -1
- package/docs/channel-setup.md +197 -19
- package/fixtures/examples/crabline.example.yaml +10 -0
- package/package.json +20 -15
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { inboundRegexSafetyError } from "../core/safe-regex.js";
|
|
2
3
|
export const FIXTURE_MODES = ["probe", "send", "roundtrip", "agent"];
|
|
3
4
|
const FIXTURE_ID_PATTERN = /^[a-z0-9-]+$/i;
|
|
5
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
4
6
|
export const INBOUND_AUTHORS = ["assistant", "user", "system", "any"];
|
|
5
7
|
export const INBOUND_STRATEGIES = ["contains", "exact", "regex"];
|
|
6
8
|
export const INBOUND_NONCE_MODES = ["contains", "exact", "ignore"];
|
|
@@ -44,66 +46,115 @@ export const PROVIDER_PLATFORMS = [
|
|
|
44
46
|
"zalo",
|
|
45
47
|
"zalouser",
|
|
46
48
|
];
|
|
49
|
+
const HttpUrlSchema = z
|
|
50
|
+
.string()
|
|
51
|
+
.url()
|
|
52
|
+
.refine((value) => {
|
|
53
|
+
try {
|
|
54
|
+
const protocol = new URL(value).protocol;
|
|
55
|
+
return protocol === "http:" || protocol === "https:";
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}, "URL must use http or https");
|
|
47
61
|
function inferProviderPlatform(adapter) {
|
|
48
62
|
if (adapter === "script") {
|
|
49
63
|
return undefined;
|
|
50
64
|
}
|
|
51
65
|
return adapter;
|
|
52
66
|
}
|
|
53
|
-
const TargetSchema = z.
|
|
67
|
+
const TargetSchema = z.strictObject({
|
|
54
68
|
id: z.string().min(1),
|
|
55
69
|
channelId: z.string().min(1).optional(),
|
|
56
70
|
threadId: z.string().min(1).optional(),
|
|
57
71
|
behavior: z.enum(["agent", "echo", "sink"]).optional(),
|
|
58
72
|
metadata: z.record(z.string(), z.string()).default({}),
|
|
59
73
|
});
|
|
60
|
-
const InboundMatchSchema = z
|
|
74
|
+
const InboundMatchSchema = z
|
|
75
|
+
.strictObject({
|
|
61
76
|
author: z.enum(INBOUND_AUTHORS).default("assistant"),
|
|
62
77
|
nonce: z.enum(INBOUND_NONCE_MODES).default("contains"),
|
|
63
78
|
pattern: z.string().min(1).optional(),
|
|
64
79
|
strategy: z.enum(INBOUND_STRATEGIES).default("contains"),
|
|
80
|
+
})
|
|
81
|
+
.superRefine((value, ctx) => {
|
|
82
|
+
if (value.strategy === "exact" && value.pattern && value.nonce !== "ignore") {
|
|
83
|
+
ctx.addIssue({
|
|
84
|
+
code: z.ZodIssueCode.custom,
|
|
85
|
+
message: "inboundMatch.strategy=exact requires inboundMatch.nonce=ignore",
|
|
86
|
+
path: ["nonce"],
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (value.strategy !== "regex" || !value.pattern) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
RegExp(value.pattern, "u");
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
ctx.addIssue({
|
|
97
|
+
code: z.ZodIssueCode.custom,
|
|
98
|
+
message: "inboundMatch.pattern must be a valid Unicode regular expression",
|
|
99
|
+
path: ["pattern"],
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const safetyError = inboundRegexSafetyError(value.pattern);
|
|
104
|
+
if (safetyError) {
|
|
105
|
+
ctx.addIssue({
|
|
106
|
+
code: z.ZodIssueCode.custom,
|
|
107
|
+
message: `inboundMatch.pattern ${safetyError}`,
|
|
108
|
+
path: ["pattern"],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
65
111
|
});
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
112
|
+
const ScriptCommandSchema = z
|
|
113
|
+
.string()
|
|
114
|
+
.min(1)
|
|
115
|
+
.refine((value) => value.trim().length > 0, "script command must not be blank");
|
|
116
|
+
const ScriptCommandsSchema = z.strictObject({
|
|
117
|
+
probe: ScriptCommandSchema.optional(),
|
|
118
|
+
send: ScriptCommandSchema.optional(),
|
|
119
|
+
waitForInbound: ScriptCommandSchema.optional(),
|
|
120
|
+
watch: ScriptCommandSchema.optional(),
|
|
71
121
|
});
|
|
72
|
-
const LoopbackConfigSchema = z.
|
|
73
|
-
delayMs: z.number().int().min(0).default(25),
|
|
122
|
+
const LoopbackConfigSchema = z.strictObject({
|
|
123
|
+
delayMs: z.number().int().min(0).max(MAX_TIMER_MS).default(25),
|
|
74
124
|
});
|
|
75
|
-
const ScriptConfigSchema = z.
|
|
125
|
+
const ScriptConfigSchema = z.strictObject({
|
|
76
126
|
commands: ScriptCommandsSchema,
|
|
77
127
|
cwd: z.string().min(1).optional(),
|
|
78
128
|
shell: z.string().min(1).optional(),
|
|
79
129
|
});
|
|
80
|
-
const SlackRecorderSchema = z.
|
|
130
|
+
const SlackRecorderSchema = z.strictObject({
|
|
81
131
|
path: z.string().min(1).optional(),
|
|
82
132
|
});
|
|
83
|
-
const SlackWebhookSchema = z.
|
|
133
|
+
const SlackWebhookSchema = z.strictObject({
|
|
84
134
|
host: z.string().min(1).default("127.0.0.1"),
|
|
85
135
|
path: z.string().min(1).default("/slack/events"),
|
|
86
136
|
port: z.number().int().min(0).max(65_535).default(8787),
|
|
87
|
-
publicUrl:
|
|
137
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
88
138
|
});
|
|
89
|
-
const SlackConfigSchema = z.
|
|
139
|
+
const SlackConfigSchema = z.strictObject({
|
|
90
140
|
recorder: SlackRecorderSchema.default({}),
|
|
141
|
+
signingSecret: z.string().min(1).optional(),
|
|
91
142
|
webhook: SlackWebhookSchema.default({
|
|
92
143
|
host: "127.0.0.1",
|
|
93
144
|
path: "/slack/events",
|
|
94
145
|
port: 8787,
|
|
95
146
|
}),
|
|
96
147
|
});
|
|
97
|
-
const DiscordRecorderSchema = z.
|
|
148
|
+
const DiscordRecorderSchema = z.strictObject({
|
|
98
149
|
path: z.string().min(1).optional(),
|
|
99
150
|
});
|
|
100
|
-
const DiscordWebhookSchema = z.
|
|
151
|
+
const DiscordWebhookSchema = z.strictObject({
|
|
101
152
|
host: z.string().min(1).default("127.0.0.1"),
|
|
102
153
|
path: z.string().min(1).default("/discord/interactions"),
|
|
103
154
|
port: z.number().int().min(0).max(65_535).default(8788),
|
|
104
|
-
publicUrl:
|
|
155
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
105
156
|
});
|
|
106
|
-
const DiscordConfigSchema = z.
|
|
157
|
+
const DiscordConfigSchema = z.strictObject({
|
|
107
158
|
applicationId: z.string().min(1).optional(),
|
|
108
159
|
botToken: z.string().min(1).optional(),
|
|
109
160
|
gatewayDurationMs: z.number().int().min(1000).default(180_000),
|
|
@@ -116,18 +167,18 @@ const DiscordConfigSchema = z.object({
|
|
|
116
167
|
port: 8788,
|
|
117
168
|
}),
|
|
118
169
|
});
|
|
119
|
-
const WhatsAppRecorderSchema = z.
|
|
170
|
+
const WhatsAppRecorderSchema = z.strictObject({
|
|
120
171
|
path: z.string().min(1).optional(),
|
|
121
172
|
});
|
|
122
|
-
const WhatsAppWebhookSchema = z.
|
|
173
|
+
const WhatsAppWebhookSchema = z.strictObject({
|
|
123
174
|
host: z.string().min(1).default("127.0.0.1"),
|
|
124
175
|
path: z.string().min(1).default("/whatsapp/webhook"),
|
|
125
176
|
port: z.number().int().min(0).max(65_535).default(8789),
|
|
126
|
-
publicUrl:
|
|
177
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
127
178
|
});
|
|
128
|
-
const WhatsAppConfigSchema = z.
|
|
179
|
+
const WhatsAppConfigSchema = z.strictObject({
|
|
129
180
|
accessToken: z.string().min(1).optional(),
|
|
130
|
-
apiUrl:
|
|
181
|
+
apiUrl: HttpUrlSchema.optional(),
|
|
131
182
|
apiVersion: z.string().min(1).optional(),
|
|
132
183
|
appSecret: z.string().min(1).optional(),
|
|
133
184
|
phoneNumberId: z.string().min(1).optional(),
|
|
@@ -140,21 +191,21 @@ const WhatsAppConfigSchema = z.object({
|
|
|
140
191
|
port: 8789,
|
|
141
192
|
}),
|
|
142
193
|
});
|
|
143
|
-
const MsTeamsFederatedSchema = z.
|
|
194
|
+
const MsTeamsFederatedSchema = z.strictObject({
|
|
144
195
|
clientAudience: z.string().min(1).optional(),
|
|
145
196
|
clientId: z.string().min(1),
|
|
146
197
|
});
|
|
147
|
-
const MsTeamsRecorderSchema = z.
|
|
198
|
+
const MsTeamsRecorderSchema = z.strictObject({
|
|
148
199
|
path: z.string().min(1).optional(),
|
|
149
200
|
});
|
|
150
|
-
const MsTeamsWebhookSchema = z.
|
|
201
|
+
const MsTeamsWebhookSchema = z.strictObject({
|
|
151
202
|
host: z.string().min(1).default("127.0.0.1"),
|
|
152
203
|
path: z.string().min(1).default("/msteams/webhook"),
|
|
153
204
|
port: z.number().int().min(0).max(65_535).default(8791),
|
|
154
|
-
publicUrl:
|
|
205
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
155
206
|
});
|
|
156
|
-
const MsTeamsConfigSchema = z.
|
|
157
|
-
apiUrl:
|
|
207
|
+
const MsTeamsConfigSchema = z.strictObject({
|
|
208
|
+
apiUrl: HttpUrlSchema.optional(),
|
|
158
209
|
appId: z.string().min(1).optional(),
|
|
159
210
|
appPassword: z.string().min(1).optional(),
|
|
160
211
|
appTenantId: z.string().min(1).optional(),
|
|
@@ -176,23 +227,24 @@ const GoogleChatCredentialsSchema = z
|
|
|
176
227
|
project_id: z.string().min(1).optional(),
|
|
177
228
|
})
|
|
178
229
|
.passthrough();
|
|
179
|
-
const GoogleChatRecorderSchema = z.
|
|
230
|
+
const GoogleChatRecorderSchema = z.strictObject({
|
|
180
231
|
path: z.string().min(1).optional(),
|
|
181
232
|
});
|
|
182
|
-
const GoogleChatWebhookSchema = z.
|
|
233
|
+
const GoogleChatWebhookSchema = z.strictObject({
|
|
183
234
|
host: z.string().min(1).default("127.0.0.1"),
|
|
184
235
|
path: z.string().min(1).default("/googlechat/webhook"),
|
|
185
236
|
port: z.number().int().min(0).max(65_535).default(8792),
|
|
186
|
-
publicUrl:
|
|
237
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
187
238
|
});
|
|
188
|
-
const GoogleChatConfigSchema = z.
|
|
189
|
-
apiUrl:
|
|
239
|
+
const GoogleChatConfigSchema = z.strictObject({
|
|
240
|
+
apiUrl: HttpUrlSchema.optional(),
|
|
190
241
|
credentials: GoogleChatCredentialsSchema.optional(),
|
|
191
242
|
disableSignatureVerification: z.boolean().optional(),
|
|
192
|
-
endpointUrl:
|
|
243
|
+
endpointUrl: HttpUrlSchema.optional(),
|
|
193
244
|
googleChatProjectNumber: z.string().min(1).optional(),
|
|
194
245
|
impersonateUser: z.string().min(1).optional(),
|
|
195
246
|
pubsubAudience: z.string().min(1).optional(),
|
|
247
|
+
pubsubServiceAccountEmail: z.string().min(1).optional(),
|
|
196
248
|
pubsubTopic: z.string().min(1).optional(),
|
|
197
249
|
recorder: GoogleChatRecorderSchema.default({}),
|
|
198
250
|
useApplicationDefaultCredentials: z.boolean().optional(),
|
|
@@ -203,7 +255,7 @@ const GoogleChatConfigSchema = z.object({
|
|
|
203
255
|
port: 8792,
|
|
204
256
|
}),
|
|
205
257
|
});
|
|
206
|
-
const TelegramLongPollingSchema = z.
|
|
258
|
+
const TelegramLongPollingSchema = z.strictObject({
|
|
207
259
|
allowedUpdates: z.array(z.string().min(1)).optional(),
|
|
208
260
|
deleteWebhook: z.boolean().optional(),
|
|
209
261
|
dropPendingUpdates: z.boolean().optional(),
|
|
@@ -211,17 +263,17 @@ const TelegramLongPollingSchema = z.object({
|
|
|
211
263
|
retryDelayMs: z.number().int().min(0).optional(),
|
|
212
264
|
timeout: z.number().int().min(0).optional(),
|
|
213
265
|
});
|
|
214
|
-
const TelegramRecorderSchema = z.
|
|
266
|
+
const TelegramRecorderSchema = z.strictObject({
|
|
215
267
|
path: z.string().min(1).optional(),
|
|
216
268
|
});
|
|
217
|
-
const TelegramWebhookSchema = z.
|
|
269
|
+
const TelegramWebhookSchema = z.strictObject({
|
|
218
270
|
host: z.string().min(1).default("127.0.0.1"),
|
|
219
271
|
path: z.string().min(1).default("/telegram/webhook"),
|
|
220
272
|
port: z.number().int().min(0).max(65_535).default(8790),
|
|
221
|
-
publicUrl:
|
|
273
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
222
274
|
});
|
|
223
|
-
const TelegramConfigSchema = z.
|
|
224
|
-
apiUrl:
|
|
275
|
+
const TelegramConfigSchema = z.strictObject({
|
|
276
|
+
apiUrl: HttpUrlSchema.optional(),
|
|
225
277
|
botToken: z.string().min(1).optional(),
|
|
226
278
|
longPolling: TelegramLongPollingSchema.optional(),
|
|
227
279
|
mode: z.enum(["auto", "polling", "webhook"]).default("auto"),
|
|
@@ -234,17 +286,19 @@ const TelegramConfigSchema = z.object({
|
|
|
234
286
|
port: 8790,
|
|
235
287
|
}),
|
|
236
288
|
});
|
|
237
|
-
const FeishuConfigSchema = z.
|
|
289
|
+
const FeishuConfigSchema = z.strictObject({
|
|
238
290
|
appId: z.string().min(1).optional(),
|
|
239
291
|
appSecret: z.string().min(1).optional(),
|
|
240
|
-
|
|
292
|
+
encryptKey: z.string().min(1).optional(),
|
|
293
|
+
recorder: z.strictObject({ path: z.string().min(1).optional() }).default({}),
|
|
241
294
|
userName: z.string().min(1).optional(),
|
|
295
|
+
verificationToken: z.string().min(1).optional(),
|
|
242
296
|
webhook: z
|
|
243
|
-
.
|
|
297
|
+
.strictObject({
|
|
244
298
|
host: z.string().min(1).default("127.0.0.1"),
|
|
245
299
|
path: z.string().min(1).default("/feishu/webhook"),
|
|
246
300
|
port: z.number().int().min(0).max(65_535).default(8795),
|
|
247
|
-
publicUrl:
|
|
301
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
248
302
|
})
|
|
249
303
|
.default({
|
|
250
304
|
host: "127.0.0.1",
|
|
@@ -252,24 +306,24 @@ const FeishuConfigSchema = z.object({
|
|
|
252
306
|
port: 8795,
|
|
253
307
|
}),
|
|
254
308
|
});
|
|
255
|
-
const MattermostRecorderSchema = z.
|
|
309
|
+
const MattermostRecorderSchema = z.strictObject({
|
|
256
310
|
path: z.string().min(1).optional(),
|
|
257
311
|
});
|
|
258
|
-
const MattermostWebhookSchema = z.
|
|
312
|
+
const MattermostWebhookSchema = z.strictObject({
|
|
259
313
|
host: z.string().min(1).default("127.0.0.1"),
|
|
260
314
|
path: z.string().min(1).default("/mattermost/webhook"),
|
|
261
315
|
port: z.number().int().min(0).max(65_535).default(8793),
|
|
262
|
-
publicUrl:
|
|
316
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
263
317
|
});
|
|
264
|
-
const MattermostWebsocketSchema = z.
|
|
318
|
+
const MattermostWebsocketSchema = z.strictObject({
|
|
265
319
|
enabled: z.boolean().optional(),
|
|
266
320
|
maxReconnectDelayMs: z.number().int().min(0).optional(),
|
|
267
321
|
reconnectDelayMs: z.number().int().min(0).optional(),
|
|
268
322
|
});
|
|
269
|
-
const MattermostConfigSchema = z.
|
|
270
|
-
baseUrl:
|
|
323
|
+
const MattermostConfigSchema = z.strictObject({
|
|
324
|
+
baseUrl: HttpUrlSchema.optional(),
|
|
271
325
|
botToken: z.string().min(1).optional(),
|
|
272
|
-
callbackUrl:
|
|
326
|
+
callbackUrl: HttpUrlSchema.optional(),
|
|
273
327
|
recorder: MattermostRecorderSchema.default({}),
|
|
274
328
|
userName: z.string().min(1).optional(),
|
|
275
329
|
webhook: MattermostWebhookSchema.default({
|
|
@@ -279,16 +333,16 @@ const MattermostConfigSchema = z.object({
|
|
|
279
333
|
}),
|
|
280
334
|
websocket: MattermostWebsocketSchema.optional(),
|
|
281
335
|
});
|
|
282
|
-
const ZaloRecorderSchema = z.
|
|
336
|
+
const ZaloRecorderSchema = z.strictObject({
|
|
283
337
|
path: z.string().min(1).optional(),
|
|
284
338
|
});
|
|
285
|
-
const ZaloWebhookSchema = z.
|
|
339
|
+
const ZaloWebhookSchema = z.strictObject({
|
|
286
340
|
host: z.string().min(1).default("127.0.0.1"),
|
|
287
341
|
path: z.string().min(1).default("/zalo/webhook"),
|
|
288
342
|
port: z.number().int().min(0).max(65_535).default(8794),
|
|
289
|
-
publicUrl:
|
|
343
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
290
344
|
});
|
|
291
|
-
const ZaloConfigSchema = z.
|
|
345
|
+
const ZaloConfigSchema = z.strictObject({
|
|
292
346
|
botToken: z.string().min(1).optional(),
|
|
293
347
|
recorder: ZaloRecorderSchema.default({}),
|
|
294
348
|
userName: z.string().min(1).optional(),
|
|
@@ -299,30 +353,30 @@ const ZaloConfigSchema = z.object({
|
|
|
299
353
|
}),
|
|
300
354
|
webhookSecret: z.string().min(1).optional(),
|
|
301
355
|
});
|
|
302
|
-
const MatrixAccessTokenAuthSchema = z.
|
|
356
|
+
const MatrixAccessTokenAuthSchema = z.strictObject({
|
|
303
357
|
accessToken: z.string().min(1),
|
|
304
358
|
type: z.literal("accessToken"),
|
|
305
359
|
userID: z.string().min(1).optional(),
|
|
306
360
|
});
|
|
307
|
-
const MatrixPasswordAuthSchema = z.
|
|
361
|
+
const MatrixPasswordAuthSchema = z.strictObject({
|
|
308
362
|
password: z.string().min(1),
|
|
309
363
|
type: z.literal("password"),
|
|
310
364
|
userID: z.string().min(1).optional(),
|
|
311
365
|
username: z.string().min(1),
|
|
312
366
|
});
|
|
313
|
-
const MatrixConfigSchema = z.
|
|
367
|
+
const MatrixConfigSchema = z.strictObject({
|
|
314
368
|
auth: z.union([MatrixAccessTokenAuthSchema, MatrixPasswordAuthSchema]).optional(),
|
|
315
|
-
baseURL:
|
|
369
|
+
baseURL: HttpUrlSchema.optional(),
|
|
316
370
|
commandPrefix: z.string().min(1).optional(),
|
|
317
|
-
recorder: z.
|
|
371
|
+
recorder: z.strictObject({ path: z.string().min(1).optional() }).default({}),
|
|
318
372
|
recoveryKey: z.string().min(1).optional(),
|
|
319
373
|
roomAllowlist: z.array(z.string().min(1)).optional(),
|
|
320
374
|
webhook: z
|
|
321
|
-
.
|
|
375
|
+
.strictObject({
|
|
322
376
|
host: z.string().min(1).default("127.0.0.1"),
|
|
323
377
|
path: z.string().min(1).default("/matrix/webhook"),
|
|
324
378
|
port: z.number().int().min(0).max(65_535).default(8797),
|
|
325
|
-
publicUrl:
|
|
379
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
326
380
|
})
|
|
327
381
|
.default({
|
|
328
382
|
host: "127.0.0.1",
|
|
@@ -330,18 +384,18 @@ const MatrixConfigSchema = z.object({
|
|
|
330
384
|
port: 8797,
|
|
331
385
|
}),
|
|
332
386
|
});
|
|
333
|
-
const IMessageConfigSchema = z.
|
|
387
|
+
const IMessageConfigSchema = z.strictObject({
|
|
334
388
|
apiKey: z.string().min(1).optional(),
|
|
335
389
|
gatewayDurationMs: z.number().int().min(1000).default(180_000),
|
|
336
390
|
local: z.boolean().optional(),
|
|
337
|
-
recorder: z.
|
|
338
|
-
serverUrl:
|
|
391
|
+
recorder: z.strictObject({ path: z.string().min(1).optional() }).default({}),
|
|
392
|
+
serverUrl: HttpUrlSchema.optional(),
|
|
339
393
|
webhook: z
|
|
340
|
-
.
|
|
394
|
+
.strictObject({
|
|
341
395
|
host: z.string().min(1).default("127.0.0.1"),
|
|
342
396
|
path: z.string().min(1).default("/imessage/webhook"),
|
|
343
397
|
port: z.number().int().min(0).max(65_535).default(8796),
|
|
344
|
-
publicUrl:
|
|
398
|
+
publicUrl: HttpUrlSchema.optional(),
|
|
345
399
|
})
|
|
346
400
|
.default({
|
|
347
401
|
host: "127.0.0.1",
|
|
@@ -350,7 +404,7 @@ const IMessageConfigSchema = z.object({
|
|
|
350
404
|
}),
|
|
351
405
|
});
|
|
352
406
|
export const ProviderConfigSchema = z
|
|
353
|
-
.
|
|
407
|
+
.strictObject({
|
|
354
408
|
adapter: z.enum(BUILTIN_ADAPTERS),
|
|
355
409
|
capabilities: z.array(z.enum(FIXTURE_MODES)).default(["probe", "send", "roundtrip", "agent"]),
|
|
356
410
|
discord: DiscordConfigSchema.optional(),
|
|
@@ -373,6 +427,18 @@ export const ProviderConfigSchema = z
|
|
|
373
427
|
})
|
|
374
428
|
.superRefine((value, ctx) => {
|
|
375
429
|
const platform = value.platform ?? inferProviderPlatform(value.adapter);
|
|
430
|
+
for (const adapterConfigKey of BUILTIN_ADAPTERS) {
|
|
431
|
+
if (adapterConfigKey === value.adapter || value[adapterConfigKey] === undefined) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
ctx.addIssue({
|
|
435
|
+
code: z.ZodIssueCode.custom,
|
|
436
|
+
message: value.adapter === "script"
|
|
437
|
+
? `script adapter cannot use ${adapterConfigKey} configuration; configure provider behavior through script.commands`
|
|
438
|
+
: `${adapterConfigKey} configuration requires adapter=${adapterConfigKey}, got adapter=${value.adapter}`,
|
|
439
|
+
path: [adapterConfigKey],
|
|
440
|
+
});
|
|
441
|
+
}
|
|
376
442
|
if (value.adapter === "script" && !value.script) {
|
|
377
443
|
ctx.addIssue({
|
|
378
444
|
code: z.ZodIssueCode.custom,
|
|
@@ -499,7 +565,7 @@ export const ProviderConfigSchema = z
|
|
|
499
565
|
...value,
|
|
500
566
|
platform: value.platform ?? inferProviderPlatform(value.adapter) ?? "loopback",
|
|
501
567
|
}));
|
|
502
|
-
export const FixtureSchema = z.
|
|
568
|
+
export const FixtureSchema = z.strictObject({
|
|
503
569
|
accountId: z.string().min(1).optional(),
|
|
504
570
|
env: z.array(z.string().min(1)).default([]),
|
|
505
571
|
id: z
|
|
@@ -517,12 +583,52 @@ export const FixtureSchema = z.object({
|
|
|
517
583
|
retries: z.number().int().min(0).default(0),
|
|
518
584
|
tags: z.array(z.string().min(1)).default([]),
|
|
519
585
|
target: TargetSchema,
|
|
520
|
-
timeoutMs: z.number().int().min(100).default(30_000),
|
|
586
|
+
timeoutMs: z.number().int().min(100).max(MAX_TIMER_MS).default(30_000),
|
|
521
587
|
});
|
|
522
|
-
|
|
588
|
+
const MANIFEST_EXTENSION_KEY_PATTERN = /^x-[a-z0-9][a-z0-9._-]*$/u;
|
|
589
|
+
function omitManifestExtensions(value) {
|
|
590
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
591
|
+
return value;
|
|
592
|
+
}
|
|
593
|
+
const entries = Object.entries(value);
|
|
594
|
+
const manifestEntries = entries.filter(([key]) => !MANIFEST_EXTENSION_KEY_PATTERN.test(key));
|
|
595
|
+
return manifestEntries.length === entries.length ? value : Object.fromEntries(manifestEntries);
|
|
596
|
+
}
|
|
597
|
+
const StrictManifestSchema = z
|
|
598
|
+
.strictObject({
|
|
523
599
|
configVersion: z.literal(1).default(1),
|
|
524
600
|
fixtures: z.array(FixtureSchema).default([]),
|
|
525
|
-
providers: z.record(z.string(), ProviderConfigSchema).default({}),
|
|
601
|
+
providers: z.record(z.string().min(1), ProviderConfigSchema).default({}),
|
|
526
602
|
userName: z.string().min(1).default("crabline"),
|
|
603
|
+
})
|
|
604
|
+
.superRefine((manifest, ctx) => {
|
|
605
|
+
const seenFixtureIds = new Set();
|
|
606
|
+
for (const [index, fixture] of manifest.fixtures.entries()) {
|
|
607
|
+
if (seenFixtureIds.has(fixture.id)) {
|
|
608
|
+
ctx.addIssue({
|
|
609
|
+
code: z.ZodIssueCode.custom,
|
|
610
|
+
message: `duplicate fixture id: ${fixture.id}`,
|
|
611
|
+
path: ["fixtures", index, "id"],
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
seenFixtureIds.add(fixture.id);
|
|
615
|
+
if (!Object.hasOwn(manifest.providers, fixture.provider)) {
|
|
616
|
+
ctx.addIssue({
|
|
617
|
+
code: z.ZodIssueCode.custom,
|
|
618
|
+
message: `fixture ${fixture.id} references unknown provider ${fixture.provider}`,
|
|
619
|
+
path: ["fixtures", index, "provider"],
|
|
620
|
+
});
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
const provider = manifest.providers[fixture.provider];
|
|
624
|
+
if (!provider.capabilities.includes(fixture.mode)) {
|
|
625
|
+
ctx.addIssue({
|
|
626
|
+
code: z.ZodIssueCode.custom,
|
|
627
|
+
message: `fixture ${fixture.id} uses mode ${fixture.mode}, but provider ${fixture.provider} declares capabilities ${provider.capabilities.join(", ") || "(none)"}`,
|
|
628
|
+
path: ["fixtures", index, "mode"],
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
}
|
|
527
632
|
});
|
|
633
|
+
export const ManifestSchema = z.preprocess(omitManifestExtensions, StrictManifestSchema);
|
|
528
634
|
//# sourceMappingURL=schema.js.map
|