| 1 | import { assertTrue, deepStrictEqual } from "@effect/vitest/utils" |
| 2 | import { Schema } from "effect" |
| 3 | import type { StandardJSONSchemaV1 } from "effect/StandardSchema" |
| 4 | import { describe, it } from "vitest" |
| 5 | |
| 6 | function standardConvertToJSONSchemaInput( |
| 7 | schema: StandardJSONSchemaV1, |
| 8 | target?: StandardJSONSchemaV1.Target |
| 9 | ): Record<string, unknown> { |
| 10 | return schema["~standard"].jsonSchema.input({ |
| 11 | target: target ?? "draft-2020-12" |
| 12 | }) |
| 13 | } |
| 14 | |
| 15 | function standardConvertToJSONSchemaOutput( |
| 16 | schema: StandardJSONSchemaV1, |
| 17 | target?: StandardJSONSchemaV1.Target |
| 18 | ): Record<string, unknown> { |
| 19 | return schema["~standard"].jsonSchema.output({ |
| 20 | target: target ?? "draft-2020-12" |
| 21 | }) |
| 22 | } |
| 23 | |
| 24 | describe("toStandardJSONSchemaV1", () => { |
| 25 | it("should return a schema with Standard JSON Schema metadata", () => { |
| 26 | const schema = Schema.FiniteFromString |
| 27 | const standardSchema = Schema.toStandardJSONSchemaV1(schema) |
| 28 | assertTrue(Schema.isSchema(standardSchema)) |
| 29 | }) |
| 30 | |
| 31 | it("should support both standards", () => { |
| 32 | const schema = Schema.String |
| 33 | const both = Schema.toStandardSchemaV1(Schema.toStandardJSONSchemaV1(schema)) |
| 34 | deepStrictEqual(standardConvertToJSONSchemaInput(both), { |
| 35 | "type": "string" |
| 36 | }) |
| 37 | }) |
| 38 | |
| 39 | describe("draft-2020-12", () => { |
| 40 | it("should return the input JSON Schema", () => { |
| 41 | const schema = Schema.Tuple([Schema.FiniteFromString]) |
| 42 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 43 | deepStrictEqual(standardConvertToJSONSchemaInput(standardJSONSchema), { |
| 44 | "type": "array", |
| 45 | "prefixItems": [{ "type": "string" }], |
| 46 | "minItems": 1, |
| 47 | "maxItems": 1 |
| 48 | }) |
| 49 | }) |
| 50 | |
| 51 | it("should return the output JSON Schema", () => { |
| 52 | const schema = Schema.Tuple([Schema.FiniteFromString]) |
| 53 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 54 | deepStrictEqual(standardConvertToJSONSchemaOutput(standardJSONSchema), { |
| 55 | "type": "array", |
| 56 | "prefixItems": [{ "type": "number" }], |
| 57 | "minItems": 1, |
| 58 | "maxItems": 1 |
| 59 | }) |
| 60 | }) |
| 61 | |
| 62 | it("a schema with identifier", () => { |
| 63 | const S = Schema.String.annotate({ identifier: "id" }) |
| 64 | const schema = Schema.Tuple([S, S]) |
| 65 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 66 | deepStrictEqual(standardConvertToJSONSchemaInput(standardJSONSchema), { |
| 67 | "type": "array", |
| 68 | "prefixItems": [ |
| 69 | { "$ref": "#/$defs/id" }, |
| 70 | { "$ref": "#/$defs/id" } |
| 71 | ], |
| 72 | "minItems": 2, |
| 73 | "maxItems": 2, |
| 74 | "$defs": { |
| 75 | "id": { |
| 76 | "type": "string" |
| 77 | } |
| 78 | } |
| 79 | }) |
| 80 | }) |
| 81 | }) |
| 82 | |
| 83 | describe("draft-07", () => { |
| 84 | it("should return the input JSON Schema", () => { |
| 85 | const schema = Schema.Tuple([Schema.FiniteFromString]) |
| 86 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 87 | deepStrictEqual(standardConvertToJSONSchemaInput(standardJSONSchema, "draft-07"), { |
| 88 | "type": "array", |
| 89 | "items": [{ "type": "string" }], |
| 90 | "minItems": 1, |
| 91 | "maxItems": 1 |
| 92 | }) |
| 93 | }) |
| 94 | |
| 95 | it("should return the output JSON Schema", () => { |
| 96 | const schema = Schema.Tuple([Schema.FiniteFromString]) |
| 97 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 98 | deepStrictEqual(standardConvertToJSONSchemaOutput(standardJSONSchema, "draft-07"), { |
| 99 | "type": "array", |
| 100 | "items": [{ "type": "number" }], |
| 101 | "minItems": 1, |
| 102 | "maxItems": 1 |
| 103 | }) |
| 104 | }) |
| 105 | |
| 106 | it("a schema with identifier", () => { |
| 107 | const S = Schema.String.annotate({ identifier: "id" }) |
| 108 | const schema = Schema.Tuple([S, S]) |
| 109 | const standardJSONSchema = Schema.toStandardJSONSchemaV1(schema) |
| 110 | deepStrictEqual(standardConvertToJSONSchemaInput(standardJSONSchema, "draft-07"), { |
| 111 | "type": "array", |
| 112 | "items": [ |
| 113 | { "$ref": "#/definitions/id" }, |
| 114 | { "$ref": "#/definitions/id" } |
| 115 | ], |
| 116 | "minItems": 2, |
| 117 | "maxItems": 2, |
| 118 | "definitions": { |
| 119 | "id": { |
| 120 | "type": "string" |
| 121 | } |
| 122 | } |
| 123 | }) |
| 124 | }) |
| 125 | }) |
| 126 | }) |