Skip to content

ivangreene/java-to-zod

Repository files navigation

Java to Zod

Convert POJOs to Zod schemas. Uses JSR-380 (bean validation) annotations to specify the constraints.

Why?

Write your schemas once, and use them for both frontend and backend validation.

Example

public class Person {
    @NotEmpty(message = "must not be empty")
    public String givenName;

    @NotEmpty
    public String surname;

    @Positive(message = "must be positive")
    public int age;

    @Email(message = "must be a valid email")
    public String email;

    @NotNull
    public AccountType accountType;
}

enum AccountType {
    PREMIUM,
    STANDARD,
    BASIC,
}

Running the java-to-zod plugin will give you:

const PersonSchema = zod.object({
  givenName: zod.string().min(1, { message: 'must not be empty' }),
  surname: zod.string().min(1),
  age: zod.number().int().positive({ message: 'must be positive' }),
  email: zod.string().email({ message: 'must be a valid email' }).optional().nullable(),
  accountType: zod.enum(['PREMIUM', 'STANDARD', 'BASIC']),
});

Goes well with typescript-generator, and shares many of the same configuration options for scanning source classes.

Example configuration for Maven plugin

<plugin>
  <groupId>sh.ivan</groupId>
  <artifactId>java-to-zod-maven-plugin</artifactId>
  <version>VERSION</version>
  <configuration>
    <jsonLibrary>jackson2</jsonLibrary>
    <outputFile>${project.basedir}/../frontend/generated-schemas.js</outputFile>
    <classPatterns>
      <classPattern>sh.ivan.pojo.**</classPattern>
    </classPatterns>
  </configuration>
  <executions>
    <execution>
      <id>generate</id>
      <goals>
        <goal>generate</goal>
      </goals>
      <phase>process-classes</phase>
    </execution>
  </executions>
</plugin>

See plugin configuration docs for all configuration properties.

Supported annotations