@automate.ax/catalog 0.63.0 → 0.65.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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/triggers/core.d.ts +136 -9
- package/dist/triggers/core.js +181 -9
- package/dist/triggers/index.d.ts +18 -1
- package/dist/triggers/index.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +5 -0
- package/src/triggers/core.ts +280 -19
- package/src/triggers/index.ts +5 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { airtableService, anthropicService, apolloService, asanaService, brevoService, cerebrasService, cloudflareService, cohereService, deepinfraService, deepseekService, firecrawlService, fireworksService, getIntegrationService, githubService, googleGenaiService, googleService, groqService, huggingfaceService, integrationCatalog, linearService, microsoftService, millionverifierService, mistralService, openaiService, openrouterService, perplexityService, postgresService, resendService, scrapflyService, slackService, tidycalService, togetheraiService, trelloService, vercelAiGatewayService, vercelService, whatsappService, xaiService, type IntegrationServiceId, } from "./catalog.js";
|
|
2
2
|
export { defineIntegrationCatalog, defineIntegrationService, integrationScope, type IntegrationAccountConnectionOption, type IntegrationAccountRequirement, type IntegrationConnectionDefinition, type IntegrationFormField, type IntegrationScopeRequirement, type IntegrationServiceDefinition, type ScopeRequirementGroup, type TriggerDefinition, type TriggerPresentation, type TriggerPresentationContext, type TriggerPresentationDetail, type TriggerScopePresentation, type TriggerPresentationValue, } from "./types.js";
|
|
3
|
-
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, DASHBOARD_RUN_CONFIG_SCHEMA, getTriggerDefinition, getTriggerName, getTriggerPresentation, isTriggerVisible, triggerCatalog, triggerDefinitions, type DashboardRunConfig, type DashboardRunEndpointOptions, type DashboardRunField, type HttpTriggerEndpointOptions, type HttpTriggerScope, type TriggerType, } from "./triggers/index.js";
|
|
3
|
+
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, getMailhookAddress, getMailhookAddressKey, DASHBOARD_RUN_CONFIG_SCHEMA, getTriggerDefinition, getTriggerName, getTriggerPresentation, isTriggerVisible, PLATFORM_EMAIL_DOMAIN, triggerCatalog, triggerDefinitions, type DashboardRunConfig, type DashboardRunEndpointOptions, type DashboardRunField, type HttpTriggerEndpointOptions, type HttpTriggerScope, type MailhookAddressOptions, type MailhookScope, type TriggerType, } from "./triggers/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { airtableService, anthropicService, apolloService, asanaService, brevoService, cerebrasService, cloudflareService, cohereService, deepinfraService, deepseekService, firecrawlService, fireworksService, getIntegrationService, githubService, googleGenaiService, googleService, groqService, huggingfaceService, integrationCatalog, linearService, microsoftService, millionverifierService, mistralService, openaiService, openrouterService, perplexityService, postgresService, resendService, scrapflyService, slackService, tidycalService, togetheraiService, trelloService, vercelAiGatewayService, vercelService, whatsappService, xaiService, } from "./catalog.js";
|
|
2
2
|
export { defineIntegrationCatalog, defineIntegrationService, integrationScope, } from "./types.js";
|
|
3
|
-
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, DASHBOARD_RUN_CONFIG_SCHEMA, getTriggerDefinition, getTriggerName, getTriggerPresentation, isTriggerVisible, triggerCatalog, triggerDefinitions, } from "./triggers/index.js";
|
|
3
|
+
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, getMailhookAddress, getMailhookAddressKey, DASHBOARD_RUN_CONFIG_SCHEMA, getTriggerDefinition, getTriggerName, getTriggerPresentation, isTriggerVisible, PLATFORM_EMAIL_DOMAIN, triggerCatalog, triggerDefinitions, } from "./triggers/index.js";
|
package/dist/triggers/core.d.ts
CHANGED
|
@@ -1,44 +1,97 @@
|
|
|
1
1
|
import * as z from "zod/mini";
|
|
2
2
|
export declare const DASHBOARD_RUN_CONFIG_SCHEMA: z.ZodMiniObject<{
|
|
3
3
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
4
|
-
fields: z.
|
|
4
|
+
fields: z.ZodMiniPrefault<z.ZodMiniArray<z.ZodMiniDiscriminatedUnion<[z.ZodMiniObject<{
|
|
5
|
+
defaultValue: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
5
6
|
maxLength: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
6
7
|
minLength: z.ZodMiniOptional<z.ZodMiniNumberFormat>;
|
|
7
8
|
placeholder: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
9
|
+
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
8
10
|
type: z.ZodMiniEnum<{
|
|
9
11
|
email: "email";
|
|
10
12
|
text: "text";
|
|
11
13
|
url: "url";
|
|
14
|
+
phone: "phone";
|
|
12
15
|
textarea: "textarea";
|
|
13
16
|
}>;
|
|
14
17
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
15
18
|
label: z.ZodMiniString<string>;
|
|
16
|
-
|
|
19
|
+
name: z.ZodMiniString<string>;
|
|
17
20
|
}, z.core.$strip>, z.ZodMiniObject<{
|
|
21
|
+
defaultValue: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
18
22
|
max: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
19
23
|
min: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
20
24
|
placeholder: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
25
|
+
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
21
26
|
step: z.ZodMiniPrefault<z.ZodMiniNumber<number>>;
|
|
22
27
|
type: z.ZodMiniLiteral<"number">;
|
|
23
28
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
24
29
|
label: z.ZodMiniString<string>;
|
|
30
|
+
name: z.ZodMiniString<string>;
|
|
31
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
32
|
+
defaultValue: z.ZodMiniOptional<z.iso.ZodMiniISODate>;
|
|
33
|
+
max: z.ZodMiniOptional<z.iso.ZodMiniISODate>;
|
|
34
|
+
min: z.ZodMiniOptional<z.iso.ZodMiniISODate>;
|
|
25
35
|
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
36
|
+
step: z.ZodMiniPrefault<z.ZodMiniNumberFormat>;
|
|
37
|
+
type: z.ZodMiniLiteral<"date">;
|
|
38
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
39
|
+
label: z.ZodMiniString<string>;
|
|
40
|
+
name: z.ZodMiniString<string>;
|
|
26
41
|
}, z.core.$strip>, z.ZodMiniObject<{
|
|
42
|
+
defaultValue: z.ZodMiniOptional<z.iso.ZodMiniISODateTime>;
|
|
43
|
+
max: z.ZodMiniOptional<z.iso.ZodMiniISODateTime>;
|
|
44
|
+
min: z.ZodMiniOptional<z.iso.ZodMiniISODateTime>;
|
|
45
|
+
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
46
|
+
step: z.ZodMiniPrefault<z.ZodMiniNumber<number>>;
|
|
47
|
+
type: z.ZodMiniLiteral<"datetime">;
|
|
48
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
49
|
+
label: z.ZodMiniString<string>;
|
|
50
|
+
name: z.ZodMiniString<string>;
|
|
51
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
52
|
+
type: z.ZodMiniLiteral<"select">;
|
|
53
|
+
defaultValue: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
27
54
|
options: z.ZodMiniArray<z.ZodMiniObject<{
|
|
28
55
|
label: z.ZodMiniString<string>;
|
|
29
56
|
value: z.ZodMiniString<string>;
|
|
30
57
|
}, z.core.$strip>>;
|
|
31
58
|
placeholder: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
32
|
-
|
|
59
|
+
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
33
60
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
34
61
|
label: z.ZodMiniString<string>;
|
|
62
|
+
name: z.ZodMiniString<string>;
|
|
63
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
64
|
+
type: z.ZodMiniLiteral<"radio">;
|
|
65
|
+
defaultValue: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
66
|
+
options: z.ZodMiniArray<z.ZodMiniObject<{
|
|
67
|
+
label: z.ZodMiniString<string>;
|
|
68
|
+
value: z.ZodMiniString<string>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
placeholder: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
35
71
|
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
72
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
73
|
+
label: z.ZodMiniString<string>;
|
|
74
|
+
name: z.ZodMiniString<string>;
|
|
36
75
|
}, z.core.$strip>, z.ZodMiniObject<{
|
|
37
|
-
|
|
76
|
+
defaultValue: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
77
|
+
options: z.ZodMiniArray<z.ZodMiniObject<{
|
|
78
|
+
label: z.ZodMiniString<string>;
|
|
79
|
+
value: z.ZodMiniString<string>;
|
|
80
|
+
}, z.core.$strip>>;
|
|
81
|
+
placeholder: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
82
|
+
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
83
|
+
type: z.ZodMiniLiteral<"multi-select">;
|
|
38
84
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
39
85
|
label: z.ZodMiniString<string>;
|
|
86
|
+
name: z.ZodMiniString<string>;
|
|
87
|
+
}, z.core.$strip>, z.ZodMiniObject<{
|
|
88
|
+
defaultValue: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
40
89
|
required: z.ZodMiniPrefault<z.ZodMiniBoolean<boolean>>;
|
|
41
|
-
|
|
90
|
+
type: z.ZodMiniLiteral<"checkbox">;
|
|
91
|
+
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
92
|
+
label: z.ZodMiniString<string>;
|
|
93
|
+
name: z.ZodMiniString<string>;
|
|
94
|
+
}, z.core.$strip>], "type">>>;
|
|
42
95
|
submitLabel: z.ZodMiniPrefault<z.ZodMiniString<string>>;
|
|
43
96
|
title: z.ZodMiniString<string>;
|
|
44
97
|
}, z.core.$strip>;
|
|
@@ -70,6 +123,15 @@ export declare const coreTriggerDefinitions: {
|
|
|
70
123
|
readonly name: "HTTP request";
|
|
71
124
|
readonly type: "http.request";
|
|
72
125
|
};
|
|
126
|
+
readonly mailhookEmailReceived: {
|
|
127
|
+
readonly getPrimary: ({ automationId, config, hookSlot, projectId, scopePath }: import("..").TriggerPresentationContext) => {
|
|
128
|
+
copyable: true;
|
|
129
|
+
value: string;
|
|
130
|
+
};
|
|
131
|
+
readonly icon: "webhook";
|
|
132
|
+
readonly name: "Mailhook";
|
|
133
|
+
readonly type: "mailhook.email.received";
|
|
134
|
+
};
|
|
73
135
|
readonly dashboardRun: {
|
|
74
136
|
readonly getDetails: ({ config }: import("..").TriggerPresentationContext) => {
|
|
75
137
|
label: string;
|
|
@@ -85,15 +147,19 @@ interface DashboardRunFieldBase {
|
|
|
85
147
|
description?: string;
|
|
86
148
|
/** Visible field label. */
|
|
87
149
|
label: string;
|
|
150
|
+
/** Property name used in submitted trigger data. */
|
|
151
|
+
name: string;
|
|
88
152
|
/** Whether the form must contain a value. Defaults to true. */
|
|
89
153
|
required?: boolean;
|
|
90
154
|
}
|
|
91
155
|
export type DashboardRunField = (DashboardRunFieldBase & {
|
|
156
|
+
defaultValue?: string;
|
|
92
157
|
maxLength?: number;
|
|
93
158
|
minLength?: number;
|
|
94
159
|
placeholder?: string;
|
|
95
|
-
type: "email" | "text" | "textarea" | "url";
|
|
160
|
+
type: "email" | "phone" | "text" | "textarea" | "url";
|
|
96
161
|
}) | (DashboardRunFieldBase & {
|
|
162
|
+
defaultValue?: number;
|
|
97
163
|
max?: number;
|
|
98
164
|
min?: number;
|
|
99
165
|
placeholder?: string;
|
|
@@ -101,6 +167,23 @@ export type DashboardRunField = (DashboardRunFieldBase & {
|
|
|
101
167
|
step?: number;
|
|
102
168
|
type: "number";
|
|
103
169
|
}) | (DashboardRunFieldBase & {
|
|
170
|
+
/** Initial local date in `YYYY-MM-DD` format. */
|
|
171
|
+
defaultValue?: string;
|
|
172
|
+
max?: string;
|
|
173
|
+
min?: string;
|
|
174
|
+
/** Allowed increment in days. Defaults to 1. */
|
|
175
|
+
step?: number;
|
|
176
|
+
type: "date";
|
|
177
|
+
}) | (DashboardRunFieldBase & {
|
|
178
|
+
/** Initial local date and time in `YYYY-MM-DDTHH:mm` format. */
|
|
179
|
+
defaultValue?: string;
|
|
180
|
+
max?: string;
|
|
181
|
+
min?: string;
|
|
182
|
+
/** Allowed increment in seconds. Defaults to 60. */
|
|
183
|
+
step?: number;
|
|
184
|
+
type: "datetime";
|
|
185
|
+
}) | (DashboardRunFieldBase & {
|
|
186
|
+
defaultValue?: string;
|
|
104
187
|
options: readonly {
|
|
105
188
|
label: string;
|
|
106
189
|
value: string;
|
|
@@ -108,13 +191,32 @@ export type DashboardRunField = (DashboardRunFieldBase & {
|
|
|
108
191
|
placeholder?: string;
|
|
109
192
|
type: "select";
|
|
110
193
|
}) | (DashboardRunFieldBase & {
|
|
194
|
+
defaultValue?: string;
|
|
195
|
+
options: readonly {
|
|
196
|
+
label: string;
|
|
197
|
+
value: string;
|
|
198
|
+
}[];
|
|
199
|
+
type: "radio";
|
|
200
|
+
}) | (DashboardRunFieldBase & {
|
|
201
|
+
defaultValue?: readonly string[];
|
|
202
|
+
options: readonly {
|
|
203
|
+
label: string;
|
|
204
|
+
value: string;
|
|
205
|
+
}[];
|
|
206
|
+
placeholder?: string;
|
|
207
|
+
type: "multi-select";
|
|
208
|
+
}) | (DashboardRunFieldBase & {
|
|
209
|
+
/** Initial checked state. Defaults to false. */
|
|
210
|
+
defaultValue?: boolean;
|
|
211
|
+
/** Whether the checkbox must be checked. Defaults to false. */
|
|
212
|
+
required?: boolean;
|
|
111
213
|
type: "checkbox";
|
|
112
214
|
});
|
|
113
|
-
export interface DashboardRunConfig<TFields extends
|
|
215
|
+
export interface DashboardRunConfig<TFields extends readonly DashboardRunField[] = readonly DashboardRunField[]> {
|
|
114
216
|
/** Supporting text shown below the form title. */
|
|
115
217
|
description?: string;
|
|
116
|
-
/**
|
|
117
|
-
fields
|
|
218
|
+
/** Ordered fields. Omit to run immediately. */
|
|
219
|
+
fields?: TFields;
|
|
118
220
|
/** Submit button text. Defaults to "Run". */
|
|
119
221
|
submitLabel?: string;
|
|
120
222
|
/** Form heading. */
|
|
@@ -127,6 +229,8 @@ export interface DashboardRunEndpointOptions {
|
|
|
127
229
|
scopePath?: readonly number[];
|
|
128
230
|
}
|
|
129
231
|
export type HttpTriggerScope = "trigger" | "automation" | "project";
|
|
232
|
+
export type MailhookScope = HttpTriggerScope;
|
|
233
|
+
export declare const PLATFORM_EMAIL_DOMAIN = "automations.automate.ax";
|
|
130
234
|
export interface HttpTriggerEndpointOptions {
|
|
131
235
|
appOrigin: string;
|
|
132
236
|
automationId: string;
|
|
@@ -135,6 +239,14 @@ export interface HttpTriggerEndpointOptions {
|
|
|
135
239
|
scope: HttpTriggerScope;
|
|
136
240
|
scopePath?: readonly number[];
|
|
137
241
|
}
|
|
242
|
+
export interface MailhookAddressOptions {
|
|
243
|
+
automationId: string;
|
|
244
|
+
hookSlot: number;
|
|
245
|
+
plusPath?: string;
|
|
246
|
+
projectId: string;
|
|
247
|
+
scope: MailhookScope;
|
|
248
|
+
scopePath?: readonly number[];
|
|
249
|
+
}
|
|
138
250
|
/**
|
|
139
251
|
* Returns the public URL for one deployed HTTP trigger.
|
|
140
252
|
*
|
|
@@ -147,6 +259,21 @@ export declare function getHttpTriggerEndpoint(options: HttpTriggerEndpointOptio
|
|
|
147
259
|
* @param options - Trigger and owning resource identity.
|
|
148
260
|
*/
|
|
149
261
|
export declare function getHttpTriggerEndpointKey(options: Omit<HttpTriggerEndpointOptions, "appOrigin">): string;
|
|
262
|
+
/**
|
|
263
|
+
* Returns the unique inbound address for one deployed mailhook.
|
|
264
|
+
*
|
|
265
|
+
* Add `+suffix` before the `@` to carry a routing value into the event.
|
|
266
|
+
*
|
|
267
|
+
* @param options - Mailhook identity and sharing scope.
|
|
268
|
+
* @throws When the generated local part exceeds the email size limit.
|
|
269
|
+
*/
|
|
270
|
+
export declare function getMailhookAddress(options: MailhookAddressOptions): string;
|
|
271
|
+
/**
|
|
272
|
+
* Returns the local-part router key for one configured mailhook scope.
|
|
273
|
+
*
|
|
274
|
+
* @param options - Mailhook identity and sharing scope.
|
|
275
|
+
*/
|
|
276
|
+
export declare function getMailhookAddressKey(options: MailhookAddressOptions): string;
|
|
150
277
|
/**
|
|
151
278
|
* Returns the organization-authenticated submission endpoint for one dashboard
|
|
152
279
|
* run.
|
package/dist/triggers/core.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import * as z from "zod/mini";
|
|
2
|
+
const MAX_EMAIL_LOCAL_PART_BYTES = 64;
|
|
3
|
+
const EMAIL_SCHEMA = z.email();
|
|
4
|
+
const URL_SCHEMA = z.url();
|
|
2
5
|
const CRON_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
3
6
|
schedule: z.string(),
|
|
4
7
|
timeZone: z.prefault(z.string(), "UTC"),
|
|
@@ -6,6 +9,9 @@ const CRON_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
|
6
9
|
const HTTP_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
7
10
|
scope: z.prefault(z.enum(["trigger", "automation", "project"]), "trigger"),
|
|
8
11
|
});
|
|
12
|
+
const MAILHOOK_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
13
|
+
scope: z.prefault(z.enum(["trigger", "automation", "project"]), "trigger"),
|
|
14
|
+
});
|
|
9
15
|
const INVOCATION_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
10
16
|
entrypoint: z.string(),
|
|
11
17
|
});
|
|
@@ -20,25 +26,48 @@ const FIELD_LENGTH_SCHEMA = z.int().check(z.nonnegative());
|
|
|
20
26
|
const DASHBOARD_RUN_FIELD_BASE_SCHEMA = {
|
|
21
27
|
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
22
28
|
label: FIELD_LABEL_SCHEMA,
|
|
23
|
-
|
|
29
|
+
name: FIELD_NAME_SCHEMA,
|
|
24
30
|
};
|
|
25
31
|
const DASHBOARD_RUN_TEXT_FIELD_SCHEMA = z.object({
|
|
26
32
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
33
|
+
defaultValue: z.optional(z.string()),
|
|
27
34
|
maxLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
28
35
|
minLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
29
36
|
placeholder: z.optional(z.string()),
|
|
30
|
-
|
|
37
|
+
required: z.prefault(z.boolean(), true),
|
|
38
|
+
type: z.enum(["email", "phone", "text", "textarea", "url"]),
|
|
31
39
|
});
|
|
32
40
|
const DASHBOARD_RUN_NUMBER_FIELD_SCHEMA = z.object({
|
|
33
41
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
42
|
+
defaultValue: z.optional(z.number()),
|
|
34
43
|
max: z.optional(z.number()),
|
|
35
44
|
min: z.optional(z.number()),
|
|
36
45
|
placeholder: z.optional(z.string()),
|
|
46
|
+
required: z.prefault(z.boolean(), true),
|
|
37
47
|
step: z.prefault(z.number().check(z.positive()), 1),
|
|
38
48
|
type: z.literal("number"),
|
|
39
49
|
});
|
|
40
|
-
const
|
|
50
|
+
const DASHBOARD_RUN_DATE_FIELD_SCHEMA = z.object({
|
|
51
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
52
|
+
defaultValue: z.optional(z.iso.date()),
|
|
53
|
+
max: z.optional(z.iso.date()),
|
|
54
|
+
min: z.optional(z.iso.date()),
|
|
55
|
+
required: z.prefault(z.boolean(), true),
|
|
56
|
+
step: z.prefault(z.int().check(z.positive()), 1),
|
|
57
|
+
type: z.literal("date"),
|
|
58
|
+
});
|
|
59
|
+
const DASHBOARD_RUN_DATETIME_FIELD_SCHEMA = z.object({
|
|
60
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
61
|
+
defaultValue: z.optional(z.iso.datetime({ local: true })),
|
|
62
|
+
max: z.optional(z.iso.datetime({ local: true })),
|
|
63
|
+
min: z.optional(z.iso.datetime({ local: true })),
|
|
64
|
+
required: z.prefault(z.boolean(), true),
|
|
65
|
+
step: z.prefault(z.number().check(z.positive()), 60),
|
|
66
|
+
type: z.literal("datetime"),
|
|
67
|
+
});
|
|
68
|
+
const DASHBOARD_RUN_CHOICE_FIELD_SCHEMA = {
|
|
41
69
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
70
|
+
defaultValue: z.optional(FIELD_NAME_SCHEMA),
|
|
42
71
|
options: z
|
|
43
72
|
.array(z.object({
|
|
44
73
|
label: FIELD_LABEL_SCHEMA,
|
|
@@ -46,20 +75,49 @@ const DASHBOARD_RUN_SELECT_FIELD_SCHEMA = z.object({
|
|
|
46
75
|
}))
|
|
47
76
|
.check(z.minLength(1)),
|
|
48
77
|
placeholder: z.optional(z.string()),
|
|
78
|
+
required: z.prefault(z.boolean(), true),
|
|
79
|
+
};
|
|
80
|
+
const DASHBOARD_RUN_SELECT_FIELD_SCHEMA = z.object({
|
|
81
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
49
82
|
type: z.literal("select"),
|
|
50
83
|
});
|
|
84
|
+
const DASHBOARD_RUN_RADIO_FIELD_SCHEMA = z.object({
|
|
85
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
86
|
+
type: z.literal("radio"),
|
|
87
|
+
});
|
|
88
|
+
const DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA = z.object({
|
|
89
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
90
|
+
defaultValue: z.optional(z.array(FIELD_NAME_SCHEMA)),
|
|
91
|
+
options: z
|
|
92
|
+
.array(z.object({
|
|
93
|
+
label: FIELD_LABEL_SCHEMA,
|
|
94
|
+
value: FIELD_NAME_SCHEMA,
|
|
95
|
+
}))
|
|
96
|
+
.check(z.minLength(1)),
|
|
97
|
+
placeholder: z.optional(z.string()),
|
|
98
|
+
required: z.prefault(z.boolean(), true),
|
|
99
|
+
type: z.literal("multi-select"),
|
|
100
|
+
});
|
|
51
101
|
const DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA = z.object({
|
|
52
102
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
103
|
+
defaultValue: z.prefault(z.boolean(), false),
|
|
104
|
+
required: z.prefault(z.boolean(), false),
|
|
53
105
|
type: z.literal("checkbox"),
|
|
54
106
|
});
|
|
107
|
+
const DASHBOARD_RUN_FIELD_SCHEMA = z.discriminatedUnion("type", [
|
|
108
|
+
DASHBOARD_RUN_TEXT_FIELD_SCHEMA,
|
|
109
|
+
DASHBOARD_RUN_NUMBER_FIELD_SCHEMA,
|
|
110
|
+
DASHBOARD_RUN_DATE_FIELD_SCHEMA,
|
|
111
|
+
DASHBOARD_RUN_DATETIME_FIELD_SCHEMA,
|
|
112
|
+
DASHBOARD_RUN_SELECT_FIELD_SCHEMA,
|
|
113
|
+
DASHBOARD_RUN_RADIO_FIELD_SCHEMA,
|
|
114
|
+
DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA,
|
|
115
|
+
DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA,
|
|
116
|
+
]);
|
|
117
|
+
const DASHBOARD_RUN_FIELDS_SCHEMA = z.array(DASHBOARD_RUN_FIELD_SCHEMA).check(z.refine((fields) => new Set(fields.map((field) => field.name)).size === fields.length, "Dashboard run field names must be unique."), z.refine((fields) => fields.every(isDashboardRunFieldDefaultValid), "Dashboard run field defaults must satisfy their field constraints."));
|
|
55
118
|
export const DASHBOARD_RUN_CONFIG_SCHEMA = z.object({
|
|
56
119
|
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
57
|
-
fields: z.
|
|
58
|
-
DASHBOARD_RUN_TEXT_FIELD_SCHEMA,
|
|
59
|
-
DASHBOARD_RUN_NUMBER_FIELD_SCHEMA,
|
|
60
|
-
DASHBOARD_RUN_SELECT_FIELD_SCHEMA,
|
|
61
|
-
DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA,
|
|
62
|
-
])),
|
|
120
|
+
fields: z.prefault(DASHBOARD_RUN_FIELDS_SCHEMA, []),
|
|
63
121
|
submitLabel: z.prefault(z.string().check(z.trim(), z.minLength(1), z.maxLength(100)), "Run"),
|
|
64
122
|
title: z.string().check(z.trim(), z.minLength(1), z.maxLength(255)),
|
|
65
123
|
});
|
|
@@ -103,6 +161,21 @@ export const coreTriggerDefinitions = {
|
|
|
103
161
|
name: "HTTP request",
|
|
104
162
|
type: "http.request",
|
|
105
163
|
},
|
|
164
|
+
mailhookEmailReceived: {
|
|
165
|
+
getPrimary: ({ automationId, config, hookSlot, projectId, scopePath }) => ({
|
|
166
|
+
copyable: true,
|
|
167
|
+
value: getMailhookAddress({
|
|
168
|
+
automationId,
|
|
169
|
+
hookSlot,
|
|
170
|
+
projectId,
|
|
171
|
+
scope: MAILHOOK_PRESENTATION_CONFIG_SCHEMA.parse(config).scope,
|
|
172
|
+
scopePath,
|
|
173
|
+
}),
|
|
174
|
+
}),
|
|
175
|
+
icon: "webhook",
|
|
176
|
+
name: "Mailhook",
|
|
177
|
+
type: "mailhook.email.received",
|
|
178
|
+
},
|
|
106
179
|
dashboardRun: {
|
|
107
180
|
getDetails: ({ config }) => [
|
|
108
181
|
{
|
|
@@ -115,6 +188,7 @@ export const coreTriggerDefinitions = {
|
|
|
115
188
|
type: "dashboard.run",
|
|
116
189
|
},
|
|
117
190
|
};
|
|
191
|
+
export const PLATFORM_EMAIL_DOMAIN = "automations.automate.ax";
|
|
118
192
|
/**
|
|
119
193
|
* Returns the public URL for one deployed HTTP trigger.
|
|
120
194
|
*
|
|
@@ -138,6 +212,39 @@ export function getHttpTriggerEndpointKey(options) {
|
|
|
138
212
|
options.hookSlot,
|
|
139
213
|
].join(".")}`;
|
|
140
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Returns the unique inbound address for one deployed mailhook.
|
|
217
|
+
*
|
|
218
|
+
* Add `+suffix` before the `@` to carry a routing value into the event.
|
|
219
|
+
*
|
|
220
|
+
* @param options - Mailhook identity and sharing scope.
|
|
221
|
+
* @throws When the generated local part exceeds the email size limit.
|
|
222
|
+
*/
|
|
223
|
+
export function getMailhookAddress(options) {
|
|
224
|
+
const localPart = `${getMailhookAddressKey(options)}${options.plusPath ? `+${options.plusPath}` : ""}`;
|
|
225
|
+
if (new TextEncoder().encode(localPart).length > MAX_EMAIL_LOCAL_PART_BYTES) {
|
|
226
|
+
throw new RangeError("Mailhook address local part exceeds 64 bytes.");
|
|
227
|
+
}
|
|
228
|
+
return EMAIL_SCHEMA.parse(`${localPart}@${PLATFORM_EMAIL_DOMAIN}`);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns the local-part router key for one configured mailhook scope.
|
|
232
|
+
*
|
|
233
|
+
* @param options - Mailhook identity and sharing scope.
|
|
234
|
+
*/
|
|
235
|
+
export function getMailhookAddressKey(options) {
|
|
236
|
+
if (options.scope === "project")
|
|
237
|
+
return `p${typeIdSuffix(options.projectId)}`;
|
|
238
|
+
if (options.scope === "automation") {
|
|
239
|
+
return `a${typeIdSuffix(options.automationId)}`;
|
|
240
|
+
}
|
|
241
|
+
return `a${typeIdSuffix(options.automationId)}.${[
|
|
242
|
+
...(options.scopePath ?? []),
|
|
243
|
+
options.hookSlot,
|
|
244
|
+
]
|
|
245
|
+
.map((segment) => segment.toString(36))
|
|
246
|
+
.join(".")}`;
|
|
247
|
+
}
|
|
141
248
|
/**
|
|
142
249
|
* Returns the organization-authenticated submission endpoint for one dashboard
|
|
143
250
|
* run.
|
|
@@ -158,3 +265,68 @@ export function getDashboardRunEndpointKey(options) {
|
|
|
158
265
|
options.hookSlot,
|
|
159
266
|
].join(".")}`;
|
|
160
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Checks a configured default against the same constraints as submitted data.
|
|
270
|
+
*
|
|
271
|
+
* @param field - Field definition to validate.
|
|
272
|
+
*/
|
|
273
|
+
function isDashboardRunFieldDefaultValid(field) {
|
|
274
|
+
if (field.type === "checkbox" || field.defaultValue === undefined)
|
|
275
|
+
return true;
|
|
276
|
+
if (field.type === "multi-select") {
|
|
277
|
+
if (field.required !== false && field.defaultValue.length === 0)
|
|
278
|
+
return false;
|
|
279
|
+
return field.defaultValue.every((value) => field.options.some((option) => option.value === value));
|
|
280
|
+
}
|
|
281
|
+
if (field.type === "radio" || field.type === "select") {
|
|
282
|
+
return field.options.some((option) => option.value === field.defaultValue);
|
|
283
|
+
}
|
|
284
|
+
if (field.type === "number") {
|
|
285
|
+
return ((field.min === undefined || field.defaultValue >= field.min) &&
|
|
286
|
+
(field.max === undefined || field.defaultValue <= field.max) &&
|
|
287
|
+
!isDashboardRunStepMismatch(field.defaultValue, field.min ?? field.defaultValue, field.step ?? 1));
|
|
288
|
+
}
|
|
289
|
+
if (field.type === "date" || field.type === "datetime") {
|
|
290
|
+
const defaultValue = parseDashboardRunDateValue(field.type, field.defaultValue);
|
|
291
|
+
return ((field.min === undefined ||
|
|
292
|
+
defaultValue >= parseDashboardRunDateValue(field.type, field.min)) &&
|
|
293
|
+
(field.max === undefined ||
|
|
294
|
+
defaultValue <= parseDashboardRunDateValue(field.type, field.max)) &&
|
|
295
|
+
!isDashboardRunStepMismatch(defaultValue, parseDashboardRunDateValue(field.type, field.min ?? field.defaultValue), (field.step ?? (field.type === "date" ? 1 : 60)) *
|
|
296
|
+
(field.type === "date" ? 86_400_000 : 1_000)));
|
|
297
|
+
}
|
|
298
|
+
const defaultValue = field.defaultValue.trim();
|
|
299
|
+
return ((defaultValue.length > 0 || field.required === false) &&
|
|
300
|
+
(field.minLength === undefined || defaultValue.length >= field.minLength) &&
|
|
301
|
+
(field.maxLength === undefined || defaultValue.length <= field.maxLength) &&
|
|
302
|
+
(field.type !== "email" || EMAIL_SCHEMA.safeParse(defaultValue).success) &&
|
|
303
|
+
(field.type !== "url" || URL_SCHEMA.safeParse(defaultValue).success));
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Checks whether a value falls outside an allowed step interval.
|
|
307
|
+
*
|
|
308
|
+
* @param value - Configured default value.
|
|
309
|
+
* @param base - Value from which step intervals begin.
|
|
310
|
+
* @param step - Allowed interval size.
|
|
311
|
+
*/
|
|
312
|
+
function isDashboardRunStepMismatch(value, base, step) {
|
|
313
|
+
const intervals = (value - base) / step;
|
|
314
|
+
return Math.abs(intervals - Math.round(intervals)) > 1e-9;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Converts a validated local date or date-time string to a UTC number.
|
|
318
|
+
*
|
|
319
|
+
* @param type - Temporal field type.
|
|
320
|
+
* @param value - Local ISO value to convert.
|
|
321
|
+
*/
|
|
322
|
+
function parseDashboardRunDateValue(type, value) {
|
|
323
|
+
return Date.parse(type === "date" ? `${value}T00:00:00Z` : `${value}Z`);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Removes the redundant TypeID prefix from an address router.
|
|
327
|
+
*
|
|
328
|
+
* @param id - Project or automation TypeID.
|
|
329
|
+
*/
|
|
330
|
+
function typeIdSuffix(id) {
|
|
331
|
+
return id.includes("_") ? id.slice(id.indexOf("_") + 1) : id;
|
|
332
|
+
}
|
package/dist/triggers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TriggerDefinition, TriggerPresentation, TriggerPresentationContext, TriggerScopePresentation } from "../types.js";
|
|
2
|
-
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, DASHBOARD_RUN_CONFIG_SCHEMA, type DashboardRunConfig, type DashboardRunEndpointOptions, type DashboardRunField, type HttpTriggerEndpointOptions, type HttpTriggerScope, } from "./core.js";
|
|
2
|
+
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, getMailhookAddress, getMailhookAddressKey, PLATFORM_EMAIL_DOMAIN, DASHBOARD_RUN_CONFIG_SCHEMA, type DashboardRunConfig, type DashboardRunEndpointOptions, type DashboardRunField, type HttpTriggerEndpointOptions, type HttpTriggerScope, type MailhookAddressOptions, type MailhookScope, } from "./core.js";
|
|
3
3
|
/** Plain shared definitions for every public trigger type. */
|
|
4
4
|
export declare const triggerDefinitions: {
|
|
5
5
|
readonly whatsappMessageDelivered: {
|
|
@@ -1075,6 +1075,15 @@ export declare const triggerDefinitions: {
|
|
|
1075
1075
|
readonly name: "HTTP request";
|
|
1076
1076
|
readonly type: "http.request";
|
|
1077
1077
|
};
|
|
1078
|
+
readonly mailhookEmailReceived: {
|
|
1079
|
+
readonly getPrimary: ({ automationId, config, hookSlot, projectId, scopePath }: TriggerPresentationContext) => {
|
|
1080
|
+
copyable: true;
|
|
1081
|
+
value: string;
|
|
1082
|
+
};
|
|
1083
|
+
readonly icon: "webhook";
|
|
1084
|
+
readonly name: "Mailhook";
|
|
1085
|
+
readonly type: "mailhook.email.received";
|
|
1086
|
+
};
|
|
1078
1087
|
readonly dashboardRun: {
|
|
1079
1088
|
readonly getDetails: ({ config }: TriggerPresentationContext) => {
|
|
1080
1089
|
label: string;
|
|
@@ -1564,6 +1573,14 @@ export declare const triggerCatalog: ({
|
|
|
1564
1573
|
};
|
|
1565
1574
|
icon: "webhook";
|
|
1566
1575
|
type: "http.request";
|
|
1576
|
+
} | {
|
|
1577
|
+
name: string;
|
|
1578
|
+
getPrimary: ({ automationId, config, hookSlot, projectId, scopePath }: TriggerPresentationContext) => {
|
|
1579
|
+
copyable: true;
|
|
1580
|
+
value: string;
|
|
1581
|
+
};
|
|
1582
|
+
icon: "webhook";
|
|
1583
|
+
type: "mailhook.email.received";
|
|
1567
1584
|
} | {
|
|
1568
1585
|
name: string;
|
|
1569
1586
|
getDetails: ({ config }: TriggerPresentationContext) => {
|
package/dist/triggers/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { trelloTriggerDefinitions } from "./trello.js";
|
|
|
12
12
|
import { vercelTriggerDefinitions } from "./vercel.js";
|
|
13
13
|
import { whatsappTriggerDefinitions } from "./whatsapp.js";
|
|
14
14
|
import { getIntegrationService } from "../catalog.js";
|
|
15
|
-
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, DASHBOARD_RUN_CONFIG_SCHEMA, } from "./core.js";
|
|
15
|
+
export { getDashboardRunEndpoint, getDashboardRunEndpointKey, getHttpTriggerEndpoint, getHttpTriggerEndpointKey, getMailhookAddress, getMailhookAddressKey, PLATFORM_EMAIL_DOMAIN, DASHBOARD_RUN_CONFIG_SCHEMA, } from "./core.js";
|
|
16
16
|
/** Plain shared definitions for every public trigger type. */
|
|
17
17
|
export const triggerDefinitions = {
|
|
18
18
|
...airtableTriggerDefinitions,
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -61,11 +61,14 @@ export {
|
|
|
61
61
|
getDashboardRunEndpointKey,
|
|
62
62
|
getHttpTriggerEndpoint,
|
|
63
63
|
getHttpTriggerEndpointKey,
|
|
64
|
+
getMailhookAddress,
|
|
65
|
+
getMailhookAddressKey,
|
|
64
66
|
DASHBOARD_RUN_CONFIG_SCHEMA,
|
|
65
67
|
getTriggerDefinition,
|
|
66
68
|
getTriggerName,
|
|
67
69
|
getTriggerPresentation,
|
|
68
70
|
isTriggerVisible,
|
|
71
|
+
PLATFORM_EMAIL_DOMAIN,
|
|
69
72
|
triggerCatalog,
|
|
70
73
|
triggerDefinitions,
|
|
71
74
|
type DashboardRunConfig,
|
|
@@ -73,5 +76,7 @@ export {
|
|
|
73
76
|
type DashboardRunField,
|
|
74
77
|
type HttpTriggerEndpointOptions,
|
|
75
78
|
type HttpTriggerScope,
|
|
79
|
+
type MailhookAddressOptions,
|
|
80
|
+
type MailhookScope,
|
|
76
81
|
type TriggerType,
|
|
77
82
|
} from "./triggers"
|
package/src/triggers/core.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { TriggerDefinition } from "../types"
|
|
2
2
|
import * as z from "zod/mini"
|
|
3
3
|
|
|
4
|
+
const MAX_EMAIL_LOCAL_PART_BYTES = 64
|
|
5
|
+
const EMAIL_SCHEMA = z.email()
|
|
6
|
+
const URL_SCHEMA = z.url()
|
|
4
7
|
const CRON_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
5
8
|
schedule: z.string(),
|
|
6
9
|
timeZone: z.prefault(z.string(), "UTC"),
|
|
@@ -8,6 +11,9 @@ const CRON_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
|
8
11
|
const HTTP_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
9
12
|
scope: z.prefault(z.enum(["trigger", "automation", "project"]), "trigger"),
|
|
10
13
|
})
|
|
14
|
+
const MAILHOOK_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
15
|
+
scope: z.prefault(z.enum(["trigger", "automation", "project"]), "trigger"),
|
|
16
|
+
})
|
|
11
17
|
const INVOCATION_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
12
18
|
entrypoint: z.string(),
|
|
13
19
|
})
|
|
@@ -22,25 +28,48 @@ const FIELD_LENGTH_SCHEMA = z.int().check(z.nonnegative())
|
|
|
22
28
|
const DASHBOARD_RUN_FIELD_BASE_SCHEMA = {
|
|
23
29
|
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
24
30
|
label: FIELD_LABEL_SCHEMA,
|
|
25
|
-
|
|
31
|
+
name: FIELD_NAME_SCHEMA,
|
|
26
32
|
}
|
|
27
33
|
const DASHBOARD_RUN_TEXT_FIELD_SCHEMA = z.object({
|
|
28
34
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
35
|
+
defaultValue: z.optional(z.string()),
|
|
29
36
|
maxLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
30
37
|
minLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
31
38
|
placeholder: z.optional(z.string()),
|
|
32
|
-
|
|
39
|
+
required: z.prefault(z.boolean(), true),
|
|
40
|
+
type: z.enum(["email", "phone", "text", "textarea", "url"]),
|
|
33
41
|
})
|
|
34
42
|
const DASHBOARD_RUN_NUMBER_FIELD_SCHEMA = z.object({
|
|
35
43
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
44
|
+
defaultValue: z.optional(z.number()),
|
|
36
45
|
max: z.optional(z.number()),
|
|
37
46
|
min: z.optional(z.number()),
|
|
38
47
|
placeholder: z.optional(z.string()),
|
|
48
|
+
required: z.prefault(z.boolean(), true),
|
|
39
49
|
step: z.prefault(z.number().check(z.positive()), 1),
|
|
40
50
|
type: z.literal("number"),
|
|
41
51
|
})
|
|
42
|
-
const
|
|
52
|
+
const DASHBOARD_RUN_DATE_FIELD_SCHEMA = z.object({
|
|
53
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
54
|
+
defaultValue: z.optional(z.iso.date()),
|
|
55
|
+
max: z.optional(z.iso.date()),
|
|
56
|
+
min: z.optional(z.iso.date()),
|
|
57
|
+
required: z.prefault(z.boolean(), true),
|
|
58
|
+
step: z.prefault(z.int().check(z.positive()), 1),
|
|
59
|
+
type: z.literal("date"),
|
|
60
|
+
})
|
|
61
|
+
const DASHBOARD_RUN_DATETIME_FIELD_SCHEMA = z.object({
|
|
43
62
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
63
|
+
defaultValue: z.optional(z.iso.datetime({ local: true })),
|
|
64
|
+
max: z.optional(z.iso.datetime({ local: true })),
|
|
65
|
+
min: z.optional(z.iso.datetime({ local: true })),
|
|
66
|
+
required: z.prefault(z.boolean(), true),
|
|
67
|
+
step: z.prefault(z.number().check(z.positive()), 60),
|
|
68
|
+
type: z.literal("datetime"),
|
|
69
|
+
})
|
|
70
|
+
const DASHBOARD_RUN_CHOICE_FIELD_SCHEMA = {
|
|
71
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
72
|
+
defaultValue: z.optional(FIELD_NAME_SCHEMA),
|
|
44
73
|
options: z
|
|
45
74
|
.array(
|
|
46
75
|
z.object({
|
|
@@ -50,24 +79,62 @@ const DASHBOARD_RUN_SELECT_FIELD_SCHEMA = z.object({
|
|
|
50
79
|
)
|
|
51
80
|
.check(z.minLength(1)),
|
|
52
81
|
placeholder: z.optional(z.string()),
|
|
82
|
+
required: z.prefault(z.boolean(), true),
|
|
83
|
+
}
|
|
84
|
+
const DASHBOARD_RUN_SELECT_FIELD_SCHEMA = z.object({
|
|
85
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
53
86
|
type: z.literal("select"),
|
|
54
87
|
})
|
|
88
|
+
const DASHBOARD_RUN_RADIO_FIELD_SCHEMA = z.object({
|
|
89
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
90
|
+
type: z.literal("radio"),
|
|
91
|
+
})
|
|
92
|
+
const DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA = z.object({
|
|
93
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
94
|
+
defaultValue: z.optional(z.array(FIELD_NAME_SCHEMA)),
|
|
95
|
+
options: z
|
|
96
|
+
.array(
|
|
97
|
+
z.object({
|
|
98
|
+
label: FIELD_LABEL_SCHEMA,
|
|
99
|
+
value: FIELD_NAME_SCHEMA,
|
|
100
|
+
}),
|
|
101
|
+
)
|
|
102
|
+
.check(z.minLength(1)),
|
|
103
|
+
placeholder: z.optional(z.string()),
|
|
104
|
+
required: z.prefault(z.boolean(), true),
|
|
105
|
+
type: z.literal("multi-select"),
|
|
106
|
+
})
|
|
55
107
|
const DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA = z.object({
|
|
56
108
|
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
109
|
+
defaultValue: z.prefault(z.boolean(), false),
|
|
110
|
+
required: z.prefault(z.boolean(), false),
|
|
57
111
|
type: z.literal("checkbox"),
|
|
58
112
|
})
|
|
113
|
+
const DASHBOARD_RUN_FIELD_SCHEMA = z.discriminatedUnion("type", [
|
|
114
|
+
DASHBOARD_RUN_TEXT_FIELD_SCHEMA,
|
|
115
|
+
DASHBOARD_RUN_NUMBER_FIELD_SCHEMA,
|
|
116
|
+
DASHBOARD_RUN_DATE_FIELD_SCHEMA,
|
|
117
|
+
DASHBOARD_RUN_DATETIME_FIELD_SCHEMA,
|
|
118
|
+
DASHBOARD_RUN_SELECT_FIELD_SCHEMA,
|
|
119
|
+
DASHBOARD_RUN_RADIO_FIELD_SCHEMA,
|
|
120
|
+
DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA,
|
|
121
|
+
DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA,
|
|
122
|
+
])
|
|
123
|
+
const DASHBOARD_RUN_FIELDS_SCHEMA = z.array(DASHBOARD_RUN_FIELD_SCHEMA).check(
|
|
124
|
+
z.refine(
|
|
125
|
+
(fields) =>
|
|
126
|
+
new Set(fields.map((field) => field.name)).size === fields.length,
|
|
127
|
+
"Dashboard run field names must be unique.",
|
|
128
|
+
),
|
|
129
|
+
z.refine(
|
|
130
|
+
(fields) => fields.every(isDashboardRunFieldDefaultValid),
|
|
131
|
+
"Dashboard run field defaults must satisfy their field constraints.",
|
|
132
|
+
),
|
|
133
|
+
)
|
|
59
134
|
|
|
60
135
|
export const DASHBOARD_RUN_CONFIG_SCHEMA = z.object({
|
|
61
136
|
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
62
|
-
fields: z.
|
|
63
|
-
FIELD_NAME_SCHEMA,
|
|
64
|
-
z.discriminatedUnion("type", [
|
|
65
|
-
DASHBOARD_RUN_TEXT_FIELD_SCHEMA,
|
|
66
|
-
DASHBOARD_RUN_NUMBER_FIELD_SCHEMA,
|
|
67
|
-
DASHBOARD_RUN_SELECT_FIELD_SCHEMA,
|
|
68
|
-
DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA,
|
|
69
|
-
]),
|
|
70
|
-
),
|
|
137
|
+
fields: z.prefault(DASHBOARD_RUN_FIELDS_SCHEMA, []),
|
|
71
138
|
submitLabel: z.prefault(
|
|
72
139
|
z.string().check(z.trim(), z.minLength(1), z.maxLength(100)),
|
|
73
140
|
"Run",
|
|
@@ -123,6 +190,21 @@ export const coreTriggerDefinitions = {
|
|
|
123
190
|
name: "HTTP request",
|
|
124
191
|
type: "http.request",
|
|
125
192
|
},
|
|
193
|
+
mailhookEmailReceived: {
|
|
194
|
+
getPrimary: ({ automationId, config, hookSlot, projectId, scopePath }) => ({
|
|
195
|
+
copyable: true,
|
|
196
|
+
value: getMailhookAddress({
|
|
197
|
+
automationId,
|
|
198
|
+
hookSlot,
|
|
199
|
+
projectId,
|
|
200
|
+
scope: MAILHOOK_PRESENTATION_CONFIG_SCHEMA.parse(config).scope,
|
|
201
|
+
scopePath,
|
|
202
|
+
}),
|
|
203
|
+
}),
|
|
204
|
+
icon: "webhook",
|
|
205
|
+
name: "Mailhook",
|
|
206
|
+
type: "mailhook.email.received",
|
|
207
|
+
},
|
|
126
208
|
dashboardRun: {
|
|
127
209
|
getDetails: ({ config }) => [
|
|
128
210
|
{
|
|
@@ -143,18 +225,23 @@ interface DashboardRunFieldBase {
|
|
|
143
225
|
/** Visible field label. */
|
|
144
226
|
label: string
|
|
145
227
|
|
|
228
|
+
/** Property name used in submitted trigger data. */
|
|
229
|
+
name: string
|
|
230
|
+
|
|
146
231
|
/** Whether the form must contain a value. Defaults to true. */
|
|
147
232
|
required?: boolean
|
|
148
233
|
}
|
|
149
234
|
|
|
150
235
|
export type DashboardRunField =
|
|
151
236
|
| (DashboardRunFieldBase & {
|
|
237
|
+
defaultValue?: string
|
|
152
238
|
maxLength?: number
|
|
153
239
|
minLength?: number
|
|
154
240
|
placeholder?: string
|
|
155
|
-
type: "email" | "text" | "textarea" | "url"
|
|
241
|
+
type: "email" | "phone" | "text" | "textarea" | "url"
|
|
156
242
|
})
|
|
157
243
|
| (DashboardRunFieldBase & {
|
|
244
|
+
defaultValue?: number
|
|
158
245
|
max?: number
|
|
159
246
|
min?: number
|
|
160
247
|
placeholder?: string
|
|
@@ -164,25 +251,59 @@ export type DashboardRunField =
|
|
|
164
251
|
type: "number"
|
|
165
252
|
})
|
|
166
253
|
| (DashboardRunFieldBase & {
|
|
254
|
+
/** Initial local date in `YYYY-MM-DD` format. */
|
|
255
|
+
defaultValue?: string
|
|
256
|
+
max?: string
|
|
257
|
+
min?: string
|
|
258
|
+
|
|
259
|
+
/** Allowed increment in days. Defaults to 1. */
|
|
260
|
+
step?: number
|
|
261
|
+
type: "date"
|
|
262
|
+
})
|
|
263
|
+
| (DashboardRunFieldBase & {
|
|
264
|
+
/** Initial local date and time in `YYYY-MM-DDTHH:mm` format. */
|
|
265
|
+
defaultValue?: string
|
|
266
|
+
max?: string
|
|
267
|
+
min?: string
|
|
268
|
+
|
|
269
|
+
/** Allowed increment in seconds. Defaults to 60. */
|
|
270
|
+
step?: number
|
|
271
|
+
type: "datetime"
|
|
272
|
+
})
|
|
273
|
+
| (DashboardRunFieldBase & {
|
|
274
|
+
defaultValue?: string
|
|
167
275
|
options: readonly { label: string; value: string }[]
|
|
168
276
|
placeholder?: string
|
|
169
277
|
type: "select"
|
|
170
278
|
})
|
|
171
279
|
| (DashboardRunFieldBase & {
|
|
280
|
+
defaultValue?: string
|
|
281
|
+
options: readonly { label: string; value: string }[]
|
|
282
|
+
type: "radio"
|
|
283
|
+
})
|
|
284
|
+
| (DashboardRunFieldBase & {
|
|
285
|
+
defaultValue?: readonly string[]
|
|
286
|
+
options: readonly { label: string; value: string }[]
|
|
287
|
+
placeholder?: string
|
|
288
|
+
type: "multi-select"
|
|
289
|
+
})
|
|
290
|
+
| (DashboardRunFieldBase & {
|
|
291
|
+
/** Initial checked state. Defaults to false. */
|
|
292
|
+
defaultValue?: boolean
|
|
293
|
+
|
|
294
|
+
/** Whether the checkbox must be checked. Defaults to false. */
|
|
295
|
+
required?: boolean
|
|
172
296
|
type: "checkbox"
|
|
173
297
|
})
|
|
174
298
|
|
|
175
299
|
export interface DashboardRunConfig<
|
|
176
|
-
TFields extends
|
|
177
|
-
string,
|
|
178
|
-
DashboardRunField
|
|
179
|
-
>,
|
|
300
|
+
TFields extends readonly DashboardRunField[] = readonly DashboardRunField[],
|
|
180
301
|
> {
|
|
181
302
|
/** Supporting text shown below the form title. */
|
|
182
303
|
description?: string
|
|
183
304
|
|
|
184
|
-
/**
|
|
185
|
-
fields
|
|
305
|
+
/** Ordered fields. Omit to run immediately. */
|
|
306
|
+
fields?: TFields
|
|
186
307
|
|
|
187
308
|
/** Submit button text. Defaults to "Run". */
|
|
188
309
|
submitLabel?: string
|
|
@@ -199,6 +320,9 @@ export interface DashboardRunEndpointOptions {
|
|
|
199
320
|
}
|
|
200
321
|
|
|
201
322
|
export type HttpTriggerScope = "trigger" | "automation" | "project"
|
|
323
|
+
export type MailhookScope = HttpTriggerScope
|
|
324
|
+
|
|
325
|
+
export const PLATFORM_EMAIL_DOMAIN = "automations.automate.ax"
|
|
202
326
|
|
|
203
327
|
export interface HttpTriggerEndpointOptions {
|
|
204
328
|
appOrigin: string
|
|
@@ -209,6 +333,15 @@ export interface HttpTriggerEndpointOptions {
|
|
|
209
333
|
scopePath?: readonly number[]
|
|
210
334
|
}
|
|
211
335
|
|
|
336
|
+
export interface MailhookAddressOptions {
|
|
337
|
+
automationId: string
|
|
338
|
+
hookSlot: number
|
|
339
|
+
plusPath?: string
|
|
340
|
+
projectId: string
|
|
341
|
+
scope: MailhookScope
|
|
342
|
+
scopePath?: readonly number[]
|
|
343
|
+
}
|
|
344
|
+
|
|
212
345
|
/**
|
|
213
346
|
* Returns the public URL for one deployed HTTP trigger.
|
|
214
347
|
*
|
|
@@ -237,6 +370,42 @@ export function getHttpTriggerEndpointKey(
|
|
|
237
370
|
].join(".")}`
|
|
238
371
|
}
|
|
239
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Returns the unique inbound address for one deployed mailhook.
|
|
375
|
+
*
|
|
376
|
+
* Add `+suffix` before the `@` to carry a routing value into the event.
|
|
377
|
+
*
|
|
378
|
+
* @param options - Mailhook identity and sharing scope.
|
|
379
|
+
* @throws When the generated local part exceeds the email size limit.
|
|
380
|
+
*/
|
|
381
|
+
export function getMailhookAddress(options: MailhookAddressOptions) {
|
|
382
|
+
const localPart = `${getMailhookAddressKey(options)}${options.plusPath ? `+${options.plusPath}` : ""}`
|
|
383
|
+
if (new TextEncoder().encode(localPart).length > MAX_EMAIL_LOCAL_PART_BYTES) {
|
|
384
|
+
throw new RangeError("Mailhook address local part exceeds 64 bytes.")
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return EMAIL_SCHEMA.parse(`${localPart}@${PLATFORM_EMAIL_DOMAIN}`)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Returns the local-part router key for one configured mailhook scope.
|
|
392
|
+
*
|
|
393
|
+
* @param options - Mailhook identity and sharing scope.
|
|
394
|
+
*/
|
|
395
|
+
export function getMailhookAddressKey(options: MailhookAddressOptions) {
|
|
396
|
+
if (options.scope === "project") return `p${typeIdSuffix(options.projectId)}`
|
|
397
|
+
if (options.scope === "automation") {
|
|
398
|
+
return `a${typeIdSuffix(options.automationId)}`
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return `a${typeIdSuffix(options.automationId)}.${[
|
|
402
|
+
...(options.scopePath ?? []),
|
|
403
|
+
options.hookSlot,
|
|
404
|
+
]
|
|
405
|
+
.map((segment) => segment.toString(36))
|
|
406
|
+
.join(".")}`
|
|
407
|
+
}
|
|
408
|
+
|
|
240
409
|
/**
|
|
241
410
|
* Returns the organization-authenticated submission endpoint for one dashboard
|
|
242
411
|
* run.
|
|
@@ -263,3 +432,95 @@ export function getDashboardRunEndpointKey(
|
|
|
263
432
|
options.hookSlot,
|
|
264
433
|
].join(".")}`
|
|
265
434
|
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Checks a configured default against the same constraints as submitted data.
|
|
438
|
+
*
|
|
439
|
+
* @param field - Field definition to validate.
|
|
440
|
+
*/
|
|
441
|
+
function isDashboardRunFieldDefaultValid(field: DashboardRunField) {
|
|
442
|
+
if (field.type === "checkbox" || field.defaultValue === undefined) return true
|
|
443
|
+
|
|
444
|
+
if (field.type === "multi-select") {
|
|
445
|
+
if (field.required !== false && field.defaultValue.length === 0)
|
|
446
|
+
return false
|
|
447
|
+
return field.defaultValue.every((value) =>
|
|
448
|
+
field.options.some((option) => option.value === value),
|
|
449
|
+
)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (field.type === "radio" || field.type === "select") {
|
|
453
|
+
return field.options.some((option) => option.value === field.defaultValue)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (field.type === "number") {
|
|
457
|
+
return (
|
|
458
|
+
(field.min === undefined || field.defaultValue >= field.min) &&
|
|
459
|
+
(field.max === undefined || field.defaultValue <= field.max) &&
|
|
460
|
+
!isDashboardRunStepMismatch(
|
|
461
|
+
field.defaultValue,
|
|
462
|
+
field.min ?? field.defaultValue,
|
|
463
|
+
field.step ?? 1,
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (field.type === "date" || field.type === "datetime") {
|
|
469
|
+
const defaultValue = parseDashboardRunDateValue(
|
|
470
|
+
field.type,
|
|
471
|
+
field.defaultValue,
|
|
472
|
+
)
|
|
473
|
+
return (
|
|
474
|
+
(field.min === undefined ||
|
|
475
|
+
defaultValue >= parseDashboardRunDateValue(field.type, field.min)) &&
|
|
476
|
+
(field.max === undefined ||
|
|
477
|
+
defaultValue <= parseDashboardRunDateValue(field.type, field.max)) &&
|
|
478
|
+
!isDashboardRunStepMismatch(
|
|
479
|
+
defaultValue,
|
|
480
|
+
parseDashboardRunDateValue(field.type, field.min ?? field.defaultValue),
|
|
481
|
+
(field.step ?? (field.type === "date" ? 1 : 60)) *
|
|
482
|
+
(field.type === "date" ? 86_400_000 : 1_000),
|
|
483
|
+
)
|
|
484
|
+
)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const defaultValue = field.defaultValue.trim()
|
|
488
|
+
return (
|
|
489
|
+
(defaultValue.length > 0 || field.required === false) &&
|
|
490
|
+
(field.minLength === undefined || defaultValue.length >= field.minLength) &&
|
|
491
|
+
(field.maxLength === undefined || defaultValue.length <= field.maxLength) &&
|
|
492
|
+
(field.type !== "email" || EMAIL_SCHEMA.safeParse(defaultValue).success) &&
|
|
493
|
+
(field.type !== "url" || URL_SCHEMA.safeParse(defaultValue).success)
|
|
494
|
+
)
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Checks whether a value falls outside an allowed step interval.
|
|
499
|
+
*
|
|
500
|
+
* @param value - Configured default value.
|
|
501
|
+
* @param base - Value from which step intervals begin.
|
|
502
|
+
* @param step - Allowed interval size.
|
|
503
|
+
*/
|
|
504
|
+
function isDashboardRunStepMismatch(value: number, base: number, step: number) {
|
|
505
|
+
const intervals = (value - base) / step
|
|
506
|
+
return Math.abs(intervals - Math.round(intervals)) > 1e-9
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Converts a validated local date or date-time string to a UTC number.
|
|
511
|
+
*
|
|
512
|
+
* @param type - Temporal field type.
|
|
513
|
+
* @param value - Local ISO value to convert.
|
|
514
|
+
*/
|
|
515
|
+
function parseDashboardRunDateValue(type: "date" | "datetime", value: string) {
|
|
516
|
+
return Date.parse(type === "date" ? `${value}T00:00:00Z` : `${value}Z`)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Removes the redundant TypeID prefix from an address router.
|
|
521
|
+
*
|
|
522
|
+
* @param id - Project or automation TypeID.
|
|
523
|
+
*/
|
|
524
|
+
function typeIdSuffix(id: string) {
|
|
525
|
+
return id.includes("_") ? id.slice(id.indexOf("_") + 1) : id
|
|
526
|
+
}
|
package/src/triggers/index.ts
CHANGED
|
@@ -24,12 +24,17 @@ export {
|
|
|
24
24
|
getDashboardRunEndpointKey,
|
|
25
25
|
getHttpTriggerEndpoint,
|
|
26
26
|
getHttpTriggerEndpointKey,
|
|
27
|
+
getMailhookAddress,
|
|
28
|
+
getMailhookAddressKey,
|
|
29
|
+
PLATFORM_EMAIL_DOMAIN,
|
|
27
30
|
DASHBOARD_RUN_CONFIG_SCHEMA,
|
|
28
31
|
type DashboardRunConfig,
|
|
29
32
|
type DashboardRunEndpointOptions,
|
|
30
33
|
type DashboardRunField,
|
|
31
34
|
type HttpTriggerEndpointOptions,
|
|
32
35
|
type HttpTriggerScope,
|
|
36
|
+
type MailhookAddressOptions,
|
|
37
|
+
type MailhookScope,
|
|
33
38
|
} from "./core"
|
|
34
39
|
|
|
35
40
|
/** Plain shared definitions for every public trigger type. */
|