-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathschemas.ts
More file actions
313 lines (264 loc) · 9.07 KB
/
schemas.ts
File metadata and controls
313 lines (264 loc) · 9.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
import { z } from "zod";
import { RequireKeys } from "../types/index.js";
import {
MachineConfig,
MachinePreset,
MachinePresetName,
TaskRunExecution,
V3TaskRunExecution,
} from "./common.js";
/*
WARNING: Never import anything from ./messages here. If it's needed in both, put it here instead.
*/
export const EnvironmentType = z.enum(["PRODUCTION", "STAGING", "DEVELOPMENT", "PREVIEW"]);
export type EnvironmentType = z.infer<typeof EnvironmentType>;
export const RunEngineVersionSchema = z.enum(["V1", "V2"]);
export const TaskRunExecutionMetric = z.object({
name: z.string(),
event: z.string(),
timestamp: z.number(),
duration: z.number(),
});
export type TaskRunExecutionMetric = z.infer<typeof TaskRunExecutionMetric>;
export const TaskRunExecutionMetrics = z.array(TaskRunExecutionMetric);
export type TaskRunExecutionMetrics = z.infer<typeof TaskRunExecutionMetrics>;
export const TaskRunExecutionPayload = z.object({
execution: TaskRunExecution,
traceContext: z.record(z.unknown()),
environment: z.record(z.string()).optional(),
metrics: TaskRunExecutionMetrics.optional(),
});
export type TaskRunExecutionPayload = z.infer<typeof TaskRunExecutionPayload>;
// **IMPORTANT NOTE**: If you change this schema, make sure it is backwards compatible with the previous version as this also used when a worker signals to the coordinator that a TaskRun is complete.
// Strategies for not breaking backwards compatibility:
// 1. Add new fields as optional
// 2. If a field is required, add a default value
export const V3ProdTaskRunExecution = V3TaskRunExecution.extend({
worker: z.object({
id: z.string(),
contentHash: z.string(),
version: z.string(),
type: RunEngineVersionSchema.optional(),
}),
machine: MachinePreset.default({ name: "small-1x", cpu: 1, memory: 1, centsPerMs: 0 }),
});
export type V3ProdTaskRunExecution = z.infer<typeof V3ProdTaskRunExecution>;
export const V3ProdTaskRunExecutionPayload = z.object({
execution: V3ProdTaskRunExecution,
traceContext: z.record(z.unknown()),
environment: z.record(z.string()).optional(),
metrics: TaskRunExecutionMetrics.optional(),
});
export type V3ProdTaskRunExecutionPayload = z.infer<typeof V3ProdTaskRunExecutionPayload>;
export const FixedWindowRateLimit = z.object({
type: z.literal("fixed-window"),
limit: z.number(),
window: z.union([
z.object({
seconds: z.number(),
}),
z.object({
minutes: z.number(),
}),
z.object({
hours: z.number(),
}),
]),
});
export const SlidingWindowRateLimit = z.object({
type: z.literal("sliding-window"),
limit: z.number(),
window: z.union([
z.object({
seconds: z.number(),
}),
z.object({
minutes: z.number(),
}),
z.object({
hours: z.number(),
}),
]),
});
export const RateLimitOptions = z.discriminatedUnion("type", [
FixedWindowRateLimit,
SlidingWindowRateLimit,
]);
export type RateLimitOptions = z.infer<typeof RateLimitOptions>;
export const RetryOptions = z.object({
/** The number of attempts before giving up */
maxAttempts: z.number().int().optional(),
/** The exponential factor to use when calculating the next retry time.
*
* Each subsequent retry will be calculated as `previousTimeout * factor`
*/
factor: z.number().optional(),
/** The minimum time to wait before retrying */
minTimeoutInMs: z.number().int().optional(),
/** The maximum time to wait before retrying */
maxTimeoutInMs: z.number().int().optional(),
/** Randomize the timeout between retries.
*
* This can be useful to prevent the thundering herd problem where all retries happen at the same time.
*/
randomize: z.boolean().optional(),
/** If a run fails with an Out Of Memory (OOM) error and you have this set, it will retry with the machine you specify.
* Note: it will not default to this [machine](https://trigger.dev/docs/machines) for new runs, only for failures caused by OOM errors.
* So if you frequently have attempts failing with OOM errors, you should set the [default machine](https://trigger.dev/docs/machines) to be higher.
*/
outOfMemory: z
.object({
machine: MachinePresetName.optional(),
})
.optional(),
});
export type RetryOptions = z.infer<typeof RetryOptions>;
export const QueueManifest = z.object({
/** You can define a shared queue and then pass the name in to your task.
*
* @example
*
* ```ts
* const myQueue = queue({
name: "my-queue",
concurrencyLimit: 1,
});
export const task1 = task({
id: "task-1",
queue: {
name: "my-queue",
},
run: async (payload: { message: string }) => {
// ...
},
});
export const task2 = task({
id: "task-2",
queue: {
name: "my-queue",
},
run: async (payload: { message: string }) => {
// ...
},
});
* ```
*/
name: z.string(),
/** An optional property that specifies the maximum number of concurrent run executions.
*
* If this property is omitted, the task can potentially use up the full concurrency of an environment */
concurrencyLimit: z.number().int().min(0).max(100000).optional().nullable(),
});
export type QueueManifest = z.infer<typeof QueueManifest>;
export const ScheduleMetadata = z.object({
cron: z.string(),
timezone: z.string(),
environments: z.array(EnvironmentType).optional(),
});
const taskMetadata = {
id: z.string(),
description: z.string().optional(),
queue: QueueManifest.extend({ name: z.string().optional() }).optional(),
retry: RetryOptions.optional(),
machine: MachineConfig.optional(),
triggerSource: z.string().optional(),
schedule: ScheduleMetadata.optional(),
maxDuration: z.number().optional(),
ttl: z.string().or(z.number().nonnegative().int()).optional(),
payloadSchema: z.unknown().optional(),
};
export const TaskMetadata = z.object(taskMetadata);
export type TaskMetadata = z.infer<typeof TaskMetadata>;
export const TaskFile = z.object({
entry: z.string(),
out: z.string(),
});
export type TaskFile = z.infer<typeof TaskFile>;
const taskFileMetadata = {
filePath: z.string(),
exportName: z.string().optional(),
entryPoint: z.string(),
};
export const TaskFileMetadata = z.object(taskFileMetadata);
export type TaskFileMetadata = z.infer<typeof TaskFileMetadata>;
export const TaskManifest = z.object({
...taskMetadata,
...taskFileMetadata,
});
export type TaskManifest = z.infer<typeof TaskManifest>;
export const PostStartCauses = z.enum(["index", "create", "restore"]);
export type PostStartCauses = z.infer<typeof PostStartCauses>;
export const PreStopCauses = z.enum(["terminate"]);
export type PreStopCauses = z.infer<typeof PreStopCauses>;
const RegexSchema = z.custom<RegExp>((val) => {
try {
// Check to see if val is a regex
return typeof (val as RegExp).test === "function";
} catch {
return false;
}
});
export const Config = z.object({
project: z.string(),
triggerDirectories: z.string().array().optional(),
triggerUrl: z.string().optional(),
projectDir: z.string().optional(),
tsconfigPath: z.string().optional(),
retries: z
.object({
enabledInDev: z.boolean().default(true),
default: RetryOptions.optional(),
})
.optional(),
additionalPackages: z.string().array().optional(),
additionalFiles: z.string().array().optional(),
dependenciesToBundle: z.array(z.union([z.string(), RegexSchema])).optional(),
logLevel: z.string().optional(),
enableConsoleLogging: z.boolean().optional(),
postInstall: z.string().optional(),
extraCACerts: z.string().optional(),
});
export type Config = z.infer<typeof Config>;
export type ResolvedConfig = RequireKeys<
Config,
"triggerDirectories" | "triggerUrl" | "projectDir" | "tsconfigPath"
>;
export const WaitReason = z.enum(["WAIT_FOR_DURATION", "WAIT_FOR_TASK", "WAIT_FOR_BATCH"]);
export type WaitReason = z.infer<typeof WaitReason>;
export const TaskRunExecutionLazyAttemptPayload = z.object({
runId: z.string(),
attemptCount: z.number().optional(),
messageId: z.string(),
isTest: z.boolean(),
traceContext: z.record(z.unknown()),
environment: z.record(z.string()).optional(),
metrics: TaskRunExecutionMetrics.optional(),
});
export type TaskRunExecutionLazyAttemptPayload = z.infer<typeof TaskRunExecutionLazyAttemptPayload>;
export const ManualCheckpointMetadata = z.object({
/** NOT a friendly ID */
attemptId: z.string(),
previousRunStatus: z.string(),
previousAttemptStatus: z.string(),
});
export type ManualCheckpointMetadata = z.infer<typeof ManualCheckpointMetadata>;
export const RunChainState = z.object({
concurrency: z
.object({
queues: z.array(z.object({ id: z.string(), name: z.string(), holding: z.number() })),
environment: z.number().optional(),
})
.optional(),
});
export type RunChainState = z.infer<typeof RunChainState>;
export const TriggerTraceContext = z.object({
traceparent: z.string().optional(),
tracestate: z.string().optional(),
external: z
.object({
traceparent: z.string().optional(),
tracestate: z.string().optional(),
})
.optional(),
});
export type TriggerTraceContext = z.infer<typeof TriggerTraceContext>;