Unexpected behavior when composing schemas with `Schema.compose` in OpenAPI rendering
Hi! I'm getting unexpected Schema.compose behavior rendering OpenAPI schema.
Here is a minimal example: https://effect.website/play/#fd1b2dacc906
Pasting same code below
Console.log output:
I expect
This behavior screws documentation generated by
Here is a minimal example: https://effect.website/play/#fd1b2dacc906
Pasting same code below
import { JSONSchema, Schema } from 'effect';
// We don't use Unicode property escapes because they are not supported in OpenAI API :-(
// biome-ignore lint/suspicious/noControlCharactersInRegex: YOLO
const REG_EXP = /[^\s\x00-\x1F\x7F-\x9F]+/;
export const VisibleString = Schema.String.pipe(
Schema.filter((s) => (REG_EXP.test(s) ? undefined : 'Expected string with visible characters')),
Schema.brand('VisibleString'),
Schema.annotations({
identifier: 'VisibleString',
title: 'String with visible characters',
description:
'A string that contains at least one visible character (non-whitespace and non-control character).',
jsonSchema: {
minLength: 1,
pattern: REG_EXP.source,
},
arbitrary: () => (fc) => fc.uuid() as never,
})
);
export const UUID = Schema.UUID.pipe(
Schema.compose(VisibleString),
Schema.brand('UUID'),
Schema.annotations({
identifier: 'UUID',
title: 'UUID',
description: 'A string that represents a UUID.',
jsonSchema: {
format: 'uuid',
},
arbitrary: () => (fc) => fc.uuid() as never,
})
);
const defs = {}
const res = JSONSchema.fromAST(UUID.ast, {
definitions: defs,
definitionPath: "#/components/schemas/",
target: "openApi3.1",
})
console.log(res, defs)import { JSONSchema, Schema } from 'effect';
// We don't use Unicode property escapes because they are not supported in OpenAI API :-(
// biome-ignore lint/suspicious/noControlCharactersInRegex: YOLO
const REG_EXP = /[^\s\x00-\x1F\x7F-\x9F]+/;
export const VisibleString = Schema.String.pipe(
Schema.filter((s) => (REG_EXP.test(s) ? undefined : 'Expected string with visible characters')),
Schema.brand('VisibleString'),
Schema.annotations({
identifier: 'VisibleString',
title: 'String with visible characters',
description:
'A string that contains at least one visible character (non-whitespace and non-control character).',
jsonSchema: {
minLength: 1,
pattern: REG_EXP.source,
},
arbitrary: () => (fc) => fc.uuid() as never,
})
);
export const UUID = Schema.UUID.pipe(
Schema.compose(VisibleString),
Schema.brand('UUID'),
Schema.annotations({
identifier: 'UUID',
title: 'UUID',
description: 'A string that represents a UUID.',
jsonSchema: {
format: 'uuid',
},
arbitrary: () => (fc) => fc.uuid() as never,
})
);
const defs = {}
const res = JSONSchema.fromAST(UUID.ast, {
definitions: defs,
definitionPath: "#/components/schemas/",
target: "openApi3.1",
})
console.log(res, defs)Console.log output:
res: { '$ref': '#/components/schemas/UUID' }
defs: { UUID: { format: 'uuid' } }res: { '$ref': '#/components/schemas/UUID' }
defs: { UUID: { format: 'uuid' } }I expect
defsdefs value to be{
UUID: {
type: 'string',
description: 'A string that represents a UUID.',
title: 'UUID',
format: 'uuid'
}
}{
UUID: {
type: 'string',
description: 'A string that represents a UUID.',
title: 'UUID',
format: 'uuid'
}
}This behavior screws documentation generated by
HttpApiScalarHttpApiScalar service.