@trigger.dev/sdk 3.3.17 → 4.0.0-v4-beta.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.
Files changed (233) hide show
  1. package/dist/commonjs/v3/ai.d.ts +23 -0
  2. package/dist/commonjs/v3/ai.js +50 -0
  3. package/dist/commonjs/v3/ai.js.map +1 -0
  4. package/dist/commonjs/v3/auth.d.ts +4 -3
  5. package/dist/commonjs/v3/auth.js.map +1 -1
  6. package/dist/commonjs/v3/hooks.d.ts +22 -0
  7. package/dist/commonjs/v3/hooks.js +65 -0
  8. package/dist/commonjs/v3/hooks.js.map +1 -0
  9. package/dist/commonjs/v3/index.d.ts +3 -1
  10. package/dist/commonjs/v3/index.js +4 -1
  11. package/dist/commonjs/v3/index.js.map +1 -1
  12. package/dist/commonjs/v3/locals.d.ts +3 -0
  13. package/dist/commonjs/v3/locals.js +6 -0
  14. package/dist/commonjs/v3/locals.js.map +1 -0
  15. package/dist/commonjs/v3/queues.d.ts +61 -0
  16. package/dist/commonjs/v3/queues.js +137 -0
  17. package/dist/commonjs/v3/queues.js.map +1 -0
  18. package/dist/commonjs/v3/retry.js +10 -7
  19. package/dist/commonjs/v3/retry.js.map +1 -1
  20. package/dist/commonjs/v3/runs.d.ts +40 -40
  21. package/dist/commonjs/v3/schedules/index.js +1 -1
  22. package/dist/commonjs/v3/schedules/index.js.map +1 -1
  23. package/dist/commonjs/v3/shared.d.ts +7 -6
  24. package/dist/commonjs/v3/shared.js +188 -176
  25. package/dist/commonjs/v3/shared.js.map +1 -1
  26. package/dist/commonjs/v3/tasks.d.ts +12 -0
  27. package/dist/commonjs/v3/tasks.js +11 -0
  28. package/dist/commonjs/v3/tasks.js.map +1 -1
  29. package/dist/commonjs/v3/wait.d.ts +208 -3
  30. package/dist/commonjs/v3/wait.js +407 -7
  31. package/dist/commonjs/v3/wait.js.map +1 -1
  32. package/dist/commonjs/version.js +1 -1
  33. package/dist/esm/v3/ai.d.ts +23 -0
  34. package/dist/esm/v3/ai.js +47 -0
  35. package/dist/esm/v3/ai.js.map +1 -0
  36. package/dist/esm/v3/auth.d.ts +4 -3
  37. package/dist/esm/v3/auth.js.map +1 -1
  38. package/dist/esm/v3/hooks.d.ts +22 -0
  39. package/dist/esm/v3/hooks.js +54 -0
  40. package/dist/esm/v3/hooks.js.map +1 -0
  41. package/dist/esm/v3/index.d.ts +3 -1
  42. package/dist/esm/v3/index.js +3 -1
  43. package/dist/esm/v3/index.js.map +1 -1
  44. package/dist/esm/v3/locals.d.ts +3 -0
  45. package/dist/esm/v3/locals.js +3 -0
  46. package/dist/esm/v3/locals.js.map +1 -0
  47. package/dist/esm/v3/queues.d.ts +61 -0
  48. package/dist/esm/v3/queues.js +131 -0
  49. package/dist/esm/v3/queues.js.map +1 -0
  50. package/dist/esm/v3/retry.js +11 -8
  51. package/dist/esm/v3/retry.js.map +1 -1
  52. package/dist/esm/v3/runs.d.ts +39 -39
  53. package/dist/esm/v3/schedules/index.js +2 -2
  54. package/dist/esm/v3/schedules/index.js.map +1 -1
  55. package/dist/esm/v3/shared.d.ts +7 -6
  56. package/dist/esm/v3/shared.js +189 -177
  57. package/dist/esm/v3/shared.js.map +1 -1
  58. package/dist/esm/v3/tasks.d.ts +12 -0
  59. package/dist/esm/v3/tasks.js +11 -0
  60. package/dist/esm/v3/tasks.js.map +1 -1
  61. package/dist/esm/v3/wait.d.ts +208 -3
  62. package/dist/esm/v3/wait.js +406 -7
  63. package/dist/esm/v3/wait.js.map +1 -1
  64. package/dist/esm/version.js +1 -1
  65. package/package.json +36 -17
  66. package/dist/commonjs/apiClient.d.ts +0 -727
  67. package/dist/commonjs/apiClient.js +0 -692
  68. package/dist/commonjs/apiClient.js.map +0 -1
  69. package/dist/commonjs/concurrencyLimit.d.ts +0 -10
  70. package/dist/commonjs/concurrencyLimit.js +0 -17
  71. package/dist/commonjs/concurrencyLimit.js.map +0 -1
  72. package/dist/commonjs/errors.d.ts +0 -66
  73. package/dist/commonjs/errors.js +0 -109
  74. package/dist/commonjs/errors.js.map +0 -1
  75. package/dist/commonjs/httpEndpoint.d.ts +0 -87
  76. package/dist/commonjs/httpEndpoint.js +0 -130
  77. package/dist/commonjs/httpEndpoint.js.map +0 -1
  78. package/dist/commonjs/index.d.ts +0 -23
  79. package/dist/commonjs/index.js +0 -55
  80. package/dist/commonjs/index.js.map +0 -1
  81. package/dist/commonjs/integrations.d.ts +0 -11
  82. package/dist/commonjs/integrations.js +0 -3
  83. package/dist/commonjs/integrations.js.map +0 -1
  84. package/dist/commonjs/io.d.ts +0 -441
  85. package/dist/commonjs/io.js +0 -1165
  86. package/dist/commonjs/io.js.map +0 -1
  87. package/dist/commonjs/ioWithIntegrations.d.ts +0 -4
  88. package/dist/commonjs/ioWithIntegrations.js +0 -32
  89. package/dist/commonjs/ioWithIntegrations.js.map +0 -1
  90. package/dist/commonjs/job.d.ts +0 -96
  91. package/dist/commonjs/job.js +0 -210
  92. package/dist/commonjs/job.js.map +0 -1
  93. package/dist/commonjs/retry.d.ts +0 -20
  94. package/dist/commonjs/retry.js +0 -22
  95. package/dist/commonjs/retry.js.map +0 -1
  96. package/dist/commonjs/runLocalStorage.d.ts +0 -8
  97. package/dist/commonjs/runLocalStorage.js +0 -6
  98. package/dist/commonjs/runLocalStorage.js.map +0 -1
  99. package/dist/commonjs/security.d.ts +0 -18
  100. package/dist/commonjs/security.js +0 -41
  101. package/dist/commonjs/security.js.map +0 -1
  102. package/dist/commonjs/status.d.ts +0 -19
  103. package/dist/commonjs/status.js +0 -38
  104. package/dist/commonjs/status.js.map +0 -1
  105. package/dist/commonjs/store/keyValueStore.d.ts +0 -17
  106. package/dist/commonjs/store/keyValueStore.js +0 -138
  107. package/dist/commonjs/store/keyValueStore.js.map +0 -1
  108. package/dist/commonjs/store/keyValueStoreClient.d.ts +0 -19
  109. package/dist/commonjs/store/keyValueStoreClient.js +0 -65
  110. package/dist/commonjs/store/keyValueStoreClient.js.map +0 -1
  111. package/dist/commonjs/triggerClient.d.ts +0 -290
  112. package/dist/commonjs/triggerClient.js +0 -1366
  113. package/dist/commonjs/triggerClient.js.map +0 -1
  114. package/dist/commonjs/triggers/dynamic.d.ts +0 -56
  115. package/dist/commonjs/triggers/dynamic.js +0 -97
  116. package/dist/commonjs/triggers/dynamic.js.map +0 -1
  117. package/dist/commonjs/triggers/eventTrigger.d.ts +0 -58
  118. package/dist/commonjs/triggers/eventTrigger.js +0 -69
  119. package/dist/commonjs/triggers/eventTrigger.js.map +0 -1
  120. package/dist/commonjs/triggers/externalSource.d.ts +0 -148
  121. package/dist/commonjs/triggers/externalSource.js +0 -106
  122. package/dist/commonjs/triggers/externalSource.js.map +0 -1
  123. package/dist/commonjs/triggers/invokeTrigger.d.ts +0 -39
  124. package/dist/commonjs/triggers/invokeTrigger.js +0 -58
  125. package/dist/commonjs/triggers/invokeTrigger.js.map +0 -1
  126. package/dist/commonjs/triggers/notifications.d.ts +0 -111
  127. package/dist/commonjs/triggers/notifications.js +0 -101
  128. package/dist/commonjs/triggers/notifications.js.map +0 -1
  129. package/dist/commonjs/triggers/scheduled.d.ts +0 -145
  130. package/dist/commonjs/triggers/scheduled.js +0 -208
  131. package/dist/commonjs/triggers/scheduled.js.map +0 -1
  132. package/dist/commonjs/triggers/webhook.d.ts +0 -143
  133. package/dist/commonjs/triggers/webhook.js +0 -133
  134. package/dist/commonjs/triggers/webhook.js.map +0 -1
  135. package/dist/commonjs/typed-emitter.d.ts +0 -37
  136. package/dist/commonjs/typed-emitter.js +0 -3
  137. package/dist/commonjs/typed-emitter.js.map +0 -1
  138. package/dist/commonjs/types.d.ts +0 -204
  139. package/dist/commonjs/types.js +0 -23
  140. package/dist/commonjs/types.js.map +0 -1
  141. package/dist/commonjs/utils/formatSchemaErrors.d.ts +0 -3
  142. package/dist/commonjs/utils/formatSchemaErrors.js +0 -10
  143. package/dist/commonjs/utils/formatSchemaErrors.js.map +0 -1
  144. package/dist/commonjs/utils/typedAsyncLocalStorage.d.ts +0 -6
  145. package/dist/commonjs/utils/typedAsyncLocalStorage.js +0 -18
  146. package/dist/commonjs/utils/typedAsyncLocalStorage.js.map +0 -1
  147. package/dist/commonjs/utils.d.ts +0 -1
  148. package/dist/commonjs/utils.js +0 -11
  149. package/dist/commonjs/utils.js.map +0 -1
  150. package/dist/esm/apiClient.d.ts +0 -727
  151. package/dist/esm/apiClient.js +0 -687
  152. package/dist/esm/apiClient.js.map +0 -1
  153. package/dist/esm/concurrencyLimit.d.ts +0 -10
  154. package/dist/esm/concurrencyLimit.js +0 -13
  155. package/dist/esm/concurrencyLimit.js.map +0 -1
  156. package/dist/esm/errors.d.ts +0 -66
  157. package/dist/esm/errors.js +0 -95
  158. package/dist/esm/errors.js.map +0 -1
  159. package/dist/esm/httpEndpoint.d.ts +0 -87
  160. package/dist/esm/httpEndpoint.js +0 -125
  161. package/dist/esm/httpEndpoint.js.map +0 -1
  162. package/dist/esm/index.d.ts +0 -23
  163. package/dist/esm/index.js +0 -35
  164. package/dist/esm/index.js.map +0 -1
  165. package/dist/esm/integrations.d.ts +0 -11
  166. package/dist/esm/integrations.js +0 -2
  167. package/dist/esm/integrations.js.map +0 -1
  168. package/dist/esm/io.d.ts +0 -441
  169. package/dist/esm/io.js +0 -1159
  170. package/dist/esm/io.js.map +0 -1
  171. package/dist/esm/ioWithIntegrations.d.ts +0 -4
  172. package/dist/esm/ioWithIntegrations.js +0 -29
  173. package/dist/esm/ioWithIntegrations.js.map +0 -1
  174. package/dist/esm/job.d.ts +0 -96
  175. package/dist/esm/job.js +0 -206
  176. package/dist/esm/job.js.map +0 -1
  177. package/dist/esm/retry.d.ts +0 -20
  178. package/dist/esm/retry.js +0 -19
  179. package/dist/esm/retry.js.map +0 -1
  180. package/dist/esm/runLocalStorage.d.ts +0 -8
  181. package/dist/esm/runLocalStorage.js +0 -3
  182. package/dist/esm/runLocalStorage.js.map +0 -1
  183. package/dist/esm/security.d.ts +0 -18
  184. package/dist/esm/security.js +0 -34
  185. package/dist/esm/security.js.map +0 -1
  186. package/dist/esm/status.d.ts +0 -19
  187. package/dist/esm/status.js +0 -34
  188. package/dist/esm/status.js.map +0 -1
  189. package/dist/esm/store/keyValueStore.d.ts +0 -17
  190. package/dist/esm/store/keyValueStore.js +0 -134
  191. package/dist/esm/store/keyValueStore.js.map +0 -1
  192. package/dist/esm/store/keyValueStoreClient.d.ts +0 -19
  193. package/dist/esm/store/keyValueStoreClient.js +0 -61
  194. package/dist/esm/store/keyValueStoreClient.js.map +0 -1
  195. package/dist/esm/triggerClient.d.ts +0 -288
  196. package/dist/esm/triggerClient.js +0 -1359
  197. package/dist/esm/triggerClient.js.map +0 -1
  198. package/dist/esm/triggers/dynamic.d.ts +0 -56
  199. package/dist/esm/triggers/dynamic.js +0 -93
  200. package/dist/esm/triggers/dynamic.js.map +0 -1
  201. package/dist/esm/triggers/eventTrigger.d.ts +0 -58
  202. package/dist/esm/triggers/eventTrigger.js +0 -64
  203. package/dist/esm/triggers/eventTrigger.js.map +0 -1
  204. package/dist/esm/triggers/externalSource.d.ts +0 -148
  205. package/dist/esm/triggers/externalSource.js +0 -100
  206. package/dist/esm/triggers/externalSource.js.map +0 -1
  207. package/dist/esm/triggers/invokeTrigger.d.ts +0 -39
  208. package/dist/esm/triggers/invokeTrigger.js +0 -53
  209. package/dist/esm/triggers/invokeTrigger.js.map +0 -1
  210. package/dist/esm/triggers/notifications.d.ts +0 -111
  211. package/dist/esm/triggers/notifications.js +0 -94
  212. package/dist/esm/triggers/notifications.js.map +0 -1
  213. package/dist/esm/triggers/scheduled.d.ts +0 -145
  214. package/dist/esm/triggers/scheduled.js +0 -197
  215. package/dist/esm/triggers/scheduled.js.map +0 -1
  216. package/dist/esm/triggers/webhook.d.ts +0 -143
  217. package/dist/esm/triggers/webhook.js +0 -128
  218. package/dist/esm/triggers/webhook.js.map +0 -1
  219. package/dist/esm/typed-emitter.d.ts +0 -37
  220. package/dist/esm/typed-emitter.js +0 -2
  221. package/dist/esm/typed-emitter.js.map +0 -1
  222. package/dist/esm/types.d.ts +0 -204
  223. package/dist/esm/types.js +0 -19
  224. package/dist/esm/types.js.map +0 -1
  225. package/dist/esm/utils/formatSchemaErrors.d.ts +0 -3
  226. package/dist/esm/utils/formatSchemaErrors.js +0 -7
  227. package/dist/esm/utils/formatSchemaErrors.js.map +0 -1
  228. package/dist/esm/utils/typedAsyncLocalStorage.d.ts +0 -6
  229. package/dist/esm/utils/typedAsyncLocalStorage.js +0 -14
  230. package/dist/esm/utils/typedAsyncLocalStorage.js.map +0 -1
  231. package/dist/esm/utils.d.ts +0 -1
  232. package/dist/esm/utils.js +0 -8
  233. package/dist/esm/utils.js.map +0 -1
@@ -1,1359 +0,0 @@
1
- import { API_VERSIONS, ErrorWithStackSchema, HttpEndpointRequestHeadersSchema, HttpSourceRequestHeadersSchema, InitializeTriggerBodySchema, PreprocessRunBodySchema, REGISTER_SOURCE_EVENT_V2, REGISTER_WEBHOOK, RegisterSourceEventSchemaV2, RegisterWebhookPayloadSchema, RequestWithRawBodySchema, RunJobBodySchema, WebhookSourceRequestHeadersSchema, } from "@trigger.dev/core";
2
- import { Logger } from "@trigger.dev/core/logger";
3
- import EventEmitter from "node:events";
4
- import { env } from "node:process";
5
- import { ApiClient } from "./apiClient.js";
6
- import { ConcurrencyLimit } from "./concurrencyLimit.js";
7
- import { AutoYieldExecutionError, AutoYieldRateLimitError, AutoYieldWithCompletedTaskExecutionError, CanceledWithTaskError, ErrorWithTask, ParsedPayloadSchemaError, ResumeWithParallelTaskError, ResumeWithTaskError, RetryWithTaskError, YieldExecutionError, } from "./errors.js";
8
- import { httpEndpoint } from "./httpEndpoint.js";
9
- import { IO } from "./io.js";
10
- import { createIOWithIntegrations } from "./ioWithIntegrations.js";
11
- import { Job } from "./job.js";
12
- import { runLocalStorage } from "./runLocalStorage.js";
13
- import { KeyValueStore } from "./store/keyValueStore.js";
14
- import { DynamicTrigger } from "./triggers/dynamic.js";
15
- import { EventTrigger } from "./triggers/eventTrigger.js";
16
- import { DynamicSchedule } from "./triggers/scheduled.js";
17
- import { formatSchemaErrors } from "./utils/formatSchemaErrors.js";
18
- import { VERSION } from "./version.js";
19
- const parseRequestPayload = (rawPayload) => {
20
- const result = RequestWithRawBodySchema.safeParse(rawPayload);
21
- if (!result.success) {
22
- throw new ParsedPayloadSchemaError(formatSchemaErrors(result.error.issues));
23
- }
24
- return new Request(new URL(result.data.url), {
25
- method: result.data.method,
26
- headers: result.data.headers,
27
- body: result.data.rawBody,
28
- });
29
- };
30
- const registerWebhookEvent = (key) => ({
31
- name: `${REGISTER_WEBHOOK}.${key}`,
32
- title: "Register Webhook",
33
- source: "internal",
34
- icon: "webhook",
35
- parsePayload: RegisterWebhookPayloadSchema.parse,
36
- });
37
- const registerSourceEvent = {
38
- name: REGISTER_SOURCE_EVENT_V2,
39
- title: "Register Source",
40
- source: "internal",
41
- icon: "register-source",
42
- parsePayload: RegisterSourceEventSchemaV2.parse,
43
- };
44
- /** A [TriggerClient](https://trigger.dev/docs/documentation/concepts/client-adaptors) is used to connect to a specific [Project](https://trigger.dev/docs/documentation/concepts/projects) by using an [API Key](https://trigger.dev/docs/documentation/concepts/environments-apikeys). */
45
- export class TriggerClient {
46
- #options;
47
- #registeredJobs = {};
48
- #registeredSources = {};
49
- #registeredWebhooks = {};
50
- #registeredHttpSourceHandlers = {};
51
- #registeredWebhookSourceHandlers = {};
52
- #registeredDynamicTriggers = {};
53
- #jobMetadataByDynamicTriggers = {};
54
- #registeredSchedules = {};
55
- #registeredHttpEndpoints = {};
56
- #authResolvers = {};
57
- #envStore;
58
- #eventEmitter = new EventEmitter();
59
- #client;
60
- #internalLogger;
61
- id;
62
- constructor(options) {
63
- this.id = options.id;
64
- this.#options = options;
65
- this.#internalLogger = new Logger("trigger.dev", this.#options.verbose ? "debug" : "log", [
66
- "output",
67
- "noopTasksSet",
68
- ]);
69
- this.#client = new ApiClient({
70
- logLevel: this.#options.verbose ? "debug" : "log",
71
- ...this.#options,
72
- });
73
- this.#envStore = new KeyValueStore(this.#client);
74
- }
75
- on = this.#eventEmitter.on.bind(this.#eventEmitter);
76
- async handleRequest(request, timeOrigin = performance.now()) {
77
- this.#internalLogger.debug("handling request", {
78
- url: request.url,
79
- headers: Object.fromEntries(request.headers.entries()),
80
- method: request.method,
81
- });
82
- const apiKey = request.headers.get("x-trigger-api-key");
83
- const triggerVersion = request.headers.get("x-trigger-version");
84
- const authorization = this.authorized(apiKey);
85
- switch (authorization) {
86
- case "authorized": {
87
- break;
88
- }
89
- case "missing-client": {
90
- return {
91
- status: 401,
92
- body: {
93
- message: "Unauthorized: client missing apiKey",
94
- },
95
- headers: this.#standardResponseHeaders(timeOrigin),
96
- };
97
- }
98
- case "missing-header": {
99
- return {
100
- status: 401,
101
- body: {
102
- message: "Unauthorized: missing x-trigger-api-key header",
103
- },
104
- headers: this.#standardResponseHeaders(timeOrigin),
105
- };
106
- }
107
- case "unauthorized": {
108
- return {
109
- status: 401,
110
- body: {
111
- message: `Forbidden: client apiKey mismatch: Make sure you are using the correct API Key for your environment`,
112
- },
113
- headers: this.#standardResponseHeaders(timeOrigin),
114
- };
115
- }
116
- }
117
- if (request.method !== "POST") {
118
- return {
119
- status: 405,
120
- body: {
121
- message: "Method not allowed (only POST is allowed)",
122
- },
123
- headers: this.#standardResponseHeaders(timeOrigin),
124
- };
125
- }
126
- const action = request.headers.get("x-trigger-action");
127
- if (!action) {
128
- return {
129
- status: 400,
130
- body: {
131
- message: "Missing x-trigger-action header",
132
- },
133
- headers: this.#standardResponseHeaders(timeOrigin),
134
- };
135
- }
136
- switch (action) {
137
- case "PING": {
138
- const endpointId = request.headers.get("x-trigger-endpoint-id");
139
- if (!endpointId) {
140
- return {
141
- status: 200,
142
- body: {
143
- ok: false,
144
- error: "Missing endpoint ID",
145
- },
146
- headers: this.#standardResponseHeaders(timeOrigin),
147
- };
148
- }
149
- if (this.id !== endpointId) {
150
- return {
151
- status: 200,
152
- body: {
153
- ok: false,
154
- error: `Endpoint ID mismatch error. Expected ${this.id}, got ${endpointId}`,
155
- },
156
- headers: this.#standardResponseHeaders(timeOrigin),
157
- };
158
- }
159
- return {
160
- status: 200,
161
- body: {
162
- ok: true,
163
- },
164
- headers: this.#standardResponseHeaders(timeOrigin),
165
- };
166
- }
167
- case "INDEX_ENDPOINT": {
168
- const body = {
169
- jobs: this.#buildJobsIndex(),
170
- sources: Object.values(this.#registeredSources),
171
- webhooks: Object.values(this.#registeredWebhooks),
172
- dynamicTriggers: Object.values(this.#registeredDynamicTriggers).map((trigger) => ({
173
- id: trigger.id,
174
- jobs: this.#jobMetadataByDynamicTriggers[trigger.id] ?? [],
175
- registerSourceJob: {
176
- id: dynamicTriggerRegisterSourceJobId(trigger.id),
177
- version: trigger.source.version,
178
- },
179
- })),
180
- dynamicSchedules: Object.entries(this.#registeredSchedules).map(([id, jobs]) => ({
181
- id,
182
- jobs,
183
- })),
184
- httpEndpoints: Object.entries(this.#registeredHttpEndpoints).map(([id, endpoint]) => endpoint.toJSON()),
185
- };
186
- // if the x-trigger-job-id header is not set, we return all jobs
187
- return {
188
- status: 200,
189
- body,
190
- headers: this.#standardResponseHeaders(timeOrigin),
191
- };
192
- }
193
- case "INITIALIZE_TRIGGER": {
194
- const json = await request.json();
195
- const body = InitializeTriggerBodySchema.safeParse(json);
196
- if (!body.success) {
197
- return {
198
- status: 400,
199
- body: {
200
- message: "Invalid trigger body",
201
- },
202
- };
203
- }
204
- const dynamicTrigger = this.#registeredDynamicTriggers[body.data.id];
205
- if (!dynamicTrigger) {
206
- return {
207
- status: 404,
208
- body: {
209
- message: "Dynamic trigger not found",
210
- },
211
- };
212
- }
213
- return {
214
- status: 200,
215
- body: dynamicTrigger.registeredTriggerForParams(body.data.params),
216
- headers: this.#standardResponseHeaders(timeOrigin),
217
- };
218
- }
219
- case "EXECUTE_JOB": {
220
- const json = await request.json();
221
- const execution = RunJobBodySchema.safeParse(json);
222
- if (!execution.success) {
223
- return {
224
- status: 400,
225
- body: {
226
- message: "Invalid execution",
227
- },
228
- };
229
- }
230
- const job = this.#registeredJobs[execution.data.job.id];
231
- if (!job) {
232
- return {
233
- status: 404,
234
- body: {
235
- message: "Job not found",
236
- },
237
- };
238
- }
239
- const results = await this.#executeJob(execution.data, job, timeOrigin, triggerVersion);
240
- this.#internalLogger.debug("executed job", {
241
- results,
242
- job: job.id,
243
- version: job.version,
244
- triggerVersion,
245
- });
246
- const standardHeaders = this.#standardResponseHeaders(timeOrigin);
247
- standardHeaders["x-trigger-run-metadata"] = this.#serializeRunMetadata(job);
248
- return {
249
- status: 200,
250
- body: results,
251
- headers: standardHeaders,
252
- };
253
- }
254
- case "PREPROCESS_RUN": {
255
- const json = await request.json();
256
- const body = PreprocessRunBodySchema.safeParse(json);
257
- if (!body.success) {
258
- return {
259
- status: 400,
260
- body: {
261
- message: "Invalid body",
262
- },
263
- };
264
- }
265
- const job = this.#registeredJobs[body.data.job.id];
266
- if (!job) {
267
- return {
268
- status: 404,
269
- body: {
270
- message: "Job not found",
271
- },
272
- };
273
- }
274
- const results = await this.#preprocessRun(body.data, job);
275
- return {
276
- status: 200,
277
- body: {
278
- abort: results.abort,
279
- properties: results.properties,
280
- },
281
- headers: this.#standardResponseHeaders(timeOrigin),
282
- };
283
- }
284
- case "DELIVER_HTTP_SOURCE_REQUEST": {
285
- const headers = HttpSourceRequestHeadersSchema.safeParse(Object.fromEntries(request.headers.entries()));
286
- if (!headers.success) {
287
- return {
288
- status: 400,
289
- body: {
290
- message: "Invalid headers",
291
- },
292
- };
293
- }
294
- const sourceRequestNeedsBody = headers.data["x-ts-http-method"] !== "GET";
295
- const sourceRequestInit = {
296
- method: headers.data["x-ts-http-method"],
297
- headers: headers.data["x-ts-http-headers"],
298
- body: sourceRequestNeedsBody ? request.body : undefined,
299
- };
300
- if (sourceRequestNeedsBody) {
301
- try {
302
- // @ts-ignore
303
- sourceRequestInit.duplex = "half";
304
- }
305
- catch (error) {
306
- // ignore
307
- }
308
- }
309
- const sourceRequest = new Request(headers.data["x-ts-http-url"], sourceRequestInit);
310
- const key = headers.data["x-ts-key"];
311
- const dynamicId = headers.data["x-ts-dynamic-id"];
312
- const secret = headers.data["x-ts-secret"];
313
- const params = headers.data["x-ts-params"];
314
- const data = headers.data["x-ts-data"];
315
- const auth = headers.data["x-ts-auth"];
316
- const inputMetadata = headers.data["x-ts-metadata"];
317
- const source = {
318
- key,
319
- dynamicId,
320
- secret,
321
- params,
322
- data,
323
- auth,
324
- metadata: inputMetadata,
325
- };
326
- const { response, events, metadata } = await this.#handleHttpSourceRequest(source, sourceRequest);
327
- return {
328
- status: 200,
329
- body: {
330
- events,
331
- response,
332
- metadata,
333
- },
334
- headers: this.#standardResponseHeaders(timeOrigin),
335
- };
336
- }
337
- case "DELIVER_HTTP_ENDPOINT_REQUEST_FOR_RESPONSE": {
338
- const headers = HttpEndpointRequestHeadersSchema.safeParse(Object.fromEntries(request.headers.entries()));
339
- if (!headers.success) {
340
- return {
341
- status: 400,
342
- body: {
343
- message: "Invalid headers",
344
- },
345
- };
346
- }
347
- const sourceRequestNeedsBody = headers.data["x-ts-http-method"] !== "GET";
348
- const sourceRequestInit = {
349
- method: headers.data["x-ts-http-method"],
350
- headers: headers.data["x-ts-http-headers"],
351
- body: sourceRequestNeedsBody ? request.body : undefined,
352
- };
353
- if (sourceRequestNeedsBody) {
354
- try {
355
- // @ts-ignore
356
- sourceRequestInit.duplex = "half";
357
- }
358
- catch (error) {
359
- // ignore
360
- }
361
- }
362
- const sourceRequest = new Request(headers.data["x-ts-http-url"], sourceRequestInit);
363
- const key = headers.data["x-ts-key"];
364
- const { response } = await this.#handleHttpEndpointRequestForResponse({
365
- key,
366
- }, sourceRequest);
367
- return {
368
- status: 200,
369
- body: response,
370
- headers: this.#standardResponseHeaders(timeOrigin),
371
- };
372
- }
373
- case "DELIVER_WEBHOOK_REQUEST": {
374
- const headers = WebhookSourceRequestHeadersSchema.safeParse(Object.fromEntries(request.headers.entries()));
375
- if (!headers.success) {
376
- return {
377
- status: 400,
378
- body: {
379
- message: "Invalid headers",
380
- },
381
- };
382
- }
383
- const sourceRequestNeedsBody = headers.data["x-ts-http-method"] !== "GET";
384
- const sourceRequestInit = {
385
- method: headers.data["x-ts-http-method"],
386
- headers: headers.data["x-ts-http-headers"],
387
- body: sourceRequestNeedsBody ? request.body : undefined,
388
- };
389
- if (sourceRequestNeedsBody) {
390
- try {
391
- // @ts-ignore
392
- sourceRequestInit.duplex = "half";
393
- }
394
- catch (error) {
395
- // ignore
396
- }
397
- }
398
- const webhookRequest = new Request(headers.data["x-ts-http-url"], sourceRequestInit);
399
- const key = headers.data["x-ts-key"];
400
- const secret = headers.data["x-ts-secret"];
401
- const params = headers.data["x-ts-params"];
402
- const ctx = {
403
- key,
404
- secret,
405
- params,
406
- };
407
- const { response, verified, error } = await this.#handleWebhookRequest(webhookRequest, ctx);
408
- return {
409
- status: 200,
410
- body: {
411
- response,
412
- verified,
413
- error,
414
- },
415
- headers: this.#standardResponseHeaders(timeOrigin),
416
- };
417
- }
418
- case "VALIDATE": {
419
- return {
420
- status: 200,
421
- body: {
422
- ok: true,
423
- endpointId: this.id,
424
- },
425
- headers: this.#standardResponseHeaders(timeOrigin),
426
- };
427
- }
428
- case "PROBE_EXECUTION_TIMEOUT": {
429
- const json = await request.json();
430
- // Keep this request open for max 15 minutes so the server can detect when the function execution limit is exceeded
431
- const timeout = json?.timeout ?? 15 * 60 * 1000;
432
- await new Promise((resolve) => setTimeout(resolve, timeout));
433
- return {
434
- status: 200,
435
- body: {
436
- ok: true,
437
- },
438
- headers: this.#standardResponseHeaders(timeOrigin),
439
- };
440
- }
441
- case "RUN_NOTIFICATION": {
442
- const rawJson = await request.json();
443
- const runNotification = rawJson;
444
- if (runNotification.ok) {
445
- await this.#deliverSuccessfulRunNotification(runNotification);
446
- }
447
- else {
448
- await this.#deliverFailedRunNotification(runNotification);
449
- }
450
- return {
451
- status: 200,
452
- body: {
453
- ok: true,
454
- },
455
- headers: this.#standardResponseHeaders(timeOrigin),
456
- };
457
- }
458
- }
459
- return {
460
- status: 405,
461
- body: {
462
- message: "Method not allowed",
463
- },
464
- headers: this.#standardResponseHeaders(timeOrigin),
465
- };
466
- }
467
- defineJob(options) {
468
- const existingRegisteredJob = this.#registeredJobs[options.id];
469
- if (existingRegisteredJob && options.__internal !== true) {
470
- console.warn(`[@trigger.dev/sdk] Warning: The Job "${existingRegisteredJob.id}" you're attempting to define has already been defined. Please assign a different ID to the job.`);
471
- }
472
- const job = new Job(options);
473
- this.attach(job);
474
- return job;
475
- }
476
- defineAuthResolver(integration, resolver) {
477
- this.#authResolvers[integration.id] = resolver;
478
- return this;
479
- }
480
- defineDynamicSchedule(options) {
481
- return new DynamicSchedule(this, options);
482
- }
483
- defineDynamicTrigger(options) {
484
- return new DynamicTrigger(this, options);
485
- }
486
- /**
487
- * An [HTTP endpoint](https://trigger.dev/docs/documentation/concepts/http-endpoints) allows you to create a [HTTP Trigger](https://trigger.dev/docs/documentation/concepts/triggers/http), which means you can trigger your Jobs from any webhooks.
488
- * @param options The Endpoint options
489
- * @returns An HTTP Endpoint, that can be used to create an HTTP Trigger.
490
- * @link https://trigger.dev/docs/documentation/concepts/http-endpoints
491
- */
492
- defineHttpEndpoint(options, suppressWarnings = false) {
493
- const existingHttpEndpoint = this.#registeredHttpEndpoints[options.id];
494
- if (!suppressWarnings && existingHttpEndpoint) {
495
- console.warn(`[@trigger.dev/sdk] Warning: The HttpEndpoint "${existingHttpEndpoint.id}" you're attempting to define has already been defined. Please assign a different ID to the HttpEndpoint.`);
496
- }
497
- const endpoint = httpEndpoint(options);
498
- this.#registeredHttpEndpoints[endpoint.id] = endpoint;
499
- return endpoint;
500
- }
501
- defineConcurrencyLimit(options) {
502
- return new ConcurrencyLimit(options);
503
- }
504
- attach(job) {
505
- this.#registeredJobs[job.id] = job;
506
- job.trigger.attachToJob(this, job);
507
- job.client = this;
508
- }
509
- attachDynamicTrigger(trigger) {
510
- this.#registeredDynamicTriggers[trigger.id] = trigger;
511
- this.defineJob({
512
- id: dynamicTriggerRegisterSourceJobId(trigger.id),
513
- name: `Register dynamic trigger ${trigger.id}`,
514
- version: trigger.source.version,
515
- trigger: new EventTrigger({
516
- event: registerSourceEvent,
517
- filter: { dynamicTriggerId: [trigger.id] },
518
- }),
519
- integrations: {
520
- integration: trigger.source.integration,
521
- },
522
- run: async (event, io, ctx) => {
523
- const updates = await trigger.source.register(event.source.params, event, io, ctx);
524
- if (!updates) {
525
- // TODO: do something here?
526
- return;
527
- }
528
- return await io.updateSource("update-source", {
529
- key: event.source.key,
530
- ...updates,
531
- });
532
- },
533
- __internal: true,
534
- });
535
- }
536
- attachJobToDynamicTrigger(job, trigger) {
537
- const jobs = this.#jobMetadataByDynamicTriggers[trigger.id] ?? [];
538
- jobs.push({ id: job.id, version: job.version });
539
- this.#jobMetadataByDynamicTriggers[trigger.id] = jobs;
540
- }
541
- attachSource(options) {
542
- this.#registeredHttpSourceHandlers[options.key] = async (s, r) => {
543
- return await options.source.handle(s, r, this.#internalLogger);
544
- };
545
- let registeredSource = this.#registeredSources[options.key];
546
- if (!registeredSource) {
547
- registeredSource = {
548
- version: "2",
549
- channel: options.source.channel,
550
- key: options.key,
551
- params: options.params,
552
- options: {},
553
- integration: {
554
- id: options.source.integration.id,
555
- metadata: options.source.integration.metadata,
556
- authSource: options.source.integration.authSource,
557
- },
558
- registerSourceJob: {
559
- id: options.key,
560
- version: options.source.version,
561
- },
562
- };
563
- }
564
- //combined the previous source options with this one, making sure to include event
565
- const newOptions = deepMergeOptions({
566
- event: typeof options.event.name === "string" ? [options.event.name] : options.event.name,
567
- }, options.options ?? {});
568
- registeredSource.options = deepMergeOptions(registeredSource.options, newOptions);
569
- this.#registeredSources[options.key] = registeredSource;
570
- this.defineJob({
571
- id: options.key,
572
- name: options.key,
573
- version: options.source.version,
574
- trigger: new EventTrigger({
575
- event: registerSourceEvent,
576
- filter: { source: { key: [options.key] } },
577
- }),
578
- integrations: {
579
- integration: options.source.integration,
580
- },
581
- run: async (event, io, ctx) => {
582
- const updates = await options.source.register(options.params, event, io, ctx);
583
- if (!updates) {
584
- // TODO: do something here?
585
- return;
586
- }
587
- return await io.updateSource("update-source", {
588
- key: options.key,
589
- ...updates,
590
- });
591
- },
592
- __internal: true,
593
- });
594
- }
595
- attachDynamicSchedule(key) {
596
- const jobs = this.#registeredSchedules[key] ?? [];
597
- this.#registeredSchedules[key] = jobs;
598
- }
599
- attachDynamicScheduleToJob(key, job) {
600
- const jobs = this.#registeredSchedules[key] ?? [];
601
- jobs.push({ id: job.id, version: job.version });
602
- this.#registeredSchedules[key] = jobs;
603
- }
604
- attachWebhook(options) {
605
- const { source } = options;
606
- this.#registeredWebhookSourceHandlers[options.key] = {
607
- verify: source.verify.bind(source),
608
- generateEvents: source.generateEvents.bind(source),
609
- };
610
- let registeredWebhook = this.#registeredWebhooks[options.key];
611
- if (!registeredWebhook) {
612
- registeredWebhook = {
613
- key: options.key,
614
- params: options.params,
615
- config: options.config,
616
- integration: {
617
- id: source.integration.id,
618
- metadata: source.integration.metadata,
619
- authSource: source.integration.authSource,
620
- },
621
- httpEndpoint: {
622
- id: options.key,
623
- },
624
- };
625
- }
626
- else {
627
- registeredWebhook.config = deepMergeOptions(registeredWebhook.config, options.config);
628
- }
629
- this.#registeredWebhooks[options.key] = registeredWebhook;
630
- this.defineJob({
631
- id: `webhook.register.${options.key}`,
632
- name: `webhook.register.${options.key}`,
633
- version: source.version,
634
- trigger: new EventTrigger({
635
- event: registerWebhookEvent(options.key),
636
- }),
637
- integrations: {
638
- integration: source.integration,
639
- },
640
- run: async (registerPayload, io, ctx) => {
641
- return await io.try(async () => {
642
- this.#internalLogger.debug("[webhook.register] Start");
643
- const crudOptions = {
644
- io,
645
- // this is just a more strongly typed payload
646
- ctx: registerPayload,
647
- };
648
- if (!registerPayload.active) {
649
- this.#internalLogger.debug("[webhook.register] Not active, run create");
650
- await io.try(async () => {
651
- await source.crud.create(crudOptions);
652
- }, async (error) => {
653
- this.#internalLogger.debug("[webhook.register] Error during create, re-trying with delete first", { error });
654
- await io.runTask("create-retry", async () => {
655
- await source.crud.delete(crudOptions);
656
- await source.crud.create(crudOptions);
657
- });
658
- });
659
- return await io.updateWebhook("update-webhook-success", {
660
- key: options.key,
661
- active: true,
662
- config: registerPayload.config.desired,
663
- });
664
- }
665
- this.#internalLogger.debug("[webhook.register] Already active, run update");
666
- if (source.crud.update) {
667
- await source.crud.update(crudOptions);
668
- }
669
- else {
670
- this.#internalLogger.debug("[webhook.register] Run delete and create instead of update");
671
- await source.crud.delete(crudOptions);
672
- await source.crud.create(crudOptions);
673
- }
674
- return await io.updateWebhook("update-webhook-success", {
675
- key: options.key,
676
- active: true,
677
- config: registerPayload.config.desired,
678
- });
679
- }, async (error) => {
680
- this.#internalLogger.debug("[webhook.register] Error", { error });
681
- await io.updateWebhook("update-webhook-error", {
682
- key: options.key,
683
- active: false,
684
- });
685
- throw error;
686
- });
687
- },
688
- __internal: true,
689
- });
690
- }
691
- async registerTrigger(id, key, options, idempotencyKey) {
692
- return this.#client.registerTrigger(this.id, id, key, options, idempotencyKey);
693
- }
694
- async getAuth(id) {
695
- return this.#client.getAuth(this.id, id);
696
- }
697
- /** You can call this function from anywhere in your backend to send an event. The other way to send an event is by using [`io.sendEvent()`](https://trigger.dev/docs/sdk/io/sendevent) from inside a `run()` function.
698
- * @param event The event to send.
699
- * @param options Options for sending the event.
700
- * @returns A promise that resolves to the event details
701
- */
702
- async sendEvent(event, options) {
703
- return this.#client.sendEvent(event, options);
704
- }
705
- /** You can call this function from anywhere in your backend to send multiple events. The other way to send multiple events is by using [`io.sendEvents()`](https://trigger.dev/docs/sdk/io/sendevents) from inside a `run()` function.
706
- * @param events The events to send.
707
- * @param options Options for sending the events.
708
- * @returns A promise that resolves to an array of event details
709
- */
710
- async sendEvents(events, options) {
711
- return this.#client.sendEvents(events, options);
712
- }
713
- async cancelEvent(eventId) {
714
- return this.#client.cancelEvent(eventId);
715
- }
716
- async cancelRunsForEvent(eventId) {
717
- return this.#client.cancelRunsForEvent(eventId);
718
- }
719
- async updateStatus(runId, id, status) {
720
- return this.#client.updateStatus(runId, id, status);
721
- }
722
- async registerSchedule(id, key, schedule) {
723
- return this.#client.registerSchedule(this.id, id, key, schedule);
724
- }
725
- async unregisterSchedule(id, key) {
726
- return this.#client.unregisterSchedule(this.id, id, key);
727
- }
728
- async getEvent(eventId) {
729
- return this.#client.getEvent(eventId);
730
- }
731
- async getRun(runId, options) {
732
- return this.#client.getRun(runId, options);
733
- }
734
- async cancelRun(runId) {
735
- return this.#client.cancelRun(runId);
736
- }
737
- async getRuns(jobSlug, options) {
738
- return this.#client.getRuns(jobSlug, options);
739
- }
740
- async getRunStatuses(runId) {
741
- return this.#client.getRunStatuses(runId);
742
- }
743
- async invokeJob(jobId, payload, options) {
744
- return this.#client.invokeJob(jobId, payload, options);
745
- }
746
- async cancelRunsForJob(jobId) {
747
- return this.#client.cancelRunsForJob(jobId);
748
- }
749
- async createEphemeralEventDispatcher(payload) {
750
- return this.#client.createEphemeralEventDispatcher(payload);
751
- }
752
- get store() {
753
- return {
754
- env: this.#envStore,
755
- };
756
- }
757
- authorized(apiKey) {
758
- if (typeof apiKey !== "string") {
759
- return "missing-header";
760
- }
761
- const localApiKey = this.#options.apiKey ?? env.TRIGGER_API_KEY;
762
- if (!localApiKey) {
763
- return "missing-client";
764
- }
765
- return apiKey === localApiKey ? "authorized" : "unauthorized";
766
- }
767
- apiKey() {
768
- return this.#options.apiKey ?? env.TRIGGER_API_KEY;
769
- }
770
- async #preprocessRun(body, job) {
771
- const context = this.#createPreprocessRunContext(body);
772
- const parsedPayload = job.trigger.event.parsePayload(body.event.payload ?? {});
773
- const properties = job.trigger.event.runProperties?.(parsedPayload) ?? [];
774
- return {
775
- abort: false,
776
- properties,
777
- };
778
- }
779
- async #executeJob(body, job, timeOrigin, triggerVersion) {
780
- this.#internalLogger.debug("executing job", {
781
- execution: body,
782
- job: job.id,
783
- version: job.version,
784
- triggerVersion,
785
- });
786
- const context = this.#createRunContext(body);
787
- const io = new IO({
788
- id: body.run.id,
789
- jobId: job.id,
790
- cachedTasks: body.tasks,
791
- cachedTasksCursor: body.cachedTaskCursor,
792
- yieldedExecutions: body.yieldedExecutions ?? [],
793
- noopTasksSet: body.noopTasksSet,
794
- apiClient: this.#client,
795
- logger: this.#internalLogger,
796
- client: this,
797
- context,
798
- jobLogLevel: job.logLevel ?? this.#options.logLevel ?? "info",
799
- jobLogger: this.#options.ioLogLocalEnabled
800
- ? new Logger(job.id, job.logLevel ?? this.#options.logLevel ?? "info")
801
- : undefined,
802
- serverVersion: triggerVersion,
803
- timeOrigin,
804
- executionTimeout: body.runChunkExecutionLimit,
805
- });
806
- const resolvedConnections = await this.#resolveConnections(context, job.options.integrations, body.connections);
807
- if (!resolvedConnections.ok) {
808
- return {
809
- status: "UNRESOLVED_AUTH_ERROR",
810
- issues: resolvedConnections.issues,
811
- };
812
- }
813
- const ioWithConnections = createIOWithIntegrations(io, resolvedConnections.data, job.options.integrations);
814
- try {
815
- const parsedPayload = job.trigger.event.parsePayload(body.event.payload ?? {});
816
- if (!context.run.isTest) {
817
- const verified = await job.trigger.verifyPayload(parsedPayload);
818
- if (!verified.success) {
819
- return {
820
- status: "ERROR",
821
- error: { message: `Payload verification failed. ${verified.reason}` },
822
- };
823
- }
824
- }
825
- const output = await runLocalStorage.runWith({ io, ctx: context }, () => {
826
- return job.options.run(parsedPayload, ioWithConnections, context);
827
- });
828
- if (this.#options.verbose) {
829
- this.#logIOStats(io.stats);
830
- }
831
- return { status: "SUCCESS", output };
832
- }
833
- catch (error) {
834
- if (this.#options.verbose) {
835
- this.#logIOStats(io.stats);
836
- }
837
- if (error instanceof ResumeWithParallelTaskError) {
838
- return {
839
- status: "RESUME_WITH_PARALLEL_TASK",
840
- task: error.task,
841
- childErrors: error.childErrors.map((childError) => {
842
- return this.#convertErrorToExecutionResponse(childError, body);
843
- }),
844
- };
845
- }
846
- return this.#convertErrorToExecutionResponse(error, body);
847
- }
848
- }
849
- #convertErrorToExecutionResponse(error, body) {
850
- if (error instanceof AutoYieldExecutionError) {
851
- return {
852
- status: "AUTO_YIELD_EXECUTION",
853
- location: error.location,
854
- timeRemaining: error.timeRemaining,
855
- timeElapsed: error.timeElapsed,
856
- limit: body.runChunkExecutionLimit,
857
- };
858
- }
859
- if (error instanceof AutoYieldWithCompletedTaskExecutionError) {
860
- return {
861
- status: "AUTO_YIELD_EXECUTION_WITH_COMPLETED_TASK",
862
- id: error.id,
863
- properties: error.properties,
864
- output: error.output,
865
- data: {
866
- ...error.data,
867
- limit: body.runChunkExecutionLimit,
868
- },
869
- };
870
- }
871
- if (error instanceof AutoYieldRateLimitError) {
872
- return {
873
- status: "AUTO_YIELD_RATE_LIMIT",
874
- reset: error.resetAtTimestamp,
875
- };
876
- }
877
- if (error instanceof YieldExecutionError) {
878
- return { status: "YIELD_EXECUTION", key: error.key };
879
- }
880
- if (error instanceof ParsedPayloadSchemaError) {
881
- return { status: "INVALID_PAYLOAD", errors: error.schemaErrors };
882
- }
883
- if (error instanceof ResumeWithTaskError) {
884
- return { status: "RESUME_WITH_TASK", task: error.task };
885
- }
886
- if (error instanceof RetryWithTaskError) {
887
- return {
888
- status: "RETRY_WITH_TASK",
889
- task: error.task,
890
- error: error.cause,
891
- retryAt: error.retryAt,
892
- };
893
- }
894
- if (error instanceof CanceledWithTaskError) {
895
- return {
896
- status: "CANCELED",
897
- task: error.task,
898
- };
899
- }
900
- if (error instanceof ErrorWithTask) {
901
- const errorWithStack = ErrorWithStackSchema.safeParse(error.cause.output);
902
- if (errorWithStack.success) {
903
- return {
904
- status: "ERROR",
905
- error: errorWithStack.data,
906
- task: error.cause,
907
- };
908
- }
909
- return {
910
- status: "ERROR",
911
- error: { message: JSON.stringify(error.cause.output) },
912
- task: error.cause,
913
- };
914
- }
915
- if (error instanceof RetryWithTaskError) {
916
- const errorWithStack = ErrorWithStackSchema.safeParse(error.cause);
917
- if (errorWithStack.success) {
918
- return {
919
- status: "ERROR",
920
- error: errorWithStack.data,
921
- task: error.task,
922
- };
923
- }
924
- return {
925
- status: "ERROR",
926
- error: { message: "Unknown error" },
927
- task: error.task,
928
- };
929
- }
930
- const errorWithStack = ErrorWithStackSchema.safeParse(error);
931
- if (errorWithStack.success) {
932
- return { status: "ERROR", error: errorWithStack.data };
933
- }
934
- const message = typeof error === "string" ? error : JSON.stringify(error);
935
- return {
936
- status: "ERROR",
937
- error: { name: "Unknown error", message },
938
- };
939
- }
940
- #createRunContext(execution) {
941
- const { event, organization, project, environment, job, run, source } = execution;
942
- return {
943
- event: {
944
- id: event.id,
945
- name: event.name,
946
- context: event.context,
947
- timestamp: event.timestamp,
948
- },
949
- organization,
950
- project: project ?? { id: "unknown", name: "unknown", slug: "unknown" }, // backwards compat with old servers
951
- environment,
952
- job,
953
- run,
954
- account: execution.account,
955
- source,
956
- };
957
- }
958
- #createPreprocessRunContext(body) {
959
- const { event, organization, environment, job, run, account } = body;
960
- return {
961
- event: {
962
- id: event.id,
963
- name: event.name,
964
- context: event.context,
965
- timestamp: event.timestamp,
966
- },
967
- organization,
968
- environment,
969
- job,
970
- run,
971
- account,
972
- };
973
- }
974
- async #handleHttpSourceRequest(source, sourceRequest) {
975
- this.#internalLogger.debug("Handling HTTP source request", {
976
- source,
977
- });
978
- if (source.dynamicId) {
979
- const dynamicTrigger = this.#registeredDynamicTriggers[source.dynamicId];
980
- if (!dynamicTrigger) {
981
- this.#internalLogger.debug("No dynamic trigger registered for HTTP source", {
982
- source,
983
- });
984
- return {
985
- response: {
986
- status: 200,
987
- body: {
988
- ok: true,
989
- },
990
- },
991
- events: [],
992
- };
993
- }
994
- const results = await dynamicTrigger.source.handle(source, sourceRequest, this.#internalLogger);
995
- if (!results) {
996
- return {
997
- events: [],
998
- response: {
999
- status: 200,
1000
- body: {
1001
- ok: true,
1002
- },
1003
- },
1004
- };
1005
- }
1006
- return {
1007
- events: results.events,
1008
- response: results.response ?? {
1009
- status: 200,
1010
- body: {
1011
- ok: true,
1012
- },
1013
- },
1014
- metadata: results.metadata,
1015
- };
1016
- }
1017
- const handler = this.#registeredHttpSourceHandlers[source.key];
1018
- if (!handler) {
1019
- this.#internalLogger.debug("No handler registered for HTTP source", {
1020
- source,
1021
- });
1022
- return {
1023
- response: {
1024
- status: 200,
1025
- body: {
1026
- ok: true,
1027
- },
1028
- },
1029
- events: [],
1030
- };
1031
- }
1032
- const results = await handler(source, sourceRequest);
1033
- if (!results) {
1034
- return {
1035
- events: [],
1036
- response: {
1037
- status: 200,
1038
- body: {
1039
- ok: true,
1040
- },
1041
- },
1042
- };
1043
- }
1044
- return {
1045
- events: results.events,
1046
- response: results.response ?? {
1047
- status: 200,
1048
- body: {
1049
- ok: true,
1050
- },
1051
- },
1052
- metadata: results.metadata,
1053
- };
1054
- }
1055
- async #handleHttpEndpointRequestForResponse(data, sourceRequest) {
1056
- this.#internalLogger.debug("Handling HTTP Endpoint request for response", {
1057
- data,
1058
- });
1059
- const httpEndpoint = this.#registeredHttpEndpoints[data.key];
1060
- if (!httpEndpoint) {
1061
- this.#internalLogger.debug("No handler registered for HTTP Endpoint", {
1062
- data,
1063
- });
1064
- return {
1065
- response: {
1066
- status: 200,
1067
- body: {
1068
- ok: true,
1069
- },
1070
- },
1071
- };
1072
- }
1073
- const handledResponse = await httpEndpoint.handleRequest(sourceRequest);
1074
- if (!handledResponse) {
1075
- this.#internalLogger.debug("There's no HTTP Endpoint respondWith.handler()", {
1076
- data,
1077
- });
1078
- return {
1079
- response: {
1080
- status: 200,
1081
- body: {
1082
- ok: true,
1083
- },
1084
- },
1085
- };
1086
- }
1087
- let body;
1088
- try {
1089
- body = await handledResponse.text();
1090
- }
1091
- catch (error) {
1092
- this.#internalLogger.error(`Error reading httpEndpoint ${httpEndpoint.id} respondWith.handler Response`, {
1093
- error,
1094
- });
1095
- }
1096
- const response = {
1097
- status: handledResponse.status,
1098
- headers: handledResponse.headers
1099
- ? Object.fromEntries(handledResponse.headers.entries())
1100
- : undefined,
1101
- body,
1102
- };
1103
- this.#internalLogger.info(`httpEndpoint ${httpEndpoint.id} respondWith.handler response`, {
1104
- response,
1105
- });
1106
- return {
1107
- response,
1108
- };
1109
- }
1110
- async #handleWebhookRequest(request, ctx) {
1111
- this.#internalLogger.debug("Handling webhook request", {
1112
- ctx,
1113
- });
1114
- const okResponse = {
1115
- status: 200,
1116
- body: {
1117
- ok: true,
1118
- },
1119
- };
1120
- const handlers = this.#registeredWebhookSourceHandlers[ctx.key];
1121
- if (!handlers) {
1122
- this.#internalLogger.debug("No handler registered for webhook", {
1123
- ctx,
1124
- });
1125
- return {
1126
- response: okResponse,
1127
- verified: false,
1128
- };
1129
- }
1130
- const { verify, generateEvents } = handlers;
1131
- const verifyResult = await verify(request, this, ctx);
1132
- if (!verifyResult.success) {
1133
- return {
1134
- response: okResponse,
1135
- verified: false,
1136
- error: verifyResult.reason,
1137
- };
1138
- }
1139
- await generateEvents(request, this, ctx);
1140
- return {
1141
- response: okResponse,
1142
- verified: true,
1143
- };
1144
- }
1145
- async #resolveConnections(ctx, integrations, connections) {
1146
- if (!integrations) {
1147
- return { ok: true, data: {} };
1148
- }
1149
- const resolvedAuthResults = await Promise.all(Object.keys(integrations).map(async (key) => {
1150
- const integration = integrations[key];
1151
- const auth = (connections ?? {})[key];
1152
- const result = await this.#resolveConnection(ctx, integration, auth);
1153
- if (result.ok) {
1154
- return {
1155
- ok: true,
1156
- auth: result.auth,
1157
- key,
1158
- };
1159
- }
1160
- else {
1161
- return {
1162
- ok: false,
1163
- error: result.error,
1164
- key,
1165
- };
1166
- }
1167
- }));
1168
- const allResolved = resolvedAuthResults.every((result) => result.ok);
1169
- if (allResolved) {
1170
- return {
1171
- ok: true,
1172
- data: resolvedAuthResults.reduce((acc, result) => {
1173
- acc[result.key] = result.auth;
1174
- return acc;
1175
- }, {}),
1176
- };
1177
- }
1178
- else {
1179
- return {
1180
- ok: false,
1181
- issues: resolvedAuthResults.reduce((acc, result) => {
1182
- if (result.ok) {
1183
- return acc;
1184
- }
1185
- const integration = integrations[result.key];
1186
- acc[result.key] = { id: integration.id, error: result.error };
1187
- return acc;
1188
- }, {}),
1189
- };
1190
- }
1191
- }
1192
- async #resolveConnection(ctx, integration, auth) {
1193
- if (auth) {
1194
- return { ok: true, auth };
1195
- }
1196
- const authResolver = this.#authResolvers[integration.id];
1197
- if (!authResolver) {
1198
- if (integration.authSource === "HOSTED") {
1199
- return {
1200
- ok: false,
1201
- error: `Something went wrong: Integration ${integration.id} is missing auth credentials from Trigger.dev`,
1202
- };
1203
- }
1204
- return {
1205
- ok: true,
1206
- auth: undefined,
1207
- };
1208
- }
1209
- try {
1210
- const resolvedAuth = await authResolver(ctx, integration);
1211
- if (!resolvedAuth) {
1212
- return {
1213
- ok: false,
1214
- error: `Auth could not be resolved for ${integration.id}: auth resolver returned null or undefined`,
1215
- };
1216
- }
1217
- return {
1218
- ok: true,
1219
- auth: resolvedAuth.type === "apiKey"
1220
- ? {
1221
- type: "apiKey",
1222
- accessToken: resolvedAuth.token,
1223
- additionalFields: resolvedAuth.additionalFields,
1224
- }
1225
- : {
1226
- type: "oauth2",
1227
- accessToken: resolvedAuth.token,
1228
- additionalFields: resolvedAuth.additionalFields,
1229
- },
1230
- };
1231
- }
1232
- catch (resolverError) {
1233
- if (resolverError instanceof Error) {
1234
- return {
1235
- ok: false,
1236
- error: `Auth could not be resolved for ${integration.id}: auth resolver threw. ${resolverError.name}: ${resolverError.message}`,
1237
- };
1238
- }
1239
- else if (typeof resolverError === "string") {
1240
- return {
1241
- ok: false,
1242
- error: `Auth could not be resolved for ${integration.id}: auth resolver threw an error: ${resolverError}`,
1243
- };
1244
- }
1245
- return {
1246
- ok: false,
1247
- error: `Auth could not be resolved for ${integration.id}: auth resolver threw an unknown error: ${JSON.stringify(resolverError)}`,
1248
- };
1249
- }
1250
- }
1251
- #buildJobsIndex() {
1252
- return Object.values(this.#registeredJobs).map((job) => this.#buildJobIndex(job));
1253
- }
1254
- #buildJobIndex(job) {
1255
- const internal = job.options.__internal;
1256
- return {
1257
- id: job.id,
1258
- name: job.name,
1259
- version: job.version,
1260
- event: job.trigger.event,
1261
- trigger: job.trigger.toJSON(),
1262
- integrations: this.#buildJobIntegrations(job),
1263
- startPosition: "latest", // job is deprecated, leaving job for now to make sure newer clients work with older servers
1264
- enabled: job.enabled,
1265
- preprocessRuns: job.trigger.preprocessRuns,
1266
- internal,
1267
- concurrencyLimit: typeof job.options.concurrencyLimit === "number"
1268
- ? job.options.concurrencyLimit
1269
- : typeof job.options.concurrencyLimit === "object"
1270
- ? { id: job.options.concurrencyLimit.id, limit: job.options.concurrencyLimit.limit }
1271
- : undefined,
1272
- };
1273
- }
1274
- #buildJobIntegrations(job) {
1275
- return Object.keys(job.options.integrations ?? {}).reduce((acc, key) => {
1276
- const integration = job.options.integrations[key];
1277
- acc[key] = this.#buildJobIntegration(integration);
1278
- return acc;
1279
- }, {});
1280
- }
1281
- #buildJobIntegration(integration) {
1282
- const authSource = this.#authResolvers[integration.id] ? "RESOLVER" : integration.authSource;
1283
- return {
1284
- id: integration.id,
1285
- metadata: integration.metadata,
1286
- authSource,
1287
- };
1288
- }
1289
- #logIOStats(stats) {
1290
- this.#internalLogger.debug("IO stats", {
1291
- stats,
1292
- });
1293
- }
1294
- #standardResponseHeaders(start) {
1295
- return {
1296
- "Trigger-Version": API_VERSIONS.LAZY_LOADED_CACHED_TASKS,
1297
- "Trigger-SDK-Version": VERSION,
1298
- "X-Trigger-Request-Timing": `dur=${performance.now() - start / 1000.0}`,
1299
- };
1300
- }
1301
- #serializeRunMetadata(job) {
1302
- const metadata = {};
1303
- if (this.#eventEmitter.listenerCount("runSucceeeded") > 0 ||
1304
- typeof job.options.onSuccess === "function") {
1305
- metadata["successSubscription"] = true;
1306
- }
1307
- if (this.#eventEmitter.listenerCount("runFailed") > 0 ||
1308
- typeof job.options.onFailure === "function") {
1309
- metadata["failedSubscription"] = true;
1310
- }
1311
- return JSON.stringify(metadata);
1312
- }
1313
- async #deliverSuccessfulRunNotification(notification) {
1314
- this.#internalLogger.debug("delivering successful run notification", {
1315
- notification,
1316
- });
1317
- this.#eventEmitter.emit("runSucceeeded", notification);
1318
- const job = this.#registeredJobs[notification.job.id];
1319
- if (!job) {
1320
- return;
1321
- }
1322
- if (typeof job.options.onSuccess === "function") {
1323
- await job.options.onSuccess(notification);
1324
- }
1325
- }
1326
- async #deliverFailedRunNotification(notification) {
1327
- this.#internalLogger.debug("delivering failed run notification", {
1328
- notification,
1329
- });
1330
- this.#eventEmitter.emit("runFailed", notification);
1331
- const job = this.#registeredJobs[notification.job.id];
1332
- if (!job) {
1333
- return;
1334
- }
1335
- if (typeof job.options.onFailure === "function") {
1336
- await job.options.onFailure(notification);
1337
- }
1338
- }
1339
- }
1340
- function dynamicTriggerRegisterSourceJobId(id) {
1341
- return `register-dynamic-trigger-${id}`;
1342
- }
1343
- function deepMergeOptions(obj1, obj2) {
1344
- const mergedOptions = { ...obj1 };
1345
- for (const key in obj2) {
1346
- if (obj2.hasOwnProperty(key)) {
1347
- if (key in mergedOptions) {
1348
- // @ts-expect-error
1349
- mergedOptions[key] = [...mergedOptions[key], ...obj2[key]];
1350
- }
1351
- else {
1352
- // @ts-expect-error
1353
- mergedOptions[key] = obj2[key];
1354
- }
1355
- }
1356
- }
1357
- return mergedOptions;
1358
- }
1359
- //# sourceMappingURL=triggerClient.js.map