@prajwalshete/telegram-plugin 0.0.0-stage → 0.1.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/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +109 -2
- package/dist/adapters/clock.d.ts +3 -0
- package/dist/adapters/clock.js +4 -0
- package/dist/adapters/console-log.d.ts +13 -0
- package/dist/adapters/console-log.js +41 -0
- package/dist/adapters/d1-db.d.ts +5 -0
- package/dist/adapters/d1-db.js +37 -0
- package/dist/adapters/ids.d.ts +5 -0
- package/dist/adapters/ids.js +25 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/keyring.d.ts +50 -0
- package/dist/adapters/keyring.js +174 -0
- package/dist/adapters/metrics.d.ts +28 -0
- package/dist/adapters/metrics.js +48 -0
- package/dist/adapters/r2-files.d.ts +20 -0
- package/dist/adapters/r2-files.js +53 -0
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +45 -0
- package/dist/client/broadcasts.d.ts +35 -0
- package/dist/client/commands.d.ts +23 -0
- package/dist/client/endpoint.d.ts +34 -0
- package/dist/client/events.d.ts +33 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.js +3 -0
- package/dist/client/schedules.d.ts +42 -0
- package/dist/client/schema.d.ts +181 -0
- package/dist/client/send.d.ts +15 -0
- package/dist/client/templates.d.ts +47 -0
- package/dist/contracts/bots.d.ts +129 -0
- package/dist/contracts/bots.js +70 -0
- package/dist/contracts/broadcasts.d.ts +116 -0
- package/dist/contracts/broadcasts.js +63 -0
- package/dist/contracts/chats.d.ts +97 -0
- package/dist/contracts/chats.js +66 -0
- package/dist/contracts/commands.d.ts +52 -0
- package/dist/contracts/commands.js +53 -0
- package/dist/contracts/common.d.ts +38 -0
- package/dist/contracts/common.js +41 -0
- package/dist/contracts/deliveries.d.ts +103 -0
- package/dist/contracts/deliveries.js +74 -0
- package/dist/contracts/destinations.d.ts +24 -0
- package/dist/contracts/destinations.js +28 -0
- package/dist/contracts/events.d.ts +165 -0
- package/dist/contracts/events.js +98 -0
- package/dist/contracts/features.d.ts +20 -0
- package/dist/contracts/features.js +21 -0
- package/dist/contracts/health.d.ts +55 -0
- package/dist/contracts/health.js +58 -0
- package/dist/contracts/index.d.ts +22 -0
- package/dist/contracts/index.js +22 -0
- package/dist/contracts/labels.d.ts +38 -0
- package/dist/contracts/labels.js +52 -0
- package/dist/contracts/links.d.ts +51 -0
- package/dist/contracts/links.js +50 -0
- package/dist/contracts/meta.d.ts +132 -0
- package/dist/contracts/meta.js +85 -0
- package/dist/contracts/permissions.d.ts +24 -0
- package/dist/contracts/permissions.js +27 -0
- package/dist/contracts/problems.d.ts +106 -0
- package/dist/contracts/problems.js +101 -0
- package/dist/contracts/recipients.d.ts +36 -0
- package/dist/contracts/recipients.js +22 -0
- package/dist/contracts/schedules.d.ts +276 -0
- package/dist/contracts/schedules.js +143 -0
- package/dist/contracts/send.d.ts +126 -0
- package/dist/contracts/send.js +69 -0
- package/dist/contracts/subscriptions.d.ts +38 -0
- package/dist/contracts/subscriptions.js +31 -0
- package/dist/contracts/templates.d.ts +358 -0
- package/dist/contracts/templates.js +174 -0
- package/dist/contracts/users.d.ts +15 -0
- package/dist/contracts/users.js +19 -0
- package/dist/core/guards.d.ts +22 -0
- package/dist/core/guards.js +47 -0
- package/dist/core/html/escape.d.ts +2 -0
- package/dist/core/html/escape.js +36 -0
- package/dist/core/html/tokenize.js +65 -0
- package/dist/core/index.d.ts +18 -0
- package/dist/core/pacing.d.ts +1 -0
- package/dist/core/pacing.js +86 -0
- package/dist/core/random.d.ts +2 -0
- package/dist/core/random.js +38 -0
- package/dist/core/recipients.d.ts +1 -0
- package/dist/core/recipients.js +86 -0
- package/dist/core/schedule/describe.d.ts +3 -0
- package/dist/core/schedule/describe.js +74 -0
- package/dist/core/schedule/index.d.ts +4 -0
- package/dist/core/schedule/policy.d.ts +1 -0
- package/dist/core/schedule/policy.js +37 -0
- package/dist/core/schedule/rule.d.ts +25 -0
- package/dist/core/schedule/rule.js +142 -0
- package/dist/core/schedule/tz.d.ts +2 -0
- package/dist/core/schedule/tz.js +59 -0
- package/dist/core/split/plain.d.ts +2 -0
- package/dist/core/split/plain.js +23 -0
- package/dist/core/split/split.d.ts +15 -0
- package/dist/core/split/split.js +158 -0
- package/dist/core/template/ast.d.ts +58 -0
- package/dist/core/template/ast.js +5 -0
- package/dist/core/template/expr.js +108 -0
- package/dist/core/template/filters.d.ts +20 -0
- package/dist/core/template/filters.js +127 -0
- package/dist/core/template/format.d.ts +17 -0
- package/dist/core/template/format.js +88 -0
- package/dist/core/template/index.d.ts +20 -0
- package/dist/core/template/index.js +29 -0
- package/dist/core/template/parse.d.ts +8 -0
- package/dist/core/template/parse.js +369 -0
- package/dist/core/template/render.d.ts +17 -0
- package/dist/core/template/render.js +118 -0
- package/dist/core/template/shape.d.ts +28 -0
- package/dist/core/template/shape.js +151 -0
- package/dist/core/template/tags.js +105 -0
- package/dist/core/template/validate.d.ts +10 -0
- package/dist/core/template/validate.js +144 -0
- package/dist/core/template/variables.d.ts +15 -0
- package/dist/core/template/variables.js +41 -0
- package/dist/do/index.d.ts +3 -0
- package/dist/do/index.js +3 -0
- package/dist/do/telegram-bot-do.d.ts +45 -0
- package/dist/do/telegram-bot-do.js +219 -0
- package/dist/engine/actions/callback.js +256 -0
- package/dist/engine/actions/tokens.d.ts +2 -0
- package/dist/engine/actions/tokens.js +51 -0
- package/dist/engine/bot-api.js +20 -0
- package/dist/engine/bot-features.js +39 -0
- package/dist/engine/chat-state.js +66 -0
- package/dist/engine/content/audience.js +54 -0
- package/dist/engine/content/buttons.d.ts +1 -0
- package/dist/engine/content/buttons.js +113 -0
- package/dist/engine/content/fanout.js +284 -0
- package/dist/engine/content/intersect.d.ts +6 -0
- package/dist/engine/content/intersect.js +26 -0
- package/dist/engine/content/providers.d.ts +6 -0
- package/dist/engine/content/providers.js +142 -0
- package/dist/engine/content/recipients.js +128 -0
- package/dist/engine/content/render.js +138 -0
- package/dist/engine/content/reply.js +156 -0
- package/dist/engine/content/report-files.js +78 -0
- package/dist/engine/content/template-rows.js +74 -0
- package/dist/engine/dialogs/dialog.d.ts +2 -0
- package/dist/engine/dialogs/dialog.js +375 -0
- package/dist/engine/dispatch/builtins.js +198 -0
- package/dist/engine/dispatch/commands.js +194 -0
- package/dist/engine/dispatch/context.d.ts +2 -0
- package/dist/engine/dispatch/context.js +194 -0
- package/dist/engine/dispatch/dispatcher.js +66 -0
- package/dist/engine/dispatch/handlers.d.ts +1 -0
- package/dist/engine/dispatch/handlers.js +103 -0
- package/dist/engine/dispatch/lifecycle.js +85 -0
- package/dist/engine/dispatch/link-chat.js +31 -0
- package/dist/engine/dispatch/linking.js +273 -0
- package/dist/engine/errors.d.ts +60 -0
- package/dist/engine/errors.js +72 -0
- package/dist/engine/events/filters.d.ts +5 -0
- package/dist/engine/events/filters.js +82 -0
- package/dist/engine/events/kick.js +30 -0
- package/dist/engine/events/payload.d.ts +3 -0
- package/dist/engine/events/payload.js +16 -0
- package/dist/engine/events/tick.js +208 -0
- package/dist/engine/i18n.d.ts +12 -0
- package/dist/engine/i18n.js +55 -0
- package/dist/engine/inbound/files.js +121 -0
- package/dist/engine/inbound/handler.js +46 -0
- package/dist/engine/jobs.d.ts +32 -0
- package/dist/engine/jobs.js +85 -0
- package/dist/engine/link-codes.js +46 -0
- package/dist/engine/metrics.js +12 -0
- package/dist/engine/options.d.ts +369 -0
- package/dist/engine/options.js +81 -0
- package/dist/engine/outbox/dead-letter.js +78 -0
- package/dist/engine/outbox/do-registry.d.ts +10 -0
- package/dist/engine/outbox/do-registry.js +10 -0
- package/dist/engine/outbox/do-transport.d.ts +33 -0
- package/dist/engine/outbox/do-transport.js +73 -0
- package/dist/engine/outbox/drain.d.ts +13 -0
- package/dist/engine/outbox/drain.js +381 -0
- package/dist/engine/outbox/enqueue.d.ts +1 -0
- package/dist/engine/outbox/enqueue.js +63 -0
- package/dist/engine/outbox/select.js +24 -0
- package/dist/engine/outbox/send.js +362 -0
- package/dist/engine/outbox/transport.d.ts +35 -0
- package/dist/engine/outbox/transport.js +175 -0
- package/dist/engine/outbox/wake.js +28 -0
- package/dist/engine/registry.d.ts +502 -0
- package/dist/engine/registry.js +258 -0
- package/dist/engine/rows.d.ts +25 -0
- package/dist/engine/rows.js +131 -0
- package/dist/engine/runtime.d.ts +95 -0
- package/dist/engine/runtime.js +149 -0
- package/dist/engine/schedules/fire.js +208 -0
- package/dist/engine/schedules/resume.js +75 -0
- package/dist/engine/schedules/rows.js +69 -0
- package/dist/engine/schedules/tick.js +30 -0
- package/dist/engine/schedules/wake.js +50 -0
- package/dist/engine/state.d.ts +11 -0
- package/dist/engine/state.js +78 -0
- package/dist/locales/en.js +339 -0
- package/dist/locales/en.json +341 -0
- package/dist/locales/mr.js +339 -0
- package/dist/locales/mr.json +341 -0
- package/dist/ports/db.d.ts +22 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/ports.d.ts +257 -0
- package/dist/ports/sql.d.ts +39 -0
- package/dist/ports/sql.js +76 -0
- package/dist/renderers/csv.d.ts +14 -0
- package/dist/renderers/csv.js +51 -0
- package/dist/renderers/html.d.ts +44 -0
- package/dist/renderers/html.js +81 -0
- package/dist/renderers/index.d.ts +5 -0
- package/dist/renderers/index.js +4 -0
- package/dist/renderers/table.d.ts +30 -0
- package/dist/renderers/table.js +114 -0
- package/dist/routes/admin.js +146 -0
- package/dist/routes/app.d.ts +3111 -0
- package/dist/routes/app.js +9 -0
- package/dist/routes/broadcasts.js +37 -0
- package/dist/routes/commands.js +35 -0
- package/dist/routes/content.js +12 -0
- package/dist/routes/events.js +36 -0
- package/dist/routes/http.d.ts +30 -0
- package/dist/routes/http.js +223 -0
- package/dist/routes/me.js +59 -0
- package/dist/routes/schedules.js +62 -0
- package/dist/routes/send.js +24 -0
- package/dist/routes/templates.js +70 -0
- package/dist/routes/webhook.js +147 -0
- package/dist/schema/columns.js +307 -0
- package/dist/schema/ddl.d.ts +7 -0
- package/dist/schema/ddl.js +45 -0
- package/dist/schema/index.d.ts +4255 -0
- package/dist/schema/index.js +44 -0
- package/dist/schema/reference.sql +359 -0
- package/dist/schema/tables.d.ts +4243 -0
- package/dist/schema/tables.js +327 -0
- package/dist/schema/version.d.ts +5 -0
- package/dist/schema/version.js +7 -0
- package/dist/server/index.d.ts +55 -0
- package/dist/server/index.js +46 -0
- package/dist/server/plugin.d.ts +81 -0
- package/dist/server/plugin.js +247 -0
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.js +4 -0
- package/dist/services/ai-tool.d.ts +26 -0
- package/dist/services/ai-tool.js +148 -0
- package/dist/services/bots.js +300 -0
- package/dist/services/broadcasts.js +390 -0
- package/dist/services/chats.js +83 -0
- package/dist/services/cleanup.js +83 -0
- package/dist/services/commands.js +140 -0
- package/dist/services/deliveries.js +53 -0
- package/dist/services/destinations.js +91 -0
- package/dist/services/event-rules.js +229 -0
- package/dist/services/events.js +20 -0
- package/dist/services/idempotency.js +64 -0
- package/dist/services/links.js +200 -0
- package/dist/services/menu.js +95 -0
- package/dist/services/ops.js +90 -0
- package/dist/services/rekey.js +63 -0
- package/dist/services/reports.js +87 -0
- package/dist/services/schedules.js +214 -0
- package/dist/services/send.d.ts +14 -0
- package/dist/services/send.js +421 -0
- package/dist/services/subscriptions.js +28 -0
- package/dist/services/templates.js +259 -0
- package/dist/telegram/classify.d.ts +30 -0
- package/dist/telegram/classify.js +164 -0
- package/dist/telegram/client.d.ts +73 -0
- package/dist/telegram/client.js +135 -0
- package/dist/telegram/errors.d.ts +37 -0
- package/dist/telegram/errors.js +62 -0
- package/dist/telegram/inbound.d.ts +40 -0
- package/dist/telegram/inbound.js +72 -0
- package/dist/telegram/index.d.ts +8 -0
- package/dist/telegram/multipart.d.ts +5 -0
- package/dist/telegram/multipart.js +47 -0
- package/dist/telegram/types.d.ts +271 -0
- package/dist/telegram/update.d.ts +833 -0
- package/dist/telegram/update.js +129 -0
- package/dist/testing/fake-html.d.ts +9 -0
- package/dist/testing/fake-html.js +83 -0
- package/dist/testing/fake-telegram.d.ts +206 -0
- package/dist/testing/fake-telegram.js +856 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/reference-sql.d.ts +4 -0
- package/dist/testing/reference-sql.js +8 -0
- package/dist/testing/test-plugin.d.ts +126 -0
- package/dist/testing/test-plugin.js +182 -0
- package/dist/testing/updates.d.ts +100 -0
- package/dist/testing/updates.js +212 -0
- package/package.json +113 -3
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Stable problem codes (docs/05 §5). Hosts with a closed list map them through `ports.errors`. */
|
|
3
|
+
export declare const TELEGRAM_PROBLEM_CODES: readonly ["feature_disabled", "bot_token_invalid", "bot_token_mismatch", "bot_unreachable", "webhook_url_missing", "webhook_failed", "chat_not_found", "chat_blocked", "link_expired", "link_used", "destination_not_allowed", "template_invalid", "template_variable_unknown", "provider_unknown", "provider_forbidden", "schedule_rule_invalid", "timezone_invalid", "recipient_empty", "send_text_rejected", "file_too_large", "renderer_unavailable", "delivery_not_retryable", "schema_outdated", "unauthenticated", "forbidden", "not_found", "validation_failed", "rate_limited", "internal_error"];
|
|
4
|
+
/** Zod enum of {@link TELEGRAM_PROBLEM_CODES}. */
|
|
5
|
+
export declare const TelegramProblemCode: z.ZodEnum<{
|
|
6
|
+
timezone_invalid: "timezone_invalid";
|
|
7
|
+
recipient_empty: "recipient_empty";
|
|
8
|
+
schedule_rule_invalid: "schedule_rule_invalid";
|
|
9
|
+
feature_disabled: "feature_disabled";
|
|
10
|
+
bot_token_invalid: "bot_token_invalid";
|
|
11
|
+
bot_token_mismatch: "bot_token_mismatch";
|
|
12
|
+
bot_unreachable: "bot_unreachable";
|
|
13
|
+
webhook_url_missing: "webhook_url_missing";
|
|
14
|
+
webhook_failed: "webhook_failed";
|
|
15
|
+
chat_not_found: "chat_not_found";
|
|
16
|
+
chat_blocked: "chat_blocked";
|
|
17
|
+
link_expired: "link_expired";
|
|
18
|
+
link_used: "link_used";
|
|
19
|
+
destination_not_allowed: "destination_not_allowed";
|
|
20
|
+
template_invalid: "template_invalid";
|
|
21
|
+
template_variable_unknown: "template_variable_unknown";
|
|
22
|
+
provider_unknown: "provider_unknown";
|
|
23
|
+
provider_forbidden: "provider_forbidden";
|
|
24
|
+
send_text_rejected: "send_text_rejected";
|
|
25
|
+
file_too_large: "file_too_large";
|
|
26
|
+
renderer_unavailable: "renderer_unavailable";
|
|
27
|
+
delivery_not_retryable: "delivery_not_retryable";
|
|
28
|
+
schema_outdated: "schema_outdated";
|
|
29
|
+
unauthenticated: "unauthenticated";
|
|
30
|
+
forbidden: "forbidden";
|
|
31
|
+
not_found: "not_found";
|
|
32
|
+
validation_failed: "validation_failed";
|
|
33
|
+
rate_limited: "rate_limited";
|
|
34
|
+
internal_error: "internal_error";
|
|
35
|
+
}>;
|
|
36
|
+
export type TelegramProblemCode = z.infer<typeof TelegramProblemCode>;
|
|
37
|
+
/** Default HTTP status per code. */
|
|
38
|
+
export declare const PROBLEM_STATUS: Readonly<Record<TelegramProblemCode, number>>;
|
|
39
|
+
/** One template syntax error (1-based line and column). */
|
|
40
|
+
export declare const TemplateError: z.ZodObject<{
|
|
41
|
+
line: z.ZodNumber;
|
|
42
|
+
column: z.ZodNumber;
|
|
43
|
+
message: z.ZodString;
|
|
44
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
export type TemplateError = z.infer<typeof TemplateError>;
|
|
47
|
+
/** One field-level validation issue. */
|
|
48
|
+
export declare const FieldIssue: z.ZodObject<{
|
|
49
|
+
path: z.ZodString;
|
|
50
|
+
message: z.ZodString;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type FieldIssue = z.infer<typeof FieldIssue>;
|
|
53
|
+
/** RFC 9457 problem+json body with the plugin's stable `code`. */
|
|
54
|
+
export declare const TelegramProblem: z.ZodObject<{
|
|
55
|
+
type: z.ZodDefault<z.ZodString>;
|
|
56
|
+
title: z.ZodString;
|
|
57
|
+
status: z.ZodNumber;
|
|
58
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
59
|
+
instance: z.ZodOptional<z.ZodString>;
|
|
60
|
+
code: z.ZodEnum<{
|
|
61
|
+
timezone_invalid: "timezone_invalid";
|
|
62
|
+
recipient_empty: "recipient_empty";
|
|
63
|
+
schedule_rule_invalid: "schedule_rule_invalid";
|
|
64
|
+
feature_disabled: "feature_disabled";
|
|
65
|
+
bot_token_invalid: "bot_token_invalid";
|
|
66
|
+
bot_token_mismatch: "bot_token_mismatch";
|
|
67
|
+
bot_unreachable: "bot_unreachable";
|
|
68
|
+
webhook_url_missing: "webhook_url_missing";
|
|
69
|
+
webhook_failed: "webhook_failed";
|
|
70
|
+
chat_not_found: "chat_not_found";
|
|
71
|
+
chat_blocked: "chat_blocked";
|
|
72
|
+
link_expired: "link_expired";
|
|
73
|
+
link_used: "link_used";
|
|
74
|
+
destination_not_allowed: "destination_not_allowed";
|
|
75
|
+
template_invalid: "template_invalid";
|
|
76
|
+
template_variable_unknown: "template_variable_unknown";
|
|
77
|
+
provider_unknown: "provider_unknown";
|
|
78
|
+
provider_forbidden: "provider_forbidden";
|
|
79
|
+
send_text_rejected: "send_text_rejected";
|
|
80
|
+
file_too_large: "file_too_large";
|
|
81
|
+
renderer_unavailable: "renderer_unavailable";
|
|
82
|
+
delivery_not_retryable: "delivery_not_retryable";
|
|
83
|
+
schema_outdated: "schema_outdated";
|
|
84
|
+
unauthenticated: "unauthenticated";
|
|
85
|
+
forbidden: "forbidden";
|
|
86
|
+
not_found: "not_found";
|
|
87
|
+
validation_failed: "validation_failed";
|
|
88
|
+
rate_limited: "rate_limited";
|
|
89
|
+
internal_error: "internal_error";
|
|
90
|
+
}>;
|
|
91
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
92
|
+
line: z.ZodNumber;
|
|
93
|
+
column: z.ZodNumber;
|
|
94
|
+
message: z.ZodString;
|
|
95
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
96
|
+
}, z.core.$strip>>>;
|
|
97
|
+
issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
98
|
+
path: z.ZodString;
|
|
99
|
+
message: z.ZodString;
|
|
100
|
+
}, z.core.$strip>>>;
|
|
101
|
+
retryAfter: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
reasons: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
export type TelegramProblem = z.infer<typeof TelegramProblem>;
|
|
105
|
+
/** `Content-Type` of every plugin error response. */
|
|
106
|
+
export declare const PROBLEM_CONTENT_TYPE = "application/problem+json";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// src/contracts/problems.ts
|
|
3
|
+
/** Stable problem codes (docs/05 §5). Hosts with a closed list map them through `ports.errors`. */
|
|
4
|
+
const TELEGRAM_PROBLEM_CODES = [
|
|
5
|
+
"feature_disabled",
|
|
6
|
+
"bot_token_invalid",
|
|
7
|
+
"bot_token_mismatch",
|
|
8
|
+
"bot_unreachable",
|
|
9
|
+
"webhook_url_missing",
|
|
10
|
+
"webhook_failed",
|
|
11
|
+
"chat_not_found",
|
|
12
|
+
"chat_blocked",
|
|
13
|
+
"link_expired",
|
|
14
|
+
"link_used",
|
|
15
|
+
"destination_not_allowed",
|
|
16
|
+
"template_invalid",
|
|
17
|
+
"template_variable_unknown",
|
|
18
|
+
"provider_unknown",
|
|
19
|
+
"provider_forbidden",
|
|
20
|
+
"schedule_rule_invalid",
|
|
21
|
+
"timezone_invalid",
|
|
22
|
+
"recipient_empty",
|
|
23
|
+
"send_text_rejected",
|
|
24
|
+
"file_too_large",
|
|
25
|
+
"renderer_unavailable",
|
|
26
|
+
"delivery_not_retryable",
|
|
27
|
+
"schema_outdated",
|
|
28
|
+
"unauthenticated",
|
|
29
|
+
"forbidden",
|
|
30
|
+
"not_found",
|
|
31
|
+
"validation_failed",
|
|
32
|
+
"rate_limited",
|
|
33
|
+
"internal_error"
|
|
34
|
+
];
|
|
35
|
+
/** Zod enum of {@link TELEGRAM_PROBLEM_CODES}. */
|
|
36
|
+
const TelegramProblemCode = z.enum(TELEGRAM_PROBLEM_CODES);
|
|
37
|
+
/** Default HTTP status per code. */
|
|
38
|
+
const PROBLEM_STATUS = {
|
|
39
|
+
feature_disabled: 404,
|
|
40
|
+
bot_token_invalid: 422,
|
|
41
|
+
bot_token_mismatch: 422,
|
|
42
|
+
bot_unreachable: 502,
|
|
43
|
+
webhook_url_missing: 422,
|
|
44
|
+
webhook_failed: 502,
|
|
45
|
+
chat_not_found: 404,
|
|
46
|
+
chat_blocked: 409,
|
|
47
|
+
link_expired: 410,
|
|
48
|
+
link_used: 409,
|
|
49
|
+
destination_not_allowed: 403,
|
|
50
|
+
template_invalid: 422,
|
|
51
|
+
template_variable_unknown: 422,
|
|
52
|
+
provider_unknown: 422,
|
|
53
|
+
provider_forbidden: 403,
|
|
54
|
+
schedule_rule_invalid: 422,
|
|
55
|
+
timezone_invalid: 422,
|
|
56
|
+
recipient_empty: 422,
|
|
57
|
+
send_text_rejected: 422,
|
|
58
|
+
file_too_large: 413,
|
|
59
|
+
renderer_unavailable: 501,
|
|
60
|
+
delivery_not_retryable: 409,
|
|
61
|
+
schema_outdated: 503,
|
|
62
|
+
unauthenticated: 401,
|
|
63
|
+
forbidden: 403,
|
|
64
|
+
not_found: 404,
|
|
65
|
+
validation_failed: 400,
|
|
66
|
+
rate_limited: 429,
|
|
67
|
+
internal_error: 500
|
|
68
|
+
};
|
|
69
|
+
/** One template syntax error (1-based line and column). */
|
|
70
|
+
const TemplateError = z.object({
|
|
71
|
+
line: z.number().int().min(1),
|
|
72
|
+
column: z.number().int().min(1),
|
|
73
|
+
message: z.string(),
|
|
74
|
+
/** Body locale the error is in, for multi-locale templates. */
|
|
75
|
+
locale: z.string().optional()
|
|
76
|
+
});
|
|
77
|
+
/** One field-level validation issue. */
|
|
78
|
+
const FieldIssue = z.object({
|
|
79
|
+
path: z.string(),
|
|
80
|
+
message: z.string()
|
|
81
|
+
});
|
|
82
|
+
/** RFC 9457 problem+json body with the plugin's stable `code`. */
|
|
83
|
+
const TelegramProblem = z.object({
|
|
84
|
+
type: z.string().default("about:blank"),
|
|
85
|
+
title: z.string(),
|
|
86
|
+
status: z.number().int().min(400).max(599),
|
|
87
|
+
detail: z.string().optional(),
|
|
88
|
+
instance: z.string().optional(),
|
|
89
|
+
code: TelegramProblemCode,
|
|
90
|
+
/** `template_invalid`: syntax errors. */
|
|
91
|
+
errors: z.array(TemplateError).optional(),
|
|
92
|
+
/** `validation_failed`: field issues. */
|
|
93
|
+
issues: z.array(FieldIssue).optional(),
|
|
94
|
+
/** `rate_limited`: seconds to wait. */
|
|
95
|
+
retryAfter: z.number().int().nonnegative().optional(),
|
|
96
|
+
/** `send_text_rejected`: the failed content checks. */
|
|
97
|
+
reasons: z.array(z.string()).optional()
|
|
98
|
+
});
|
|
99
|
+
/** `Content-Type` of every plugin error response. */
|
|
100
|
+
const PROBLEM_CONTENT_TYPE = "application/problem+json";
|
|
101
|
+
export { FieldIssue, PROBLEM_CONTENT_TYPE, PROBLEM_STATUS, TELEGRAM_PROBLEM_CODES, TelegramProblem, TelegramProblemCode, TemplateError };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Who receives a message. Built-in kinds plus host audiences from `defineAudience`
|
|
4
|
+
* (`{ audience: "projectTeam", ref: "P-12" }`).
|
|
5
|
+
*/
|
|
6
|
+
export declare const RecipientSpec: z.ZodUnion<readonly [z.ZodObject<{
|
|
7
|
+
destination: z.ZodString;
|
|
8
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
9
|
+
chat: z.ZodString;
|
|
10
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
11
|
+
user: z.ZodString;
|
|
12
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
13
|
+
role: z.ZodString;
|
|
14
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
15
|
+
allLinked: z.ZodLiteral<true>;
|
|
16
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
audience: z.ZodString;
|
|
18
|
+
ref: z.ZodString;
|
|
19
|
+
}, z.core.$strict>]>;
|
|
20
|
+
export type RecipientSpec = z.infer<typeof RecipientSpec>;
|
|
21
|
+
/** 1–100 recipient specs; an empty list fails with `recipient_empty`. */
|
|
22
|
+
export declare const Recipients: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
23
|
+
destination: z.ZodString;
|
|
24
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
25
|
+
chat: z.ZodString;
|
|
26
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
27
|
+
user: z.ZodString;
|
|
28
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
29
|
+
role: z.ZodString;
|
|
30
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
+
allLinked: z.ZodLiteral<true>;
|
|
32
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
33
|
+
audience: z.ZodString;
|
|
34
|
+
ref: z.ZodString;
|
|
35
|
+
}, z.core.$strict>]>>;
|
|
36
|
+
export type Recipients = z.infer<typeof Recipients>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Id } from "./common.js";
|
|
2
|
+
import { Slug } from "./destinations.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
// src/contracts/recipients.ts
|
|
5
|
+
/**
|
|
6
|
+
* Who receives a message. Built-in kinds plus host audiences from `defineAudience`
|
|
7
|
+
* (`{ audience: "projectTeam", ref: "P-12" }`).
|
|
8
|
+
*/
|
|
9
|
+
const RecipientSpec = z.union([
|
|
10
|
+
z.strictObject({ destination: Slug }),
|
|
11
|
+
z.strictObject({ chat: Id }),
|
|
12
|
+
z.strictObject({ user: z.string().min(1) }),
|
|
13
|
+
z.strictObject({ role: z.string().min(1) }),
|
|
14
|
+
z.strictObject({ allLinked: z.literal(true) }),
|
|
15
|
+
z.strictObject({
|
|
16
|
+
audience: z.string().regex(/^[a-zA-Z][a-zA-Z0-9_]{0,31}$/),
|
|
17
|
+
ref: z.string().min(1).max(128)
|
|
18
|
+
})
|
|
19
|
+
]);
|
|
20
|
+
/** 1–100 recipient specs; an empty list fails with `recipient_empty`. */
|
|
21
|
+
const Recipients = z.array(RecipientSpec).min(1, "recipient_empty").max(100);
|
|
22
|
+
export { RecipientSpec, Recipients };
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Weekday keys used by weekly rules. */
|
|
3
|
+
export declare const WEEKDAYS: readonly ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
4
|
+
/** Zod enum of {@link WEEKDAYS}. */
|
|
5
|
+
export declare const Weekday: z.ZodEnum<{
|
|
6
|
+
mon: "mon";
|
|
7
|
+
tue: "tue";
|
|
8
|
+
wed: "wed";
|
|
9
|
+
thu: "thu";
|
|
10
|
+
fri: "fri";
|
|
11
|
+
sat: "sat";
|
|
12
|
+
sun: "sun";
|
|
13
|
+
}>;
|
|
14
|
+
export type Weekday = z.infer<typeof Weekday>;
|
|
15
|
+
/** 5-field cron (minute hour day-of-month month day-of-week). Seconds and year fields are rejected. */
|
|
16
|
+
export declare const CronExpr: z.ZodString;
|
|
17
|
+
/** Local wall-clock date-time `YYYY-MM-DDTHH:MM`, read in the schedule's time zone. */
|
|
18
|
+
export declare const LocalDateTime: z.ZodString;
|
|
19
|
+
/** When a schedule fires. All times are local to the schedule's `timezone`. */
|
|
20
|
+
export declare const ScheduleRule: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
21
|
+
kind: z.ZodLiteral<"daily">;
|
|
22
|
+
at: z.ZodString;
|
|
23
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
24
|
+
kind: z.ZodLiteral<"weekly">;
|
|
25
|
+
days: z.ZodArray<z.ZodEnum<{
|
|
26
|
+
mon: "mon";
|
|
27
|
+
tue: "tue";
|
|
28
|
+
wed: "wed";
|
|
29
|
+
thu: "thu";
|
|
30
|
+
fri: "fri";
|
|
31
|
+
sat: "sat";
|
|
32
|
+
sun: "sun";
|
|
33
|
+
}>>;
|
|
34
|
+
at: z.ZodString;
|
|
35
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
36
|
+
kind: z.ZodLiteral<"monthly">;
|
|
37
|
+
day: z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"last">]>;
|
|
38
|
+
at: z.ZodString;
|
|
39
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
40
|
+
kind: z.ZodLiteral<"cron">;
|
|
41
|
+
expr: z.ZodString;
|
|
42
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
43
|
+
kind: z.ZodLiteral<"once">;
|
|
44
|
+
at: z.ZodString;
|
|
45
|
+
}, z.core.$strip>], "kind">;
|
|
46
|
+
export type ScheduleRule = z.infer<typeof ScheduleRule>;
|
|
47
|
+
/** The `kind` values of {@link ScheduleRule}. */
|
|
48
|
+
export declare const SCHEDULE_RULE_KINDS: readonly ["daily", "weekly", "monthly", "cron", "once"];
|
|
49
|
+
/** Zod enum of {@link SCHEDULE_RULE_KINDS}. */
|
|
50
|
+
export declare const ScheduleRuleKind: z.ZodEnum<{
|
|
51
|
+
daily: "daily";
|
|
52
|
+
weekly: "weekly";
|
|
53
|
+
monthly: "monthly";
|
|
54
|
+
cron: "cron";
|
|
55
|
+
once: "once";
|
|
56
|
+
}>;
|
|
57
|
+
export type ScheduleRuleKind = z.infer<typeof ScheduleRuleKind>;
|
|
58
|
+
/** What to do with a slot found more than `missedGraceMin` late: `skip` it, or `run_once` (latest slot only). */
|
|
59
|
+
export declare const MISSED_POLICIES: readonly ["skip", "run_once"];
|
|
60
|
+
/** Zod enum of {@link MISSED_POLICIES}. */
|
|
61
|
+
export declare const MissedPolicy: z.ZodEnum<{
|
|
62
|
+
run_once: "run_once";
|
|
63
|
+
skip: "skip";
|
|
64
|
+
}>;
|
|
65
|
+
export type MissedPolicy = z.infer<typeof MissedPolicy>;
|
|
66
|
+
/** Run outcome; `partial` = some deliveries queued before an error, `skipped` = missed-run policy skipped it. */
|
|
67
|
+
export declare const SCHEDULE_RUN_STATUSES: readonly ["running", "done", "partial", "failed", "skipped"];
|
|
68
|
+
/** Zod enum of {@link SCHEDULE_RUN_STATUSES}. */
|
|
69
|
+
export declare const ScheduleRunStatus: z.ZodEnum<{
|
|
70
|
+
running: "running";
|
|
71
|
+
failed: "failed";
|
|
72
|
+
done: "done";
|
|
73
|
+
partial: "partial";
|
|
74
|
+
skipped: "skipped";
|
|
75
|
+
}>;
|
|
76
|
+
export type ScheduleRunStatus = z.infer<typeof ScheduleRunStatus>;
|
|
77
|
+
/** What started a run: the rule (`schedule`), or `run-now` (`manual`). */
|
|
78
|
+
export declare const SCHEDULE_RUN_TRIGGERS: readonly ["schedule", "manual"];
|
|
79
|
+
/** Zod enum of {@link SCHEDULE_RUN_TRIGGERS}. */
|
|
80
|
+
export declare const ScheduleRunTrigger: z.ZodEnum<{
|
|
81
|
+
schedule: "schedule";
|
|
82
|
+
manual: "manual";
|
|
83
|
+
}>;
|
|
84
|
+
export type ScheduleRunTrigger = z.infer<typeof ScheduleRunTrigger>;
|
|
85
|
+
/** A recurring templated send (`/admin/schedules`, permission `telegram.schedules.manage`). */
|
|
86
|
+
export declare const ScheduleDto: z.ZodObject<{
|
|
87
|
+
id: z.ZodString;
|
|
88
|
+
name: z.ZodString;
|
|
89
|
+
rule: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
90
|
+
kind: z.ZodLiteral<"daily">;
|
|
91
|
+
at: z.ZodString;
|
|
92
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
93
|
+
kind: z.ZodLiteral<"weekly">;
|
|
94
|
+
days: z.ZodArray<z.ZodEnum<{
|
|
95
|
+
mon: "mon";
|
|
96
|
+
tue: "tue";
|
|
97
|
+
wed: "wed";
|
|
98
|
+
thu: "thu";
|
|
99
|
+
fri: "fri";
|
|
100
|
+
sat: "sat";
|
|
101
|
+
sun: "sun";
|
|
102
|
+
}>>;
|
|
103
|
+
at: z.ZodString;
|
|
104
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
105
|
+
kind: z.ZodLiteral<"monthly">;
|
|
106
|
+
day: z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"last">]>;
|
|
107
|
+
at: z.ZodString;
|
|
108
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
109
|
+
kind: z.ZodLiteral<"cron">;
|
|
110
|
+
expr: z.ZodString;
|
|
111
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
112
|
+
kind: z.ZodLiteral<"once">;
|
|
113
|
+
at: z.ZodString;
|
|
114
|
+
}, z.core.$strip>], "kind">;
|
|
115
|
+
timezone: z.ZodString;
|
|
116
|
+
templateId: z.ZodString;
|
|
117
|
+
params: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
118
|
+
recipients: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
119
|
+
destination: z.ZodString;
|
|
120
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
121
|
+
chat: z.ZodString;
|
|
122
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
123
|
+
user: z.ZodString;
|
|
124
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
125
|
+
role: z.ZodString;
|
|
126
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
127
|
+
allLinked: z.ZodLiteral<true>;
|
|
128
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
129
|
+
audience: z.ZodString;
|
|
130
|
+
ref: z.ZodString;
|
|
131
|
+
}, z.core.$strict>]>>;
|
|
132
|
+
personalize: z.ZodBoolean;
|
|
133
|
+
missedPolicy: z.ZodEnum<{
|
|
134
|
+
run_once: "run_once";
|
|
135
|
+
skip: "skip";
|
|
136
|
+
}>;
|
|
137
|
+
missedGraceMin: z.ZodNumber;
|
|
138
|
+
enabled: z.ZodBoolean;
|
|
139
|
+
pausedUntil: z.ZodNullable<z.ZodNumber>;
|
|
140
|
+
nextRunAt: z.ZodNullable<z.ZodNumber>;
|
|
141
|
+
lastRunAt: z.ZodNullable<z.ZodNumber>;
|
|
142
|
+
lastStatus: z.ZodNullable<z.ZodEnum<{
|
|
143
|
+
running: "running";
|
|
144
|
+
failed: "failed";
|
|
145
|
+
done: "done";
|
|
146
|
+
partial: "partial";
|
|
147
|
+
skipped: "skipped";
|
|
148
|
+
}>>;
|
|
149
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
150
|
+
createdAt: z.ZodNumber;
|
|
151
|
+
updatedAt: z.ZodNumber;
|
|
152
|
+
}, z.core.$strip>;
|
|
153
|
+
export type ScheduleDto = z.infer<typeof ScheduleDto>;
|
|
154
|
+
/** `POST`/`PUT /admin/schedules` body (defaults: personalize, `run_once`, 30 min grace, enabled). */
|
|
155
|
+
export declare const ScheduleSave: z.ZodObject<{
|
|
156
|
+
name: z.ZodString;
|
|
157
|
+
rule: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
158
|
+
kind: z.ZodLiteral<"daily">;
|
|
159
|
+
at: z.ZodString;
|
|
160
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
161
|
+
kind: z.ZodLiteral<"weekly">;
|
|
162
|
+
days: z.ZodArray<z.ZodEnum<{
|
|
163
|
+
mon: "mon";
|
|
164
|
+
tue: "tue";
|
|
165
|
+
wed: "wed";
|
|
166
|
+
thu: "thu";
|
|
167
|
+
fri: "fri";
|
|
168
|
+
sat: "sat";
|
|
169
|
+
sun: "sun";
|
|
170
|
+
}>>;
|
|
171
|
+
at: z.ZodString;
|
|
172
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
173
|
+
kind: z.ZodLiteral<"monthly">;
|
|
174
|
+
day: z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"last">]>;
|
|
175
|
+
at: z.ZodString;
|
|
176
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
177
|
+
kind: z.ZodLiteral<"cron">;
|
|
178
|
+
expr: z.ZodString;
|
|
179
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
180
|
+
kind: z.ZodLiteral<"once">;
|
|
181
|
+
at: z.ZodString;
|
|
182
|
+
}, z.core.$strip>], "kind">;
|
|
183
|
+
timezone: z.ZodOptional<z.ZodString>;
|
|
184
|
+
templateId: z.ZodString;
|
|
185
|
+
params: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
186
|
+
recipients: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
187
|
+
destination: z.ZodString;
|
|
188
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
189
|
+
chat: z.ZodString;
|
|
190
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
191
|
+
user: z.ZodString;
|
|
192
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
193
|
+
role: z.ZodString;
|
|
194
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
195
|
+
allLinked: z.ZodLiteral<true>;
|
|
196
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
197
|
+
audience: z.ZodString;
|
|
198
|
+
ref: z.ZodString;
|
|
199
|
+
}, z.core.$strict>]>>;
|
|
200
|
+
personalize: z.ZodDefault<z.ZodBoolean>;
|
|
201
|
+
missedPolicy: z.ZodDefault<z.ZodEnum<{
|
|
202
|
+
run_once: "run_once";
|
|
203
|
+
skip: "skip";
|
|
204
|
+
}>>;
|
|
205
|
+
missedGraceMin: z.ZodDefault<z.ZodNumber>;
|
|
206
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
207
|
+
}, z.core.$strip>;
|
|
208
|
+
export type ScheduleSave = z.infer<typeof ScheduleSave>;
|
|
209
|
+
/** One schedule run (`GET /admin/schedules/:id/runs`). */
|
|
210
|
+
export declare const ScheduleRunDto: z.ZodObject<{
|
|
211
|
+
id: z.ZodString;
|
|
212
|
+
scheduleId: z.ZodString;
|
|
213
|
+
slotAt: z.ZodNumber;
|
|
214
|
+
trigger: z.ZodEnum<{
|
|
215
|
+
schedule: "schedule";
|
|
216
|
+
manual: "manual";
|
|
217
|
+
}>;
|
|
218
|
+
startedAt: z.ZodNumber;
|
|
219
|
+
finishedAt: z.ZodNullable<z.ZodNumber>;
|
|
220
|
+
status: z.ZodEnum<{
|
|
221
|
+
running: "running";
|
|
222
|
+
failed: "failed";
|
|
223
|
+
done: "done";
|
|
224
|
+
partial: "partial";
|
|
225
|
+
skipped: "skipped";
|
|
226
|
+
}>;
|
|
227
|
+
deliveries: z.ZodNumber;
|
|
228
|
+
error: z.ZodNullable<z.ZodString>;
|
|
229
|
+
templateVersion: z.ZodNullable<z.ZodNumber>;
|
|
230
|
+
}, z.core.$strip>;
|
|
231
|
+
export type ScheduleRunDto = z.infer<typeof ScheduleRunDto>;
|
|
232
|
+
/** `POST /admin/schedules/next-runs`. */
|
|
233
|
+
export declare const NextRunsRequest: z.ZodObject<{
|
|
234
|
+
rule: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
235
|
+
kind: z.ZodLiteral<"daily">;
|
|
236
|
+
at: z.ZodString;
|
|
237
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
238
|
+
kind: z.ZodLiteral<"weekly">;
|
|
239
|
+
days: z.ZodArray<z.ZodEnum<{
|
|
240
|
+
mon: "mon";
|
|
241
|
+
tue: "tue";
|
|
242
|
+
wed: "wed";
|
|
243
|
+
thu: "thu";
|
|
244
|
+
fri: "fri";
|
|
245
|
+
sat: "sat";
|
|
246
|
+
sun: "sun";
|
|
247
|
+
}>>;
|
|
248
|
+
at: z.ZodString;
|
|
249
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
250
|
+
kind: z.ZodLiteral<"monthly">;
|
|
251
|
+
day: z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<"last">]>;
|
|
252
|
+
at: z.ZodString;
|
|
253
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
254
|
+
kind: z.ZodLiteral<"cron">;
|
|
255
|
+
expr: z.ZodString;
|
|
256
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
257
|
+
kind: z.ZodLiteral<"once">;
|
|
258
|
+
at: z.ZodString;
|
|
259
|
+
}, z.core.$strip>], "kind">;
|
|
260
|
+
tz: z.ZodString;
|
|
261
|
+
count: z.ZodDefault<z.ZodNumber>;
|
|
262
|
+
from: z.ZodOptional<z.ZodNumber>;
|
|
263
|
+
}, z.core.$strip>;
|
|
264
|
+
export type NextRunsRequest = z.infer<typeof NextRunsRequest>;
|
|
265
|
+
/** Upcoming fire times (epoch ms UTC), soonest first. */
|
|
266
|
+
export declare const NextRunsResponse: z.ZodObject<{
|
|
267
|
+
runs: z.ZodArray<z.ZodNumber>;
|
|
268
|
+
}, z.core.$strip>;
|
|
269
|
+
export type NextRunsResponse = z.infer<typeof NextRunsResponse>;
|
|
270
|
+
/** `pausedUntil` of a schedule paused until it is resumed (9999-12-31T23:59:59.999Z). */
|
|
271
|
+
export declare const PAUSED_INDEFINITELY = 253402300799999;
|
|
272
|
+
/** `POST /admin/schedules/:id/pause`. Without `until` the schedule stays paused until resumed. */
|
|
273
|
+
export declare const SchedulePause: z.ZodObject<{
|
|
274
|
+
until: z.ZodOptional<z.ZodNumber>;
|
|
275
|
+
}, z.core.$strip>;
|
|
276
|
+
export type SchedulePause = z.infer<typeof SchedulePause>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { ClockTime, EpochMs, Id, JsonObject, TimeZone } from "./common.js";
|
|
2
|
+
import { Recipients } from "./recipients.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
// src/contracts/schedules.ts
|
|
5
|
+
/** Weekday keys used by weekly rules. */
|
|
6
|
+
const WEEKDAYS = [
|
|
7
|
+
"mon",
|
|
8
|
+
"tue",
|
|
9
|
+
"wed",
|
|
10
|
+
"thu",
|
|
11
|
+
"fri",
|
|
12
|
+
"sat",
|
|
13
|
+
"sun"
|
|
14
|
+
];
|
|
15
|
+
/** Zod enum of {@link WEEKDAYS}. */
|
|
16
|
+
const Weekday = z.enum(WEEKDAYS);
|
|
17
|
+
/** 5-field cron (minute hour day-of-month month day-of-week). Seconds and year fields are rejected. */
|
|
18
|
+
const CronExpr = z.string().trim().max(120).refine((s) => s.split(/\s+/).length === 5, "schedule_rule_invalid");
|
|
19
|
+
/** Local wall-clock date-time `YYYY-MM-DDTHH:MM`, read in the schedule's time zone. */
|
|
20
|
+
const LocalDateTime = z.string().regex(/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3]):[0-5]\d$/);
|
|
21
|
+
/** When a schedule fires. All times are local to the schedule's `timezone`. */
|
|
22
|
+
const ScheduleRule = z.discriminatedUnion("kind", [
|
|
23
|
+
z.object({
|
|
24
|
+
kind: z.literal("daily"),
|
|
25
|
+
at: ClockTime
|
|
26
|
+
}),
|
|
27
|
+
z.object({
|
|
28
|
+
kind: z.literal("weekly"),
|
|
29
|
+
days: z.array(Weekday).min(1).max(7).refine((d) => new Set(d).size === d.length, "duplicate day"),
|
|
30
|
+
at: ClockTime
|
|
31
|
+
}),
|
|
32
|
+
z.object({
|
|
33
|
+
kind: z.literal("monthly"),
|
|
34
|
+
day: z.union([z.number().int().min(1).max(31), z.literal("last")]),
|
|
35
|
+
at: ClockTime
|
|
36
|
+
}),
|
|
37
|
+
z.object({
|
|
38
|
+
kind: z.literal("cron"),
|
|
39
|
+
expr: CronExpr
|
|
40
|
+
}),
|
|
41
|
+
z.object({
|
|
42
|
+
kind: z.literal("once"),
|
|
43
|
+
at: LocalDateTime
|
|
44
|
+
})
|
|
45
|
+
]);
|
|
46
|
+
/** The `kind` values of {@link ScheduleRule}. */
|
|
47
|
+
const SCHEDULE_RULE_KINDS = [
|
|
48
|
+
"daily",
|
|
49
|
+
"weekly",
|
|
50
|
+
"monthly",
|
|
51
|
+
"cron",
|
|
52
|
+
"once"
|
|
53
|
+
];
|
|
54
|
+
/** Zod enum of {@link SCHEDULE_RULE_KINDS}. */
|
|
55
|
+
const ScheduleRuleKind = z.enum(SCHEDULE_RULE_KINDS);
|
|
56
|
+
/** What to do with a slot found more than `missedGraceMin` late: `skip` it, or `run_once` (latest slot only). */
|
|
57
|
+
const MISSED_POLICIES = ["skip", "run_once"];
|
|
58
|
+
/** Zod enum of {@link MISSED_POLICIES}. */
|
|
59
|
+
const MissedPolicy = z.enum(MISSED_POLICIES);
|
|
60
|
+
/** Run outcome; `partial` = some deliveries queued before an error, `skipped` = missed-run policy skipped it. */
|
|
61
|
+
const SCHEDULE_RUN_STATUSES = [
|
|
62
|
+
"running",
|
|
63
|
+
"done",
|
|
64
|
+
"partial",
|
|
65
|
+
"failed",
|
|
66
|
+
"skipped"
|
|
67
|
+
];
|
|
68
|
+
/** Zod enum of {@link SCHEDULE_RUN_STATUSES}. */
|
|
69
|
+
const ScheduleRunStatus = z.enum(SCHEDULE_RUN_STATUSES);
|
|
70
|
+
/** What started a run: the rule (`schedule`), or `run-now` (`manual`). */
|
|
71
|
+
const SCHEDULE_RUN_TRIGGERS = ["schedule", "manual"];
|
|
72
|
+
/** Zod enum of {@link SCHEDULE_RUN_TRIGGERS}. */
|
|
73
|
+
const ScheduleRunTrigger = z.enum(SCHEDULE_RUN_TRIGGERS);
|
|
74
|
+
/** A recurring templated send (`/admin/schedules`, permission `telegram.schedules.manage`). */
|
|
75
|
+
const ScheduleDto = z.object({
|
|
76
|
+
id: Id,
|
|
77
|
+
name: z.string(),
|
|
78
|
+
rule: ScheduleRule,
|
|
79
|
+
/** IANA zone the rule is read in. */
|
|
80
|
+
timezone: z.string(),
|
|
81
|
+
templateId: Id,
|
|
82
|
+
params: JsonObject.nullable(),
|
|
83
|
+
recipients: Recipients,
|
|
84
|
+
/** True = run the provider per recipient user (exact redaction); false = once per audience role. */
|
|
85
|
+
personalize: z.boolean(),
|
|
86
|
+
missedPolicy: MissedPolicy,
|
|
87
|
+
/** Minutes a slot may be late and still run normally. */
|
|
88
|
+
missedGraceMin: z.number().int(),
|
|
89
|
+
enabled: z.boolean(),
|
|
90
|
+
/** Paused until this time (epoch ms UTC; {@link PAUSED_INDEFINITELY} = until resumed), or null. */
|
|
91
|
+
pausedUntil: EpochMs.nullable(),
|
|
92
|
+
/** Next planned slot (epoch ms UTC), or null when finished or disabled. */
|
|
93
|
+
nextRunAt: EpochMs.nullable(),
|
|
94
|
+
lastRunAt: EpochMs.nullable(),
|
|
95
|
+
lastStatus: ScheduleRunStatus.nullable(),
|
|
96
|
+
createdBy: z.string().nullable(),
|
|
97
|
+
createdAt: EpochMs,
|
|
98
|
+
updatedAt: EpochMs
|
|
99
|
+
});
|
|
100
|
+
/** `POST`/`PUT /admin/schedules` body (defaults: personalize, `run_once`, 30 min grace, enabled). */
|
|
101
|
+
const ScheduleSave = z.object({
|
|
102
|
+
name: z.string().trim().min(1).max(120),
|
|
103
|
+
rule: ScheduleRule,
|
|
104
|
+
/** Defaults to the host's `settings.timezone`. */
|
|
105
|
+
timezone: TimeZone.optional(),
|
|
106
|
+
templateId: Id,
|
|
107
|
+
params: JsonObject.nullable().default(null),
|
|
108
|
+
recipients: Recipients,
|
|
109
|
+
personalize: z.boolean().default(true),
|
|
110
|
+
missedPolicy: MissedPolicy.default("run_once"),
|
|
111
|
+
missedGraceMin: z.number().int().min(0).max(1440).default(30),
|
|
112
|
+
enabled: z.boolean().default(true)
|
|
113
|
+
});
|
|
114
|
+
/** One schedule run (`GET /admin/schedules/:id/runs`). */
|
|
115
|
+
const ScheduleRunDto = z.object({
|
|
116
|
+
id: Id,
|
|
117
|
+
scheduleId: Id,
|
|
118
|
+
/** Planned slot time this run is for (epoch ms UTC). */
|
|
119
|
+
slotAt: EpochMs,
|
|
120
|
+
trigger: ScheduleRunTrigger,
|
|
121
|
+
startedAt: EpochMs,
|
|
122
|
+
finishedAt: EpochMs.nullable(),
|
|
123
|
+
status: ScheduleRunStatus,
|
|
124
|
+
/** Delivery rows queued. */
|
|
125
|
+
deliveries: z.number().int().nonnegative(),
|
|
126
|
+
error: z.string().nullable(),
|
|
127
|
+
/** Template version rendered, or null if it failed before rendering. */
|
|
128
|
+
templateVersion: z.number().int().nullable()
|
|
129
|
+
});
|
|
130
|
+
/** `POST /admin/schedules/next-runs`. */
|
|
131
|
+
const NextRunsRequest = z.object({
|
|
132
|
+
rule: ScheduleRule,
|
|
133
|
+
tz: TimeZone,
|
|
134
|
+
count: z.number().int().min(1).max(20).default(5),
|
|
135
|
+
from: EpochMs.optional()
|
|
136
|
+
});
|
|
137
|
+
/** Upcoming fire times (epoch ms UTC), soonest first. */
|
|
138
|
+
const NextRunsResponse = z.object({ runs: z.array(EpochMs) });
|
|
139
|
+
/** `pausedUntil` of a schedule paused until it is resumed (9999-12-31T23:59:59.999Z). */
|
|
140
|
+
const PAUSED_INDEFINITELY = 0xe677d21fdbff;
|
|
141
|
+
/** `POST /admin/schedules/:id/pause`. Without `until` the schedule stays paused until resumed. */
|
|
142
|
+
const SchedulePause = z.object({ until: EpochMs.optional() });
|
|
143
|
+
export { CronExpr, LocalDateTime, MISSED_POLICIES, MissedPolicy, NextRunsRequest, NextRunsResponse, PAUSED_INDEFINITELY, SCHEDULE_RULE_KINDS, SCHEDULE_RUN_STATUSES, SCHEDULE_RUN_TRIGGERS, ScheduleDto, SchedulePause, ScheduleRule, ScheduleRuleKind, ScheduleRunDto, ScheduleRunStatus, ScheduleRunTrigger, ScheduleSave, WEEKDAYS, Weekday };
|