Skip to content

Commit

Permalink
fix: readonly support for Zod and TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
stijnvanhulle committed Oct 16, 2023
1 parent d93668e commit a6e7557
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 4 deletions.
2 changes: 2 additions & 0 deletions examples/advanced/petStore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -831,9 +831,11 @@ components:
type: integer
format: int64
example: 10
readOnly: true
name:
type: string
example: doggie
writeOnly: true
category:
$ref: "#/components/schemas/Category"
photoUrls:
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/src/gen/models/ts/Pet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type Pet = {
* @type integer | undefined int64
* @example 10
*/
id?: number
readonly id?: number
/**
* @type string
* @example doggie
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/src/gen/zod/petSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { categorySchema } from './categorySchema'
import { tagSchema } from './tagSchema'

export const petSchema = z.object({
id: z.number().optional(),
id: z.number().readonly().optional(),
name: z.string(),
category: z.lazy(() => categorySchema).optional(),
photoUrls: z.array(z.string()),
Expand Down
11 changes: 9 additions & 2 deletions packages/parser/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,24 @@ export function createUnionDeclaration({ nodes, withParentheses }: { nodes: Arra
}

export function createPropertySignature({
modifiers,
readOnly,
modifiers = [],
name,
questionToken,
type,
}: {
readOnly?: boolean
modifiers?: Array<ts.Modifier>
name: ts.PropertyName | string
questionToken?: ts.QuestionToken | boolean
type?: ts.TypeNode
}) {
return factory.createPropertySignature(modifiers, propertyName(name), createQuestionToken(questionToken), type)
return factory.createPropertySignature(
[...modifiers, readOnly ? factory.createToken(ts.SyntaxKind.ReadonlyKeyword) : undefined].filter(Boolean) as Array<ts.Modifier>,
propertyName(name),
createQuestionToken(questionToken),
type,
)
}

export function createParameterSignature(
Expand Down
1 change: 1 addition & 0 deletions packages/swagger-ts/src/generators/TypeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OpenAPIV3.SchemaObje
questionToken: ['questionToken', 'questionTokenAndUndefined'].includes(optionalType) && !isRequired,
name,
type: type as ts.TypeNode,
readOnly: schema.readOnly,
})
if (this.options.withJSDocs) {
return appendJSDocToNode({
Expand Down
4 changes: 4 additions & 0 deletions packages/swagger-zod/src/generators/ZodGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ export class ZodGenerator extends SchemaGenerator<Options, OpenAPIV3.SchemaObjec
validationFunctions.push({ keyword: zodKeywords.uuid })
}

if (schema.readOnly) {
validationFunctions.push({ keyword: zodKeywords.readOnly })
}

if (schema.default !== undefined && !Array.isArray(schema.default)) {
if (typeof schema.default === 'string') {
validationFunctions.push({ keyword: zodKeywords.default, args: `'${schema.default}'` })
Expand Down
4 changes: 4 additions & 0 deletions packages/swagger-zod/src/parsers/zodParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const zodKeywords = {
max: 'max',
optional: 'optional',
catchall: 'catchall',
readOnly: 'readOnly',

// custom ones
ref: 'ref',
Expand Down Expand Up @@ -62,6 +63,7 @@ export const zodKeywordMapper: Record<ZodKeyword, string> = {
max: '.max',
optional: '.optional',
catchall: '.catchall',
readOnly: '.readonly',

// custom ones
ref: 'ref',
Expand Down Expand Up @@ -119,6 +121,7 @@ type ZodMetaEmail = { keyword: typeof zodKeywords.email }
type ZodMetaUuid = { keyword: typeof zodKeywords.uuid }

type ZodMetaUrl = { keyword: typeof zodKeywords.url }
type ZodMetaReadOnly = { keyword: typeof zodKeywords.readOnly }

export type ZodMeta =
| ZodMetaAny
Expand Down Expand Up @@ -149,6 +152,7 @@ export type ZodMeta =
| ZodMetaUuid
| ZodMetaLiteral
| ZodMetaUrl
| ZodMetaReadOnly

/**
*
Expand Down

1 comment on commit a6e7557

@vercel
Copy link

@vercel vercel bot commented on a6e7557 Oct 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kubb – ./

kubb-kubb.vercel.app
kubb-git-main-kubb.vercel.app
kubb.dev
www.kubb.dev

Please sign in to comment.