@automate.ax/catalog 0.75.0 → 0.77.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/authoring.d.ts +1 -0
- package/dist/authoring.js +1 -0
- package/dist/catalog.d.ts +142 -74
- package/dist/catalog.js +74 -13
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/triggers/airtable.js +1 -2
- package/dist/triggers/asana.js +1 -2
- package/dist/triggers/brevo.js +1 -2
- package/dist/triggers/core-dashboard.d.ts +374 -0
- package/dist/triggers/core-dashboard.js +202 -0
- package/dist/triggers/core-http.d.ts +30 -0
- package/dist/triggers/core-http.js +43 -0
- package/dist/triggers/core-invocation.d.ts +9 -0
- package/dist/triggers/core-invocation.js +15 -0
- package/dist/triggers/core-mailhook.d.ts +35 -0
- package/dist/triggers/core-mailhook.js +63 -0
- package/dist/triggers/core-schedule.d.ts +9 -0
- package/dist/triggers/core-schedule.js +17 -0
- package/dist/triggers/core.d.ts +15 -426
- package/dist/triggers/core.js +16 -346
- package/dist/triggers/github.js +4 -5
- package/dist/triggers/google.d.ts +143 -0
- package/dist/triggers/google.js +92 -5
- package/dist/triggers/index.d.ts +347 -74
- package/dist/triggers/index.js +2 -1
- package/dist/triggers/linear.js +1 -2
- package/dist/triggers/microsoft.js +3 -4
- package/dist/triggers/name.d.ts +13 -0
- package/dist/triggers/name.js +31 -0
- package/dist/triggers/resend.js +1 -2
- package/dist/triggers/slack.js +3 -4
- package/dist/triggers/trello.js +1 -2
- package/dist/triggers/vercel.d.ts +27 -27
- package/dist/triggers/vercel.js +10 -11
- package/dist/triggers/whatsapp.js +1 -2
- package/dist/types.d.ts +1 -1
- package/dist/types.js +3 -3
- package/package.json +118 -5
- package/src/authoring.ts +8 -0
- package/src/catalog.ts +76 -13
- package/src/index.ts +2 -0
- package/src/triggers/airtable.ts +1 -2
- package/src/triggers/asana.ts +1 -2
- package/src/triggers/brevo.ts +1 -2
- package/src/triggers/core-dashboard.ts +361 -0
- package/src/triggers/core-http.ts +69 -0
- package/src/triggers/core-invocation.ts +18 -0
- package/src/triggers/core-mailhook.ts +83 -0
- package/src/triggers/core-schedule.ts +21 -0
- package/src/triggers/core.ts +38 -544
- package/src/triggers/github.ts +4 -5
- package/src/triggers/google.ts +93 -5
- package/src/triggers/index.ts +2 -1
- package/src/triggers/linear.ts +1 -2
- package/src/triggers/microsoft.ts +3 -4
- package/src/triggers/name.ts +37 -0
- package/src/triggers/resend.ts +1 -2
- package/src/triggers/slack.ts +3 -4
- package/src/triggers/trello.ts +1 -2
- package/src/triggers/vercel.ts +10 -11
- package/src/triggers/whatsapp.ts +1 -2
- package/src/types.ts +4 -4
package/src/catalog.ts
CHANGED
|
@@ -9,7 +9,7 @@ const API_KEY_FIELD = {
|
|
|
9
9
|
} as const
|
|
10
10
|
|
|
11
11
|
export const airtableService = defineIntegrationService({
|
|
12
|
-
connectionMethods: [{ id: "
|
|
12
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
13
13
|
description: "Connect an Airtable account.",
|
|
14
14
|
id: "airtable",
|
|
15
15
|
name: "Airtable",
|
|
@@ -39,7 +39,7 @@ export const apolloService = defineIntegrationService({
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
export const asanaService = defineIntegrationService({
|
|
42
|
-
connectionMethods: [{ id: "
|
|
42
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
43
43
|
description: "Connect an Asana account.",
|
|
44
44
|
id: "asana",
|
|
45
45
|
name: "Asana",
|
|
@@ -82,6 +82,52 @@ export const cloudflareService = defineIntegrationService({
|
|
|
82
82
|
preferredConnectionMethodId: "oauth",
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
+
export const chatgptService = defineIntegrationService({
|
|
86
|
+
connectionMethods: [
|
|
87
|
+
{
|
|
88
|
+
fields: [
|
|
89
|
+
{
|
|
90
|
+
input: "password",
|
|
91
|
+
label: "Workspace Agent access token",
|
|
92
|
+
name: "apiKey",
|
|
93
|
+
placeholder: "Paste your ChatGPT access token",
|
|
94
|
+
required: true,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
id: "access-token",
|
|
98
|
+
name: "Access token",
|
|
99
|
+
type: "form",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
description: "Connect a Workspace Agent access token.",
|
|
103
|
+
icon: "openai",
|
|
104
|
+
id: "chatgpt",
|
|
105
|
+
name: "ChatGPT",
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export const codexService = defineIntegrationService({
|
|
109
|
+
connectionMethods: [
|
|
110
|
+
{
|
|
111
|
+
fields: [
|
|
112
|
+
{
|
|
113
|
+
input: "password",
|
|
114
|
+
label: "Codex access token",
|
|
115
|
+
name: "apiKey",
|
|
116
|
+
placeholder: "Paste your Codex access token",
|
|
117
|
+
required: true,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
id: "access-token",
|
|
121
|
+
name: "Access token",
|
|
122
|
+
type: "form",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
description: "Connect a Codex workspace access token.",
|
|
126
|
+
icon: "openai",
|
|
127
|
+
id: "codex",
|
|
128
|
+
name: "Codex",
|
|
129
|
+
})
|
|
130
|
+
|
|
85
131
|
export const cohereService = defineApiKeyService({
|
|
86
132
|
description: "Connect a Cohere API key.",
|
|
87
133
|
id: "cohere",
|
|
@@ -114,14 +160,16 @@ export const fireworksService = defineApiKeyService({
|
|
|
114
160
|
})
|
|
115
161
|
|
|
116
162
|
export const githubService = defineIntegrationService({
|
|
117
|
-
connectionMethods: [
|
|
163
|
+
connectionMethods: [
|
|
164
|
+
{ id: "github-app", name: "GitHub App", type: "redirect" },
|
|
165
|
+
],
|
|
118
166
|
description: "Install Automate.ax on a GitHub account or organization.",
|
|
119
167
|
id: "github",
|
|
120
168
|
name: "GitHub",
|
|
121
169
|
})
|
|
122
170
|
|
|
123
171
|
export const googleService = defineIntegrationService({
|
|
124
|
-
connectionMethods: [{ id: "
|
|
172
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
125
173
|
connectionNotice: {
|
|
126
174
|
action: {
|
|
127
175
|
href: "mailto:hello@automate.ax?subject=Google%20integration%20access",
|
|
@@ -149,22 +197,35 @@ export const groqService = defineApiKeyService({
|
|
|
149
197
|
name: "Groq",
|
|
150
198
|
})
|
|
151
199
|
|
|
152
|
-
export const huggingfaceService =
|
|
200
|
+
export const huggingfaceService = defineIntegrationService({
|
|
201
|
+
connectionMethods: [
|
|
202
|
+
{
|
|
203
|
+
fields: [
|
|
204
|
+
{
|
|
205
|
+
...API_KEY_FIELD,
|
|
206
|
+
label: "Access token",
|
|
207
|
+
placeholder: "hf_...",
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
id: "access-token",
|
|
211
|
+
name: "Access token",
|
|
212
|
+
type: "form",
|
|
213
|
+
},
|
|
214
|
+
],
|
|
153
215
|
description: "Connect a Hugging Face access token.",
|
|
154
216
|
id: "huggingface",
|
|
155
217
|
name: "Hugging Face",
|
|
156
|
-
placeholder: "hf_...",
|
|
157
218
|
})
|
|
158
219
|
|
|
159
220
|
export const linearService = defineIntegrationService({
|
|
160
|
-
connectionMethods: [{ id: "
|
|
221
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
161
222
|
description: "Connect a Linear workspace.",
|
|
162
223
|
id: "linear",
|
|
163
224
|
name: "Linear",
|
|
164
225
|
})
|
|
165
226
|
|
|
166
227
|
export const microsoftService = defineIntegrationService({
|
|
167
|
-
connectionMethods: [{ id: "
|
|
228
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
168
229
|
description: "Connect a Microsoft account.",
|
|
169
230
|
id: "microsoft",
|
|
170
231
|
name: "Microsoft",
|
|
@@ -217,7 +278,7 @@ export const postgresService = defineIntegrationService({
|
|
|
217
278
|
required: true,
|
|
218
279
|
},
|
|
219
280
|
],
|
|
220
|
-
id: "
|
|
281
|
+
id: "credentials",
|
|
221
282
|
name: "Credentials",
|
|
222
283
|
type: "form",
|
|
223
284
|
},
|
|
@@ -251,14 +312,14 @@ export const scrapflyService = defineApiKeyService({
|
|
|
251
312
|
})
|
|
252
313
|
|
|
253
314
|
export const slackService = defineIntegrationService({
|
|
254
|
-
connectionMethods: [{ id: "
|
|
315
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
255
316
|
description: "Install the Automate.ax bot in a Slack workspace.",
|
|
256
317
|
id: "slack",
|
|
257
318
|
name: "Slack",
|
|
258
319
|
})
|
|
259
320
|
|
|
260
321
|
export const tidycalService = defineIntegrationService({
|
|
261
|
-
connectionMethods: [{ id: "
|
|
322
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
262
323
|
description: "Connect a TidyCal account.",
|
|
263
324
|
id: "tidycal",
|
|
264
325
|
name: "TidyCal",
|
|
@@ -271,7 +332,7 @@ export const togetheraiService = defineApiKeyService({
|
|
|
271
332
|
})
|
|
272
333
|
|
|
273
334
|
export const trelloService = defineIntegrationService({
|
|
274
|
-
connectionMethods: [{ id: "
|
|
335
|
+
connectionMethods: [{ id: "oauth", name: "OAuth", type: "redirect" }],
|
|
275
336
|
description: "Connect a Trello account.",
|
|
276
337
|
id: "trello",
|
|
277
338
|
name: "Trello",
|
|
@@ -331,7 +392,9 @@ export const integrationCatalog = defineIntegrationCatalog([
|
|
|
331
392
|
asanaService,
|
|
332
393
|
brevoService,
|
|
333
394
|
cerebrasService,
|
|
395
|
+
chatgptService,
|
|
334
396
|
cloudflareService,
|
|
397
|
+
codexService,
|
|
335
398
|
cohereService,
|
|
336
399
|
deepinfraService,
|
|
337
400
|
deepseekService,
|
|
@@ -399,7 +462,7 @@ function defineApiKeyService<const TId extends string>(
|
|
|
399
462
|
placeholder: service.placeholder ?? "API key",
|
|
400
463
|
},
|
|
401
464
|
],
|
|
402
|
-
id: "
|
|
465
|
+
id: "api-key",
|
|
403
466
|
name: "API key",
|
|
404
467
|
type: "form",
|
|
405
468
|
},
|
package/src/index.ts
CHANGED
package/src/triggers/airtable.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { airtableService } from "../catalog"
|
|
2
1
|
import type { IntegrationAccountRequirement, TriggerDefinition } from "../types"
|
|
3
2
|
|
|
4
3
|
const AIRTABLE_ACCOUNT = {
|
|
@@ -12,7 +11,7 @@ const AIRTABLE_ACCOUNT = {
|
|
|
12
11
|
],
|
|
13
12
|
},
|
|
14
13
|
],
|
|
15
|
-
serviceId:
|
|
14
|
+
serviceId: "airtable",
|
|
16
15
|
} as const satisfies IntegrationAccountRequirement
|
|
17
16
|
|
|
18
17
|
export const airtableTriggerDefinitions = {
|
package/src/triggers/asana.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { asanaService } from "../catalog"
|
|
2
1
|
import type { IntegrationAccountRequirement, TriggerDefinition } from "../types"
|
|
3
2
|
|
|
4
3
|
const ASANA_ACCOUNT = {
|
|
@@ -7,7 +6,7 @@ const ASANA_ACCOUNT = {
|
|
|
7
6
|
requiredScopes: [],
|
|
8
7
|
},
|
|
9
8
|
],
|
|
10
|
-
serviceId:
|
|
9
|
+
serviceId: "asana",
|
|
11
10
|
} as const satisfies IntegrationAccountRequirement
|
|
12
11
|
|
|
13
12
|
export const asanaTriggerDefinitions = {
|
package/src/triggers/brevo.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { brevoService } from "../catalog"
|
|
2
1
|
import type { IntegrationAccountRequirement, TriggerDefinition } from "../types"
|
|
3
2
|
|
|
4
3
|
const BREVO_ACCOUNT = {
|
|
@@ -7,7 +6,7 @@ const BREVO_ACCOUNT = {
|
|
|
7
6
|
requiredScopes: [],
|
|
8
7
|
},
|
|
9
8
|
],
|
|
10
|
-
serviceId:
|
|
9
|
+
serviceId: "brevo",
|
|
11
10
|
} as const satisfies IntegrationAccountRequirement
|
|
12
11
|
|
|
13
12
|
export const brevoTriggerDefinitions = {
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import type { TriggerDefinition } from "../types"
|
|
2
|
+
import { sentenceCase } from "./name"
|
|
3
|
+
import * as z from "zod/mini"
|
|
4
|
+
|
|
5
|
+
const EMAIL_SCHEMA = z.email()
|
|
6
|
+
const URL_SCHEMA = z.url()
|
|
7
|
+
const FIELD_NAME_SCHEMA = z
|
|
8
|
+
.string()
|
|
9
|
+
.check(z.trim(), z.minLength(1), z.maxLength(100))
|
|
10
|
+
const FIELD_LABEL_SCHEMA = z
|
|
11
|
+
.string()
|
|
12
|
+
.check(z.trim(), z.minLength(1), z.maxLength(255))
|
|
13
|
+
const FIELD_DESCRIPTION_SCHEMA = z.string().check(z.maxLength(2_000))
|
|
14
|
+
const FIELD_LENGTH_SCHEMA = z.int().check(z.nonnegative())
|
|
15
|
+
const DASHBOARD_RUN_FIELD_BASE_SCHEMA = {
|
|
16
|
+
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
17
|
+
label: z.optional(FIELD_LABEL_SCHEMA),
|
|
18
|
+
name: FIELD_NAME_SCHEMA,
|
|
19
|
+
}
|
|
20
|
+
const DASHBOARD_RUN_TEXT_FIELD_SCHEMA = z.object({
|
|
21
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
22
|
+
defaultValue: z.optional(z.string()),
|
|
23
|
+
maxLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
24
|
+
minLength: z.optional(FIELD_LENGTH_SCHEMA),
|
|
25
|
+
placeholder: z.optional(z.string()),
|
|
26
|
+
required: z.prefault(z.boolean(), true),
|
|
27
|
+
type: z.enum(["email", "phone", "text", "textarea", "url"]),
|
|
28
|
+
})
|
|
29
|
+
const DASHBOARD_RUN_NUMBER_FIELD_SCHEMA = z.object({
|
|
30
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
31
|
+
defaultValue: z.optional(z.number()),
|
|
32
|
+
max: z.optional(z.number()),
|
|
33
|
+
min: z.optional(z.number()),
|
|
34
|
+
placeholder: z.optional(z.string()),
|
|
35
|
+
required: z.prefault(z.boolean(), true),
|
|
36
|
+
step: z.prefault(z.number().check(z.positive()), 1),
|
|
37
|
+
type: z.literal("number"),
|
|
38
|
+
})
|
|
39
|
+
const DASHBOARD_RUN_DATE_FIELD_SCHEMA = z.object({
|
|
40
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
41
|
+
defaultValue: z.optional(z.iso.date()),
|
|
42
|
+
max: z.optional(z.iso.date()),
|
|
43
|
+
min: z.optional(z.iso.date()),
|
|
44
|
+
required: z.prefault(z.boolean(), true),
|
|
45
|
+
step: z.prefault(z.int().check(z.positive()), 1),
|
|
46
|
+
type: z.literal("date"),
|
|
47
|
+
})
|
|
48
|
+
const DASHBOARD_RUN_DATETIME_FIELD_SCHEMA = z.object({
|
|
49
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
50
|
+
defaultValue: z.optional(z.iso.datetime({ local: true })),
|
|
51
|
+
max: z.optional(z.iso.datetime({ local: true })),
|
|
52
|
+
min: z.optional(z.iso.datetime({ local: true })),
|
|
53
|
+
required: z.prefault(z.boolean(), true),
|
|
54
|
+
step: z.prefault(z.number().check(z.positive()), 60),
|
|
55
|
+
type: z.literal("datetime"),
|
|
56
|
+
})
|
|
57
|
+
const DASHBOARD_RUN_CHOICE_FIELD_SCHEMA = {
|
|
58
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
59
|
+
defaultValue: z.optional(FIELD_NAME_SCHEMA),
|
|
60
|
+
options: z
|
|
61
|
+
.array(
|
|
62
|
+
z.object({
|
|
63
|
+
label: FIELD_LABEL_SCHEMA,
|
|
64
|
+
value: FIELD_NAME_SCHEMA,
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
.check(z.minLength(1)),
|
|
68
|
+
placeholder: z.optional(z.string()),
|
|
69
|
+
required: z.prefault(z.boolean(), true),
|
|
70
|
+
}
|
|
71
|
+
const DASHBOARD_RUN_SELECT_FIELD_SCHEMA = z.object({
|
|
72
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
73
|
+
type: z.literal("select"),
|
|
74
|
+
})
|
|
75
|
+
const DASHBOARD_RUN_RADIO_FIELD_SCHEMA = z.object({
|
|
76
|
+
...DASHBOARD_RUN_CHOICE_FIELD_SCHEMA,
|
|
77
|
+
type: z.literal("radio"),
|
|
78
|
+
})
|
|
79
|
+
const DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA = z.object({
|
|
80
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
81
|
+
defaultValue: z.optional(z.array(FIELD_NAME_SCHEMA)),
|
|
82
|
+
options: z
|
|
83
|
+
.array(
|
|
84
|
+
z.object({
|
|
85
|
+
label: FIELD_LABEL_SCHEMA,
|
|
86
|
+
value: FIELD_NAME_SCHEMA,
|
|
87
|
+
}),
|
|
88
|
+
)
|
|
89
|
+
.check(z.minLength(1)),
|
|
90
|
+
placeholder: z.optional(z.string()),
|
|
91
|
+
required: z.prefault(z.boolean(), true),
|
|
92
|
+
type: z.literal("multi-select"),
|
|
93
|
+
})
|
|
94
|
+
const DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA = z.object({
|
|
95
|
+
...DASHBOARD_RUN_FIELD_BASE_SCHEMA,
|
|
96
|
+
defaultValue: z.prefault(z.boolean(), false),
|
|
97
|
+
required: z.prefault(z.boolean(), false),
|
|
98
|
+
type: z.literal("checkbox"),
|
|
99
|
+
})
|
|
100
|
+
const DASHBOARD_RUN_FIELD_SCHEMA = z.pipe(
|
|
101
|
+
z.discriminatedUnion("type", [
|
|
102
|
+
DASHBOARD_RUN_TEXT_FIELD_SCHEMA,
|
|
103
|
+
DASHBOARD_RUN_NUMBER_FIELD_SCHEMA,
|
|
104
|
+
DASHBOARD_RUN_DATE_FIELD_SCHEMA,
|
|
105
|
+
DASHBOARD_RUN_DATETIME_FIELD_SCHEMA,
|
|
106
|
+
DASHBOARD_RUN_SELECT_FIELD_SCHEMA,
|
|
107
|
+
DASHBOARD_RUN_RADIO_FIELD_SCHEMA,
|
|
108
|
+
DASHBOARD_RUN_MULTI_SELECT_FIELD_SCHEMA,
|
|
109
|
+
DASHBOARD_RUN_CHECKBOX_FIELD_SCHEMA,
|
|
110
|
+
]),
|
|
111
|
+
z.transform((field) => ({
|
|
112
|
+
...field,
|
|
113
|
+
label:
|
|
114
|
+
field.label ??
|
|
115
|
+
`${sentenceCase(field.name)}${field.type === "checkbox" ? "?" : ""}`,
|
|
116
|
+
})),
|
|
117
|
+
)
|
|
118
|
+
const DASHBOARD_RUN_FIELDS_SCHEMA = z.array(DASHBOARD_RUN_FIELD_SCHEMA).check(
|
|
119
|
+
z.refine(
|
|
120
|
+
(fields) =>
|
|
121
|
+
new Set(fields.map((field) => field.name)).size === fields.length,
|
|
122
|
+
"Dashboard run field names must be unique.",
|
|
123
|
+
),
|
|
124
|
+
z.refine(
|
|
125
|
+
(fields) => fields.every(isDashboardRunFieldDefaultValid),
|
|
126
|
+
"Dashboard run field defaults must satisfy their field constraints.",
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
export const DASHBOARD_RUN_CONFIG_SCHEMA = z.object({
|
|
131
|
+
description: z.optional(FIELD_DESCRIPTION_SCHEMA),
|
|
132
|
+
fields: z.prefault(DASHBOARD_RUN_FIELDS_SCHEMA, []),
|
|
133
|
+
submitLabel: z.prefault(
|
|
134
|
+
z.string().check(z.trim(), z.minLength(1), z.maxLength(100)),
|
|
135
|
+
"Run",
|
|
136
|
+
),
|
|
137
|
+
title: z.string().check(z.trim(), z.minLength(1), z.maxLength(255)),
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
export const dashboardRunTriggerDefinition = {
|
|
141
|
+
getDetails: ({ config }) => [
|
|
142
|
+
{
|
|
143
|
+
label: "Run form",
|
|
144
|
+
value: DASHBOARD_RUN_CONFIG_SCHEMA.parse(config).title,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
icon: "automation",
|
|
148
|
+
name: "Dashboard run",
|
|
149
|
+
type: "dashboard.run",
|
|
150
|
+
} as const satisfies TriggerDefinition
|
|
151
|
+
|
|
152
|
+
interface DashboardRunFieldBase {
|
|
153
|
+
/** Supporting text shown below the field. */
|
|
154
|
+
description?: string
|
|
155
|
+
|
|
156
|
+
/** Visible field label. Inferred from `name` when omitted. */
|
|
157
|
+
label?: string
|
|
158
|
+
|
|
159
|
+
/** Property name used in submitted trigger data. */
|
|
160
|
+
name: string
|
|
161
|
+
|
|
162
|
+
/** Whether the form must contain a value. Defaults to true. */
|
|
163
|
+
required?: boolean
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export type DashboardRunField =
|
|
167
|
+
| (DashboardRunFieldBase & {
|
|
168
|
+
defaultValue?: string
|
|
169
|
+
maxLength?: number
|
|
170
|
+
minLength?: number
|
|
171
|
+
placeholder?: string
|
|
172
|
+
type: "email" | "phone" | "text" | "textarea" | "url"
|
|
173
|
+
})
|
|
174
|
+
| (DashboardRunFieldBase & {
|
|
175
|
+
defaultValue?: number
|
|
176
|
+
max?: number
|
|
177
|
+
min?: number
|
|
178
|
+
placeholder?: string
|
|
179
|
+
|
|
180
|
+
/** Increment used by the number input. Defaults to 1. */
|
|
181
|
+
step?: number
|
|
182
|
+
type: "number"
|
|
183
|
+
})
|
|
184
|
+
| (DashboardRunFieldBase & {
|
|
185
|
+
/** Initial local date in `YYYY-MM-DD` format. */
|
|
186
|
+
defaultValue?: string
|
|
187
|
+
max?: string
|
|
188
|
+
min?: string
|
|
189
|
+
|
|
190
|
+
/** Allowed increment in days. Defaults to 1. */
|
|
191
|
+
step?: number
|
|
192
|
+
type: "date"
|
|
193
|
+
})
|
|
194
|
+
| (DashboardRunFieldBase & {
|
|
195
|
+
/** Initial local date and time in `YYYY-MM-DDTHH:mm` format. */
|
|
196
|
+
defaultValue?: string
|
|
197
|
+
max?: string
|
|
198
|
+
min?: string
|
|
199
|
+
|
|
200
|
+
/** Allowed increment in seconds. Defaults to 60. */
|
|
201
|
+
step?: number
|
|
202
|
+
type: "datetime"
|
|
203
|
+
})
|
|
204
|
+
| (DashboardRunFieldBase & {
|
|
205
|
+
defaultValue?: string
|
|
206
|
+
options: readonly { label: string; value: string }[]
|
|
207
|
+
placeholder?: string
|
|
208
|
+
type: "select"
|
|
209
|
+
})
|
|
210
|
+
| (DashboardRunFieldBase & {
|
|
211
|
+
defaultValue?: string
|
|
212
|
+
options: readonly { label: string; value: string }[]
|
|
213
|
+
type: "radio"
|
|
214
|
+
})
|
|
215
|
+
| (DashboardRunFieldBase & {
|
|
216
|
+
defaultValue?: readonly string[]
|
|
217
|
+
options: readonly { label: string; value: string }[]
|
|
218
|
+
placeholder?: string
|
|
219
|
+
type: "multi-select"
|
|
220
|
+
})
|
|
221
|
+
| (DashboardRunFieldBase & {
|
|
222
|
+
/** Initial checked state. Defaults to false. */
|
|
223
|
+
defaultValue?: boolean
|
|
224
|
+
|
|
225
|
+
/** Whether the checkbox must be checked. Defaults to false. */
|
|
226
|
+
required?: boolean
|
|
227
|
+
type: "checkbox"
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
export interface DashboardRunConfig<
|
|
231
|
+
TFields extends readonly DashboardRunField[] = readonly DashboardRunField[],
|
|
232
|
+
> {
|
|
233
|
+
/** Supporting text shown below the form title. */
|
|
234
|
+
description?: string
|
|
235
|
+
|
|
236
|
+
/** Ordered fields. Omit to run immediately. */
|
|
237
|
+
fields?: TFields
|
|
238
|
+
|
|
239
|
+
/** Submit button text. Defaults to "Run". */
|
|
240
|
+
submitLabel?: string
|
|
241
|
+
|
|
242
|
+
/** Form heading. */
|
|
243
|
+
title: string
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface DashboardRunEndpointOptions {
|
|
247
|
+
appOrigin: string
|
|
248
|
+
automationId: string
|
|
249
|
+
hookSlot: number
|
|
250
|
+
scopePath?: readonly number[]
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Returns the organization-authenticated submission endpoint for one dashboard
|
|
255
|
+
* run.
|
|
256
|
+
*
|
|
257
|
+
* @param options - Public origin and trigger identity.
|
|
258
|
+
*/
|
|
259
|
+
export function getDashboardRunEndpoint(options: DashboardRunEndpointOptions) {
|
|
260
|
+
return new URL(
|
|
261
|
+
`/api/dashboard-runs/${getDashboardRunEndpointKey(options)}`,
|
|
262
|
+
options.appOrigin,
|
|
263
|
+
).toString()
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Returns the durable endpoint identity for one dashboard run trigger.
|
|
268
|
+
*
|
|
269
|
+
* @param options - Trigger and owning automation identity.
|
|
270
|
+
*/
|
|
271
|
+
export function getDashboardRunEndpointKey(
|
|
272
|
+
options: Omit<DashboardRunEndpointOptions, "appOrigin">,
|
|
273
|
+
) {
|
|
274
|
+
return `${options.automationId}:${[
|
|
275
|
+
...(options.scopePath ?? []),
|
|
276
|
+
options.hookSlot,
|
|
277
|
+
].join(".")}`
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Checks a configured default against the same constraints as submitted data.
|
|
282
|
+
*
|
|
283
|
+
* @param field - Field definition to validate.
|
|
284
|
+
*/
|
|
285
|
+
function isDashboardRunFieldDefaultValid(field: DashboardRunField) {
|
|
286
|
+
if (field.type === "checkbox" || field.defaultValue === undefined) return true
|
|
287
|
+
|
|
288
|
+
if (field.type === "multi-select") {
|
|
289
|
+
if (field.required !== false && field.defaultValue.length === 0)
|
|
290
|
+
return false
|
|
291
|
+
return field.defaultValue.every((value) =>
|
|
292
|
+
field.options.some((option) => option.value === value),
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (field.type === "radio" || field.type === "select") {
|
|
297
|
+
return field.options.some((option) => option.value === field.defaultValue)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (field.type === "number") {
|
|
301
|
+
return (
|
|
302
|
+
(field.min === undefined || field.defaultValue >= field.min) &&
|
|
303
|
+
(field.max === undefined || field.defaultValue <= field.max) &&
|
|
304
|
+
!isDashboardRunStepMismatch(
|
|
305
|
+
field.defaultValue,
|
|
306
|
+
field.min ?? field.defaultValue,
|
|
307
|
+
field.step ?? 1,
|
|
308
|
+
)
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (field.type === "date" || field.type === "datetime") {
|
|
313
|
+
const defaultValue = parseDashboardRunDateValue(
|
|
314
|
+
field.type,
|
|
315
|
+
field.defaultValue,
|
|
316
|
+
)
|
|
317
|
+
return (
|
|
318
|
+
(field.min === undefined ||
|
|
319
|
+
defaultValue >= parseDashboardRunDateValue(field.type, field.min)) &&
|
|
320
|
+
(field.max === undefined ||
|
|
321
|
+
defaultValue <= parseDashboardRunDateValue(field.type, field.max)) &&
|
|
322
|
+
!isDashboardRunStepMismatch(
|
|
323
|
+
defaultValue,
|
|
324
|
+
parseDashboardRunDateValue(field.type, field.min ?? field.defaultValue),
|
|
325
|
+
(field.step ?? (field.type === "date" ? 1 : 60)) *
|
|
326
|
+
(field.type === "date" ? 86_400_000 : 1_000),
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const defaultValue = field.defaultValue.trim()
|
|
332
|
+
return (
|
|
333
|
+
(defaultValue.length > 0 || field.required === false) &&
|
|
334
|
+
(field.minLength === undefined || defaultValue.length >= field.minLength) &&
|
|
335
|
+
(field.maxLength === undefined || defaultValue.length <= field.maxLength) &&
|
|
336
|
+
(field.type !== "email" || EMAIL_SCHEMA.safeParse(defaultValue).success) &&
|
|
337
|
+
(field.type !== "url" || URL_SCHEMA.safeParse(defaultValue).success)
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Checks whether a value falls outside an allowed step interval.
|
|
343
|
+
*
|
|
344
|
+
* @param value - Configured default value.
|
|
345
|
+
* @param base - Value from which step intervals begin.
|
|
346
|
+
* @param step - Allowed interval size.
|
|
347
|
+
*/
|
|
348
|
+
function isDashboardRunStepMismatch(value: number, base: number, step: number) {
|
|
349
|
+
const intervals = (value - base) / step
|
|
350
|
+
return Math.abs(intervals - Math.round(intervals)) > 1e-9
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Converts a validated local date or date-time string to a UTC number.
|
|
355
|
+
*
|
|
356
|
+
* @param type - Temporal field type.
|
|
357
|
+
* @param value - Local ISO value to convert.
|
|
358
|
+
*/
|
|
359
|
+
function parseDashboardRunDateValue(type: "date" | "datetime", value: string) {
|
|
360
|
+
return Date.parse(type === "date" ? `${value}T00:00:00Z` : `${value}Z`)
|
|
361
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { TriggerDefinition } from "../types"
|
|
2
|
+
import * as z from "zod/mini"
|
|
3
|
+
|
|
4
|
+
const HTTP_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
5
|
+
scope: z.prefault(z.enum(["trigger", "automation", "project"]), "trigger"),
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
export const httpRequestTriggerDefinition = {
|
|
9
|
+
getPrimary: ({
|
|
10
|
+
appOrigin,
|
|
11
|
+
automationId,
|
|
12
|
+
config,
|
|
13
|
+
hookSlot,
|
|
14
|
+
projectId,
|
|
15
|
+
scopePath,
|
|
16
|
+
}) => ({
|
|
17
|
+
copyable: true,
|
|
18
|
+
value: getHttpTriggerEndpoint({
|
|
19
|
+
appOrigin,
|
|
20
|
+
automationId,
|
|
21
|
+
hookSlot,
|
|
22
|
+
projectId,
|
|
23
|
+
scope: HTTP_PRESENTATION_CONFIG_SCHEMA.parse(config).scope,
|
|
24
|
+
scopePath,
|
|
25
|
+
}),
|
|
26
|
+
}),
|
|
27
|
+
icon: "webhook",
|
|
28
|
+
name: "HTTP request",
|
|
29
|
+
type: "http.request",
|
|
30
|
+
} as const satisfies TriggerDefinition
|
|
31
|
+
|
|
32
|
+
export type HttpTriggerScope = "trigger" | "automation" | "project"
|
|
33
|
+
|
|
34
|
+
export interface HttpTriggerEndpointOptions {
|
|
35
|
+
appOrigin: string
|
|
36
|
+
automationId: string
|
|
37
|
+
hookSlot: number
|
|
38
|
+
projectId: string
|
|
39
|
+
scope: HttpTriggerScope
|
|
40
|
+
scopePath?: readonly number[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns the public URL for one deployed HTTP trigger.
|
|
45
|
+
*
|
|
46
|
+
* @param options - Public origin and trigger identity.
|
|
47
|
+
*/
|
|
48
|
+
export function getHttpTriggerEndpoint(options: HttpTriggerEndpointOptions) {
|
|
49
|
+
return new URL(
|
|
50
|
+
`/x/${getHttpTriggerEndpointKey(options)}/`,
|
|
51
|
+
options.appOrigin,
|
|
52
|
+
).toString()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the durable endpoint identity for one configured HTTP scope.
|
|
57
|
+
*
|
|
58
|
+
* @param options - Trigger and owning resource identity.
|
|
59
|
+
*/
|
|
60
|
+
export function getHttpTriggerEndpointKey(
|
|
61
|
+
options: Omit<HttpTriggerEndpointOptions, "appOrigin">,
|
|
62
|
+
) {
|
|
63
|
+
if (options.scope === "project") return options.projectId
|
|
64
|
+
if (options.scope === "automation") return options.automationId
|
|
65
|
+
return `${options.automationId}:${[
|
|
66
|
+
...(options.scopePath ?? []),
|
|
67
|
+
options.hookSlot,
|
|
68
|
+
].join(".")}`
|
|
69
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TriggerDefinition } from "../types"
|
|
2
|
+
import * as z from "zod/mini"
|
|
3
|
+
|
|
4
|
+
const INVOCATION_PRESENTATION_CONFIG_SCHEMA = z.object({
|
|
5
|
+
entrypoint: z.string(),
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
export const automationInvokedTriggerDefinition = {
|
|
9
|
+
getDetails: ({ config }) => [
|
|
10
|
+
{
|
|
11
|
+
label: "Entrypoint",
|
|
12
|
+
value: INVOCATION_PRESENTATION_CONFIG_SCHEMA.parse(config).entrypoint,
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
icon: "automation",
|
|
16
|
+
name: "Invocation",
|
|
17
|
+
type: "automation.invoked",
|
|
18
|
+
} as const satisfies TriggerDefinition
|