Skip to content
Merged

Zod #42

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "functional-models",
"version": "3.4.1",
"version": "3.5.1",
"description": "Functional models is ooey gooey framework for building and using awesome models EVERYWHERE.",
"main": "index.js",
"types": "index.d.ts",
Expand Down
18 changes: 17 additions & 1 deletion src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ const createZodForProperty =
}

const _getZodForPropertyType = (pt: any) => {
if (myConfig.choices) {
return z.enum(myConfig.choices as any)
}
switch (pt) {
case 'UniqueId':
return z.string()
Expand Down Expand Up @@ -319,7 +322,20 @@ const createZodForProperty =
? s.default(myConfig.defaultValue)
: s,
s => (myConfig.required ? s : s.optional()),
s => (myConfig.description ? s.describe(myConfig.description) : s),
// Attach description for Zod consumers and OpenAPI generators.
s => {
if (myConfig.description) {
// zod's describe helps Zod introspection; some zod-openapi versions expect metadata via .meta or .openapi
// Use .describe and also attach .meta with openapi description if available.
if (typeof s.openapi === 'function') {
return s.openapi({ description: myConfig.description })
}
return s.meta
? s.meta({ description: myConfig.description })
: s.describe(myConfig.description)
}
return s
},
])(schemaFromChoices)

return finalSchema as ZodType<any>
Expand Down
25 changes: 20 additions & 5 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,28 @@ const _convertOptions = <T extends DataDescription>(
return r
}

const _addDescription = (
schema: ZodObject<DataDescription>,
description?: string
) => {
if (!description) {
return schema
}
// @ts-ignore
if (typeof schema.openapi === 'function') {
// @ts-ignore
return schema.openapi({ description: description })
}
return schema.meta
? schema.meta({ description: description })
: schema.describe(description)
}

const _createZod = <T extends DataDescription>(
modelDefinition: MinimalModelDefinition<T>
): ZodObject<DataDescription> => {
if (modelDefinition.schema) {
if (modelDefinition.description) {
return modelDefinition.schema.describe(modelDefinition.description)
}
return modelDefinition.schema
return _addDescription(modelDefinition.schema, modelDefinition.description)
}
const properties = Object.entries(modelDefinition.properties).reduce(
(acc, [key, property]) => {
Expand All @@ -62,7 +76,8 @@ const _createZod = <T extends DataDescription>(
},
{} as Record<string, ZodType>
)
return z.object(properties) as ZodObject<DataDescription>
const obj = z.object(properties) as ZodObject<DataDescription>
return _addDescription(obj, modelDefinition.description)
}

const _toModelDefinition = <T extends DataDescription>(
Expand Down
2 changes: 1 addition & 1 deletion test/src/lib.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
createZodForProperty,
} from '../../src/lib'
import { ApiInfo, ApiMethod } from '../../src/index'
import z from 'zod'
import { z } from 'zod'

describe('/src/lib.ts', () => {
describe('#populateApiInformation', () => {
Expand Down