Skip to content

Commit eb23a34

Browse files
feat: add support for standard schema in schemaTask
1 parent 1d744fa commit eb23a34

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

.changeset/nine-snails-beam.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"@trigger.dev/core": major
3+
---
4+
Why
5+
Allow usage of validation libraries that implement standard schema for schemaTask
6+
7+
What
8+
support standard schema for schemaTask
9+
10+
How
11+
Pass schema definition via schemaTask.schema
12+
Usage:
13+
schemaTask({
14+
schema : `any compatable schema`
15+
})
16+
17+

packages/core/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@
199199
"uncrypto": "^0.1.3",
200200
"zod": "3.25.76",
201201
"zod-error": "1.5.0",
202-
"zod-validation-error": "^1.5.0"
202+
"zod-validation-error": "^1.5.0",
203+
"@standard-schema/spec" : "^1.1.0"
203204
},
204205
"devDependencies": {
205206
"@ai-sdk/provider-utils": "^1.0.22",

packages/core/src/v3/types/schemas.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { StandardSchemaV1 } from "@standard-schema/spec";
2+
13
export type SchemaZodEsque<TInput, TParsedInput> = {
24
_input: TInput;
35
_output: TParsedInput;
@@ -41,6 +43,12 @@ export function isSchemaArkTypeEsque<TInput, TParsedInput>(
4143
return typeof schema === "object" && "_inferIn" in schema && "_infer" in schema;
4244
}
4345

46+
export function isSchemaStandardSchemaV1<TInput, TParsedInput>(
47+
schema: Schema
48+
): schema is StandardSchemaV1<TInput, TParsedInput> {
49+
return typeof schema === "object" && "~standard" in schema && schema["~standard"].version === 1;
50+
}
51+
4452
export type SchemaMyZodEsque<TInput> = {
4553
parse: (input: any) => TInput;
4654
};
@@ -64,12 +72,14 @@ export type SchemaWithoutInput<TInput> =
6472
| SchemaMyZodEsque<TInput>
6573
| SchemaScaleEsque<TInput>
6674
| SchemaSuperstructEsque<TInput>
67-
| SchemaYupEsque<TInput>;
75+
| SchemaYupEsque<TInput>
76+
| StandardSchemaV1<TInput>;
6877

6978
export type SchemaWithInputOutput<TInput, TParsedInput> =
7079
| SchemaZodEsque<TInput, TParsedInput>
7180
| SchemaValibotEsque<TInput, TParsedInput>
72-
| SchemaArkTypeEsque<TInput, TParsedInput>;
81+
| SchemaArkTypeEsque<TInput, TParsedInput>
82+
| StandardSchemaV1<TInput, TParsedInput>;
7383

7484
export type Schema = SchemaWithInputOutput<any, any> | SchemaWithoutInput<any>;
7585

@@ -98,11 +108,26 @@ export type inferSchemaOut<
98108
TDefault = unknown,
99109
> = TSchema extends Schema ? inferSchema<TSchema>["out"] : TDefault;
100110

111+
function issueToString(issue: StandardSchemaV1.Issue) : string {
112+
return `{ message : ${issue.message} , path : ${issue.path}}`
113+
}
114+
115+
class StandardSchemaV1ValidateError extends Error {
116+
constructor(result : StandardSchemaV1.FailureResult){
117+
let message = `StandardSchemaV1 Validate Error [`
118+
result.issues.forEach((issue) => {
119+
message += ` ${issueToString(issue)}`
120+
})
121+
message += ' ]'
122+
super(message)
123+
}
124+
}
125+
101126
export type SchemaParseFn<TType> = (value: unknown) => Promise<TType> | TType;
102127
export type AnySchemaParseFn = SchemaParseFn<any>;
103128

104129
export function getSchemaParseFn<TType>(procedureParser: Schema): SchemaParseFn<TType> {
105-
const parser = procedureParser as any;
130+
const parser = procedureParser as any;
106131

107132
if (typeof parser === "function" && typeof parser.assert === "function") {
108133
// ParserArkTypeEsque - arktype schemas shouldn't be called as a function because they return a union type instead of throwing
@@ -144,5 +169,16 @@ export function getSchemaParseFn<TType>(procedureParser: Schema): SchemaParseFn<
144169
};
145170
}
146171

172+
if (parser["~standard"] && typeof parser["~standard"].validate === "function") {
173+
return (value) => {
174+
let response = parser["~standard"].validate(value);
175+
if ("value" in response) {
176+
return response["value"] as TType;
177+
}
178+
//FailureResult type
179+
throw new StandardSchemaV1ValidateError(response);
180+
};
181+
}
182+
147183
throw new Error("Could not find a validator fn");
148184
}

0 commit comments

Comments
 (0)