chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
.tshy
|
||||
.tshy-build
|
||||
*.log
|
||||
.DS_Store
|
||||
@@ -0,0 +1,261 @@
|
||||
# @trigger.dev/schema-to-json
|
||||
|
||||
## 4.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.3`
|
||||
|
||||
## 4.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.2`
|
||||
|
||||
## 4.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.1`
|
||||
|
||||
## 4.5.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0`
|
||||
|
||||
## 4.5.0-rc.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.7`
|
||||
|
||||
## 4.5.0-rc.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.6`
|
||||
|
||||
## 4.5.0-rc.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.5`
|
||||
|
||||
## 4.5.0-rc.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.4`
|
||||
|
||||
## 4.5.0-rc.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.3`
|
||||
|
||||
## 4.5.0-rc.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.2`
|
||||
|
||||
## 4.5.0-rc.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.1`
|
||||
|
||||
## 4.5.0-rc.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.5.0-rc.0`
|
||||
|
||||
## 4.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.6`
|
||||
|
||||
## 4.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.5`
|
||||
|
||||
## 4.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.4`
|
||||
|
||||
## 4.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.3`
|
||||
|
||||
## 4.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.2`
|
||||
|
||||
## 4.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.1`
|
||||
|
||||
## 4.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.4.0`
|
||||
|
||||
## 4.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.3.3`
|
||||
|
||||
## 4.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.3.2`
|
||||
|
||||
## 4.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.3.1`
|
||||
|
||||
## 4.3.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.3.0`
|
||||
|
||||
## 4.2.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.2.0`
|
||||
|
||||
## 4.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.1.2`
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.1.1`
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.1.0`
|
||||
|
||||
## 4.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.7`
|
||||
|
||||
## 4.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.6`
|
||||
|
||||
## 4.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.5`
|
||||
|
||||
## 4.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- remove effect from optional peer dependencies since it's now a production dependency ([#2527](https://github.com/triggerdotdev/trigger.dev/pull/2527))
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.4`
|
||||
|
||||
## 4.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.3`
|
||||
|
||||
## 4.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.2`
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.1`
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.0`
|
||||
|
||||
## 4.0.0-v4-beta.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.0-v4-beta.28`
|
||||
|
||||
## 4.0.0-v4-beta.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies:
|
||||
- `@trigger.dev/core@4.0.0-v4-beta.27`
|
||||
@@ -0,0 +1,151 @@
|
||||
# @trigger.dev/schema-to-json
|
||||
|
||||
Convert various schema validation libraries to JSON Schema format.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @trigger.dev/schema-to-json
|
||||
```
|
||||
|
||||
## Important: Bundle Safety
|
||||
|
||||
This package is designed to be **bundle-safe**. It does NOT bundle any schema libraries (zod, yup, etc.) as dependencies. Instead:
|
||||
|
||||
1. **Built-in conversions** work immediately (ArkType, Zod 4, TypeBox)
|
||||
2. **External conversions** (Zod 3, Yup, Effect) require the conversion libraries to be available at runtime
|
||||
|
||||
This design ensures that:
|
||||
- ✅ Your bundle size stays small
|
||||
- ✅ You only include the schema libraries you actually use
|
||||
- ✅ Tree-shaking works properly
|
||||
- ✅ No unnecessary dependencies are installed
|
||||
|
||||
## Supported Schema Libraries
|
||||
|
||||
- ✅ **Zod** - Full support
|
||||
- Zod 4: Native support via built-in `toJsonSchema` method (no external deps needed)
|
||||
- Zod 3: Requires `zod-to-json-schema` to be installed
|
||||
- ✅ **Yup** - Requires `@sodaru/yup-to-json-schema` to be installed
|
||||
- ✅ **ArkType** - Native support (built-in `toJsonSchema` method)
|
||||
- ✅ **Effect/Schema** - Requires `effect` or `@effect/schema` to be installed
|
||||
- ✅ **TypeBox** - Native support (already JSON Schema compliant)
|
||||
- ⏳ **Valibot** - Coming soon
|
||||
- ⏳ **Superstruct** - Coming soon
|
||||
- ⏳ **Runtypes** - Coming soon
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage (Built-in conversions only)
|
||||
|
||||
```typescript
|
||||
import { schemaToJsonSchema } from '@trigger.dev/schema-to-json';
|
||||
import { type } from 'arktype';
|
||||
|
||||
// Works immediately for schemas with built-in conversion
|
||||
const arkSchema = type({
|
||||
name: 'string',
|
||||
age: 'number',
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(arkSchema);
|
||||
console.log(result);
|
||||
// { jsonSchema: {...}, schemaType: 'arktype' }
|
||||
```
|
||||
|
||||
### Full Usage (With external conversion libraries)
|
||||
|
||||
```typescript
|
||||
import { schemaToJsonSchema, initializeSchemaConverters } from '@trigger.dev/schema-to-json';
|
||||
import { z } from 'zod';
|
||||
|
||||
// Initialize converters once in your app (loads conversion libraries if available)
|
||||
await initializeSchemaConverters();
|
||||
|
||||
// Now you can convert Zod 3, Yup, and Effect schemas
|
||||
const zodSchema = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
email: z.string().email(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(zodSchema);
|
||||
console.log(result);
|
||||
// {
|
||||
// jsonSchema: {
|
||||
// type: 'object',
|
||||
// properties: {
|
||||
// name: { type: 'string' },
|
||||
// age: { type: 'number' },
|
||||
// email: { type: 'string', format: 'email' }
|
||||
// },
|
||||
// required: ['name', 'age', 'email']
|
||||
// },
|
||||
// schemaType: 'zod'
|
||||
// }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `schemaToJsonSchema(schema, options?)`
|
||||
|
||||
Convert a schema to JSON Schema format.
|
||||
|
||||
**Parameters:**
|
||||
- `schema` - The schema to convert
|
||||
- `options` (optional)
|
||||
- `name` - Name to use for the schema (supported by some converters)
|
||||
- `additionalProperties` - Additional properties to merge into the result
|
||||
|
||||
**Returns:**
|
||||
- `{ jsonSchema, schemaType }` - The converted JSON Schema and detected type
|
||||
- `undefined` - If the schema cannot be converted
|
||||
|
||||
### `initializeSchemaConverters()`
|
||||
|
||||
Initialize the external conversion libraries. Call this once in your application if you need to convert schemas that don't have built-in JSON Schema support (Zod 3, Yup, Effect).
|
||||
|
||||
**Returns:** `Promise<void>`
|
||||
|
||||
### `canConvertSchema(schema)`
|
||||
|
||||
Check if a schema can be converted to JSON Schema.
|
||||
|
||||
**Returns:** `boolean`
|
||||
|
||||
### `detectSchemaType(schema)`
|
||||
|
||||
Detect the type of schema.
|
||||
|
||||
**Returns:** `'zod' | 'yup' | 'arktype' | 'effect' | 'valibot' | 'superstruct' | 'runtypes' | 'typebox' | 'unknown'`
|
||||
|
||||
### `areConvertersInitialized()`
|
||||
|
||||
Check which conversion libraries are available.
|
||||
|
||||
**Returns:** `{ zod: boolean, yup: boolean, effect: boolean }`
|
||||
|
||||
## Peer Dependencies
|
||||
|
||||
Each schema library is an optional peer dependency. Install only the ones you need:
|
||||
|
||||
```bash
|
||||
# For Zod
|
||||
npm install zod
|
||||
|
||||
# For Yup
|
||||
npm install yup
|
||||
|
||||
# For ArkType
|
||||
npm install arktype
|
||||
|
||||
# For Effect
|
||||
npm install effect @effect/schema
|
||||
|
||||
# For TypeBox
|
||||
npm install @sinclair/typebox
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"name": "@trigger.dev/schema-to-json",
|
||||
"version": "4.5.3",
|
||||
"description": "Convert various schema validation libraries to JSON Schema",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/triggerdotdev/trigger.dev",
|
||||
"directory": "packages/schema-to-json"
|
||||
},
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=18.20.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build": "pnpm run clean && pnpm run build:tshy && pnpm run update-version",
|
||||
"build:tshy": "tshy",
|
||||
"dev": "tshy --watch",
|
||||
"typecheck": "tsc -p tsconfig.src.json --noEmit",
|
||||
"test": "vitest",
|
||||
"update-version": "tsx ../../scripts/updateVersion.ts",
|
||||
"check-exports": "attw --pack ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@trigger.dev/core": "workspace:*",
|
||||
"zod-to-json-schema": "^3.24.0",
|
||||
"@sodaru/yup-to-json-schema": "^2",
|
||||
"zod": "3.25.76",
|
||||
"effect": "^3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"arktype": "^2.0.0",
|
||||
"runtypes": "^6.7.0",
|
||||
"superstruct": "^2.0.2",
|
||||
"tshy": "^3.0.2",
|
||||
"@sinclair/typebox": "^0.34.3",
|
||||
"valibot": "^1.1.0",
|
||||
"yup": "^1.7.0",
|
||||
"rimraf": "6.0.1",
|
||||
"@arethetypeswrong/cli": "^0.15.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"arktype": ">=2.0.0",
|
||||
"runtypes": ">=5.0.0",
|
||||
"superstruct": ">=0.14.2",
|
||||
"@sinclair/typebox": ">=0.34.30",
|
||||
"valibot": ">=0.41.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"arktype": {
|
||||
"optional": true
|
||||
},
|
||||
"runtypes": {
|
||||
"optional": true
|
||||
},
|
||||
"superstruct": {
|
||||
"optional": true
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
"optional": true
|
||||
},
|
||||
"valibot": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"tshy": {
|
||||
"selfLink": false,
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"project": "./tsconfig.src.json"
|
||||
},
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"module": "./dist/esm/index.js"
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
// Import JSONSchema from core to ensure compatibility
|
||||
import type { JSONSchema } from "@trigger.dev/core/v3";
|
||||
import { zodToJsonSchema } from "zod-to-json-schema";
|
||||
import * as z4 from "zod/v4";
|
||||
import { convertSchema } from "@sodaru/yup-to-json-schema";
|
||||
import { JSONSchema as EffectJSONSchema } from "effect";
|
||||
|
||||
export type Schema = unknown;
|
||||
export type { JSONSchema };
|
||||
|
||||
export interface ConversionOptions {
|
||||
/**
|
||||
* Enables support for references in the schema.
|
||||
* This is required for recursive schemas, e.g. with `z.lazy`.
|
||||
* However, not all language models and providers support such references.
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
useReferences?: boolean;
|
||||
}
|
||||
|
||||
export interface ConversionResult {
|
||||
/**
|
||||
* The JSON Schema representation (JSON Schema Draft 7)
|
||||
*/
|
||||
jsonSchema: JSONSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a schema from various validation libraries to JSON Schema
|
||||
*
|
||||
* This function attempts to convert schemas without requiring external dependencies to be bundled.
|
||||
* It will only succeed if:
|
||||
* 1. The schema has built-in JSON Schema conversion (ArkType, Zod 4, TypeBox)
|
||||
* 2. The required conversion library is available at runtime (zod-to-json-schema, @sodaru/yup-to-json-schema, etc.)
|
||||
*
|
||||
* @param schema The schema to convert
|
||||
* @param options Optional conversion options
|
||||
* @returns The conversion result or undefined if conversion is not possible
|
||||
*/
|
||||
export function schemaToJsonSchema(
|
||||
schema: Schema,
|
||||
options?: ConversionOptions
|
||||
): ConversionResult | undefined {
|
||||
const parser = schema as any;
|
||||
|
||||
// Check if schema has a built-in toJsonSchema method (e.g., ArkType, Zod 4)
|
||||
if (typeof parser.toJsonSchema === "function") {
|
||||
try {
|
||||
const jsonSchema = parser.toJsonSchema();
|
||||
|
||||
return {
|
||||
jsonSchema,
|
||||
};
|
||||
} catch (_error) {
|
||||
// If toJsonSchema fails, continue to other checks
|
||||
}
|
||||
}
|
||||
|
||||
if (isZodSchema(parser)) {
|
||||
const jsonSchema = convertZodSchema(parser, options);
|
||||
|
||||
if (jsonSchema) {
|
||||
return {
|
||||
jsonSchema: jsonSchema,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's a TypeBox schema (has Static and Kind symbols)
|
||||
if (parser[Symbol.for("TypeBox.Kind")] !== undefined) {
|
||||
// TypeBox schemas are already JSON Schema compliant
|
||||
return {
|
||||
jsonSchema: parser,
|
||||
};
|
||||
}
|
||||
|
||||
if (isYupSchema(parser)) {
|
||||
const jsonSchema = convertYupSchema(parser);
|
||||
if (jsonSchema) {
|
||||
return {
|
||||
jsonSchema: jsonSchema,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (isEffectSchema(parser)) {
|
||||
const jsonSchema = convertEffectSchema(parser);
|
||||
if (jsonSchema) {
|
||||
return {
|
||||
jsonSchema: jsonSchema,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Future schema types can be added here...
|
||||
|
||||
// Unknown schema type
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a schema can be converted to JSON Schema
|
||||
*/
|
||||
export function canConvertSchema(schema: Schema): boolean {
|
||||
const result = schemaToJsonSchema(schema);
|
||||
return result !== undefined;
|
||||
}
|
||||
|
||||
export function isZodSchema(schema: any): boolean {
|
||||
return isZod3Schema(schema) || isZod4Schema(schema);
|
||||
}
|
||||
|
||||
function isZod3Schema(schema: any): boolean {
|
||||
return "_def" in schema && "parse" in schema && "parseAsync" in schema && "safeParse" in schema;
|
||||
}
|
||||
|
||||
function isZod4Schema(schema: any): boolean {
|
||||
return "_zod" in schema;
|
||||
}
|
||||
|
||||
function convertZodSchema(schema: any, options?: ConversionOptions): JSONSchema | undefined {
|
||||
if (isZod4Schema(schema)) {
|
||||
return convertZod4Schema(schema, options);
|
||||
}
|
||||
|
||||
if (isZod3Schema(schema)) {
|
||||
return convertZod3Schema(schema, options);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function convertZod3Schema(schema: any, options?: ConversionOptions): JSONSchema | undefined {
|
||||
const useReferences = options?.useReferences ?? false;
|
||||
|
||||
return zodToJsonSchema(schema, {
|
||||
$refStrategy: useReferences ? "root" : "none",
|
||||
}) as JSONSchema;
|
||||
}
|
||||
|
||||
function convertZod4Schema(schema: any, options?: ConversionOptions): JSONSchema | undefined {
|
||||
const useReferences = options?.useReferences ?? false;
|
||||
|
||||
return z4.toJSONSchema(schema, {
|
||||
target: "draft-7",
|
||||
io: "output",
|
||||
reused: useReferences ? "ref" : "inline",
|
||||
}) as JSONSchema;
|
||||
}
|
||||
|
||||
function isYupSchema(schema: any): boolean {
|
||||
return "spec" in schema && "_typeCheck" in schema;
|
||||
}
|
||||
|
||||
function convertYupSchema(schema: any): JSONSchema | undefined {
|
||||
try {
|
||||
return convertSchema(schema) as JSONSchema;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function isEffectSchema(schema: any): boolean {
|
||||
return "ast" in schema && typeof schema.ast === "object" && typeof schema.ast._tag === "string";
|
||||
}
|
||||
|
||||
function convertEffectSchema(schema: any): JSONSchema | undefined {
|
||||
try {
|
||||
return EffectJSONSchema.make(schema) as JSONSchema;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
import * as z3 from "zod/v3";
|
||||
import * as z4 from "zod/v4";
|
||||
import * as y from "yup";
|
||||
// @ts-ignore
|
||||
import { type } from "arktype";
|
||||
import { Schema } from "effect";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { schemaToJsonSchema, canConvertSchema } from "../src/index.js";
|
||||
|
||||
describe("schemaToJsonSchema", () => {
|
||||
describe("Zod schemas", () => {
|
||||
it("should convert a simple Zod object schema", () => {
|
||||
const schema = z3.object({
|
||||
name: z3.string(),
|
||||
age: z3.number(),
|
||||
email: z3.string().email(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
email: { type: "string", format: "email" },
|
||||
},
|
||||
required: ["name", "age", "email"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert a simple Zod 4 object schema", () => {
|
||||
const schema = z4.object({
|
||||
name: z4.string(),
|
||||
age: z4.number(),
|
||||
email: z4.email(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
email: { type: "string", format: "email" },
|
||||
},
|
||||
required: ["name", "age", "email"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert a Zod schema with optional fields", () => {
|
||||
const schema = z3.object({
|
||||
id: z3.string(),
|
||||
description: z3.string().optional(),
|
||||
tags: z3.array(z3.string()).optional(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
id: { type: "string" },
|
||||
description: { type: "string" },
|
||||
tags: { type: "array", items: { type: "string" } },
|
||||
},
|
||||
required: ["id"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle Zod schema with name option", () => {
|
||||
const schema = z3.object({
|
||||
value: z3.number(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema, { useReferences: true });
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toBeDefined();
|
||||
// The exact structure depends on zod-to-json-schema implementation
|
||||
});
|
||||
});
|
||||
|
||||
describe("Yup schemas", () => {
|
||||
it("should convert a simple Yup object schema", () => {
|
||||
const schema = y.object({
|
||||
name: y.string().required(),
|
||||
age: y.number().required(),
|
||||
email: y.string().email().required(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
email: { type: "string", format: "email" },
|
||||
},
|
||||
required: ["name", "age", "email"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert a Yup schema with optional fields", () => {
|
||||
const schema = y.object({
|
||||
id: y.string().required(),
|
||||
description: y.string(),
|
||||
count: y.number().min(0).max(100),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
id: { type: "string" },
|
||||
description: { type: "string" },
|
||||
count: { type: "number", minimum: 0, maximum: 100 },
|
||||
},
|
||||
required: ["id"],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("ArkType schemas", () => {
|
||||
it("should convert a simple ArkType schema", () => {
|
||||
const schema = type({
|
||||
name: "string",
|
||||
age: "number",
|
||||
active: "boolean",
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toBeDefined();
|
||||
expect(result?.jsonSchema.type).toBe("object");
|
||||
});
|
||||
|
||||
it("should convert an ArkType schema with optional fields", () => {
|
||||
const schema = type({
|
||||
id: "string",
|
||||
"description?": "string",
|
||||
"tags?": "string[]",
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toBeDefined();
|
||||
expect(result?.jsonSchema.type).toBe("object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Effect schemas", () => {
|
||||
it("should convert a simple Effect schema", () => {
|
||||
const schema = Schema.Struct({
|
||||
name: Schema.String,
|
||||
age: Schema.Number,
|
||||
active: Schema.Boolean,
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
active: { type: "boolean" },
|
||||
},
|
||||
required: ["name", "age", "active"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert an Effect schema with optional fields", () => {
|
||||
const schema = Schema.Struct({
|
||||
id: Schema.String,
|
||||
description: Schema.optional(Schema.String),
|
||||
count: Schema.optional(Schema.Number),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toBeDefined();
|
||||
expect(result?.jsonSchema.type).toBe("object");
|
||||
});
|
||||
});
|
||||
|
||||
describe("TypeBox schemas", () => {
|
||||
it("should convert a simple TypeBox schema", () => {
|
||||
const schema = Type.Object({
|
||||
name: Type.String(),
|
||||
age: Type.Number(),
|
||||
active: Type.Boolean(),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
active: { type: "boolean" },
|
||||
},
|
||||
required: ["name", "age", "active"],
|
||||
});
|
||||
});
|
||||
|
||||
it("should convert a TypeBox schema with optional fields", () => {
|
||||
const schema = Type.Object({
|
||||
id: Type.String(),
|
||||
description: Type.Optional(Type.String()),
|
||||
tags: Type.Optional(Type.Array(Type.String())),
|
||||
});
|
||||
|
||||
const result = schemaToJsonSchema(schema);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.jsonSchema).toMatchObject({
|
||||
type: "object",
|
||||
properties: {
|
||||
id: { type: "string" },
|
||||
description: { type: "string" },
|
||||
tags: { type: "array", items: { type: "string" } },
|
||||
},
|
||||
required: ["id"],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Unsupported schemas", () => {
|
||||
it("should return undefined for unsupported schema types", () => {
|
||||
const invalidSchema = { notASchema: true };
|
||||
const result = schemaToJsonSchema(invalidSchema);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return undefined for plain functions", () => {
|
||||
const fn = (value: unknown) => typeof value === "string";
|
||||
const result = schemaToJsonSchema(fn);
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("canConvertSchema", () => {
|
||||
it("should return true for supported schemas", () => {
|
||||
expect(canConvertSchema(z3.string())).toBe(true);
|
||||
expect(canConvertSchema(y.string())).toBe(true);
|
||||
expect(canConvertSchema(type("string"))).toBe(true);
|
||||
expect(canConvertSchema(Schema.String)).toBe(true);
|
||||
expect(canConvertSchema(Type.String())).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for unsupported schemas", () => {
|
||||
expect(canConvertSchema({ notASchema: true })).toBe(false);
|
||||
expect(canConvertSchema(() => true)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "../../.configs/tsconfig.base.json",
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.src.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.test.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["./src/**/*.ts"],
|
||||
"exclude": ["src/**/*.test.ts"],
|
||||
"compilerOptions": {
|
||||
"isolatedDeclarations": false,
|
||||
"composite": true,
|
||||
"sourceMap": true,
|
||||
"customConditions": ["@triggerdotdev/source"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["./tests/**/*.ts"],
|
||||
"references": [{ "path": "./tsconfig.src.json" }],
|
||||
"compilerOptions": {
|
||||
"isolatedDeclarations": false,
|
||||
"composite": true,
|
||||
"sourceMap": true,
|
||||
"types": ["vitest/globals"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "node",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user