Skip to content

Zod Validator Generator — sdk-generator - #81

Merged
cb-alish merged 13 commits into
mainfrom
validator/chargebee-node
May 20, 2026
Merged

Zod Validator Generator — sdk-generator#81
cb-alish merged 13 commits into
mainfrom
validator/chargebee-node

Conversation

@cb-alish

Copy link
Copy Markdown
Contributor

Zod Validator Generator — sdk-generator

Overview

The validator generator is a subsystem inside sdk-generator that automatically produces
Zod validation files for chargebee-node (v3) and chargebee-typescript-typings (v3)
from the same OpenAPI specification used to generate the SDK itself.

The design is intentionally split into two independent layers:

  1. Validation IR — a language-agnostic tree that describes what to validate
  2. Language AST + Printer — describes how to express those constraints in TypeScript/Zod

This separation means the IR is built once from the spec and the Zod emitter is a pure
function from IR → TypeScript source. Adding a new validation target in future (Pydantic,
Zod for Go, etc.) only requires writing a new emitter — the IR layer should not change.


@snyk-io

snyk-io Bot commented Apr 21, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cb-alish cb-alish changed the title Validator/chargebee node Zod Validator Generator — sdk-generator Apr 21, 2026

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 9.2 - Very Complex

View Breakdown
  • Lines Changed: 1503
  • Files Changed: 19
  • Complexity Added: 210
  • Raw Score: 402.06
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
Overview

This PR introduces a new Zod-based validator generation pipeline into sdk-generator, producing TypeScript validation schemas for chargebee-node and associated typings from the OpenAPI spec. It defines a language-agnostic validation IR, a minimal JS/TS AST with a printer, and a Zod-specific emitter wired into the existing Lang/Language system. It also adds an enableValidation configuration flag to the TypeScript typings so clients can opt into parameter validation before HTTP calls.

Key Changes
  • Adds a validation subsystem documentation (VALIDATOR_GENERATOR.md) describing architecture, pipeline, naming strategy, and extensibility for Zod validators.
  • Introduces Lang.VALIDATOR_ZOD and a ValidatorZod Language implementation that invokes a ValidatorEmitter to generate Zod validators, with directory cleaning enabled before generation.
  • Defines a language-agnostic Validation IR (ValidationNode, PropertyEntry, ValidationIRBuilder, SharedSchemaRegistry) that converts OpenAPI schemas into a structured tree, handling $refs, multi-value attributes (x-cb-is-multi-value-attribute), hidden properties, and requiredness hints.
  • Implements a minimal JS/TS AST and printer (JsNode, JsBuilder, TsPrinter) to build TypeScript source via AST rather than string templates, supporting imports, exports, method chains, objects, arrays, and literals.
  • Adds a Zod-specific emitter (ZodTsEmitter, ZodTypeMapper, ZodNamingStrategy) that maps the IR to Zod schemas, generates per-action .validation.ts files, a shared.validation.ts for shared $ref schemas, and an index.ts barrel, using z.looseObject for unknown-key-tolerant schemas and consistent naming conventions.
  • Extends the TypeScript typings (core.d.ts.hbs, v3/core.d.ts.hbs, v3/index.d.ts.hbs) to include an optional enableValidation flag on configuration/request config types, with tests updated to reflect the new field and documentation comment.
Risks & Considerations
  • Correctness of the IR builder (ValidationIRBuilder) is critical: bugs in $ref handling, multi-value attribute detection, or required/optional inference could generate incorrect validators and break client validation.
  • The Zod mapping (ZodTypeMapper) must stay in sync with Zod v4 semantics (e.g., z.looseObject vs .passthrough()); future Zod changes could require emitter adjustments.
  • The emitter assumes POST actions with application/x-www-form-urlencoded bodies; if specs introduce different content types or methods that should be validated, additional handling may be needed.
  • Generated import paths (../shared.validation.js, ./... .js) and JS vs TS file naming must be consistent with the runtime bundling/build configuration of chargebee-node; mismatches could cause runtime module resolution issues.
  • The new enableValidation flag is purely typings-level here; consumers might expect runtime validation behavior, so coordination with the runtime implementation is necessary to avoid confusion.
  • Performance and payload size impact of client-side validation is not addressed here; enabling validation on large or high-throughput workloads might introduce noticeable overhead.
File-level change summary
File Change summary
VALIDATOR_GENERATOR.md Adds comprehensive documentation for the new Zod validator generator architecture, pipeline, and design decisions.
src/main/java/com/chargebee/Main.java Registers the new VALIDATOR_ZOD language option and wires it to the ValidatorZod implementation.
src/main/java/com/chargebee/sdk/validator/ValidatorEmitter.java Introduces a common interface for validator emitters that produce FileOp lists from a spec and shared schema registry.
src/main/java/com/chargebee/sdk/validator/ValidatorZod.java Implements a Language subclass that invokes the Zod validator emitter and always cleans the output directory before generation.
src/main/java/com/chargebee/sdk/validator/ast/js/JsBuilder.java Adds a fluent factory for constructing JS/TS AST nodes used by the validator emitter.
src/main/java/com/chargebee/sdk/validator/ast/js/JsNode.java Defines a sealed JS/TS AST node hierarchy for programs, imports, exports, calls, objects, arrays, identifiers, and literals.
src/main/java/com/chargebee/sdk/validator/ast/js/TsPrinter.java Implements a printer that converts the JS/TS AST into formatted TypeScript source with ES-style imports/exports.
src/main/java/com/chargebee/sdk/validator/emitter/zod/ZodNamingStrategy.java Provides centralized naming conventions for Zod file names, schema constants, shared schemas, and resource directories.
src/main/java/com/chargebee/sdk/validator/emitter/zod/ZodTsEmitter.java Walks the OpenAPI spec to build IR, map it to Zod AST, and emit per-action validator files, a shared schema file, and an index barrel.
src/main/java/com/chargebee/sdk/validator/emitter/zod/ZodTypeMapper.java Maps ValidationNode IR types to Zod AST expressions, including object, array, string, number, boolean, map, and ref handling with .optional().
src/main/java/com/chargebee/sdk/validator/ir/PropertyEntry.java Introduces a record that wraps a ValidationNode with field-level metadata such as requiredness, defaults, and description.
src/main/java/com/chargebee/sdk/validator/ir/SharedSchemaRegistry.java Adds a registry to collect and expose shared $ref schemas for emission into a common validation file.
src/main/java/com/chargebee/sdk/validator/ir/ValidationIRBuilder.java Implements recursive OpenAPI SchemaValidationNode IR conversion, including $ref resolution, multi-value attribute flattening, and hidden/required rules.
src/main/java/com/chargebee/sdk/validator/ir/ValidationNode.java Defines the sealed validation IR node types (object, string, number, boolean, array, map, ref) used by all validator emitters.
src/main/resources/templates/ts/typings/core.d.ts.hbs Extends the v2 typings’ RequestConfig with an optional enableValidation boolean and accompanying documentation comment.
src/main/resources/templates/ts/typings/v3/core.d.ts.hbs Extends the v3 typings’ RequestConfig with an optional enableValidation boolean and documentation comment.
src/main/resources/templates/ts/typings/v3/index.d.ts.hbs Adds an enableValidation?: boolean field with documentation to the top-level Config type in the v3 typings index.
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingTests.java Updates expected core typings snapshot string to include the new enableValidation field and its doc comment for v2.
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java Updates v3 typings snapshot expectations (core and index) to include the new enableValidation field and its documentation.

Comment thread VALIDATOR_GENERATOR.md
Comment thread VALIDATOR_GENERATOR.md

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 1.3 - Trivial

View Breakdown
  • Lines Changed: 22
  • Files Changed: 2
  • Complexity Added: 0
  • Raw Score: 6.44
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
Overview

This PR extends the TypeScript v3 typings for the Chargebee SDK to expose the new request validation feature and associated error type. It adds an enableValidation configuration flag to the SDK config typings and introduces a ChargebeeZodValidationError class in the typings. The tests for TypeScript typing generation are updated to assert the new declarations.

Key Changes
  • Adds an optional enableValidation?: boolean property to the Config type (and RequestConfig in tests) in the TypeScript typings, documenting that when enabled, POST action arguments are validated against Zod schemas before the HTTP call.
  • Introduces a ChargebeeZodValidationError class in the typings, carrying actionName and the original ZodError to allow programmatic handling of validation failures.
  • Updates TypeScript typing generation tests to match the new enableValidation option and ChargebeeZodValidationError declarations in the generated index.d.ts.
Risks & Considerations
  • TypeScript projects consuming these typings may now see a reference to import('zod').ZodError; reviewers should confirm that this does not introduce an unintended runtime or type dependency issue for consumers without Zod installed.
  • The documentation string for enableValidation is verbose and embedded in generated typings; ensure this is acceptable for SDK consumers and does not exceed tooling limits for comment size.
File-level change summary
File Change summary
src/main/resources/templates/ts/typings/v3/index.d.ts.hbs Adds enableValidation to the Chargebee config interface and declares the ChargebeeZodValidationError class in the v3 TypeScript typings template.
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java Updates expected generated index.d.ts strings in tests to include the new enableValidation property and ChargebeeZodValidationError class.

@cb-alish
cb-alish force-pushed the validator/chargebee-node branch from e03ad48 to 09581cd Compare May 5, 2026 14:28

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 4.7 - Moderate

View Breakdown
  • Lines Changed: 266
  • Files Changed: 6
  • Complexity Added: 43
  • Raw Score: 87.82
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
Overview

This PR adds a new ZodTsEmitter to generate TypeScript Zod validator files from the OpenAPI spec for request bodies and query parameters. It also exposes a new enableValidation configuration flag in the TypeScript typings for both v2 and v3 clients and introduces a typed ChargebeeZodValidationError surface. Existing TypeScript typing tests are updated to assert the new fields and error class.

Key Changes
  • Introduces ZodTsEmitter, a ValidatorEmitter implementation that:
    • Emits per-resource, per-action .validation.ts files for POST bodies and GET query parameters, using Zod schemas derived from the OpenAPI spec and ValidationIRBuilder.
    • Builds a shared shared.validation.ts file for reusable $ref schemas and a barrel index.ts that re-exports shared and per-action validators.
    • For GET operations, synthesizes an ObjectSchema from query parameters (with required inferred from Parameter.required) and always treats the top-level body/query object as allowing unknown keys.
  • Adds enableValidation?: boolean to RequestConfig typings (v2 & v3 core typings), documenting that when enabled, request parameters are validated against generated Zod schemas before each HTTP call (where available).
  • Extends v3 typings to include an enableValidation flag on the main Config type with detailed JSDoc explaining behavior (validation of params as {}, error shape, and separate path-id checks).
  • Defines a new ChargebeeZodValidationError class in v3 typings, carrying actionName and the underlying import('zod').ZodError for programmatic error handling when validation fails.
  • Updates TypeScript typing tests to reflect the new enableValidation fields and the ChargebeeZodValidationError type in the expected flattened declaration strings.
Risks & Considerations
  • The emitter currently targets POST bodies (with application/x-www-form-urlencoded) and GET query parameters only; other HTTP methods or content types are not validated and may surprise users expecting broader coverage.
  • Top-level schemas always allowing unknown keys may diverge from stricter OpenAPI definitions and could mask unexpected extra parameters.
  • The correctness of the synthesized query-parameter object schema (including required flags) depends on accurate OpenAPI parameter metadata; mis-specified specs could lead to false positives/negatives.
  • The code assumes the presence of Zod in the TypeScript runtime environment (import('zod').ZodError); consumers must ensure Zod is installed and compatible.
  • Barrel and relative import paths (*.validation.js) must align with the rest of the build/bundling pipeline; any change in output extension strategy could break the generated imports.
File-level change summary
File Change summary
src/main/java/com/chargebee/sdk/validator/emitter/zod/ZodTsEmitter.java Adds a new emitter that generates Zod-based TypeScript validator files for POST bodies and GET query parameters, including shared schemas and an index barrel.
src/main/resources/templates/ts/typings/core.d.ts.hbs Extends the v2 RequestConfig declaration with an optional enableValidation flag and documentation describing Zod-based request validation.
src/main/resources/templates/ts/typings/v3/core.d.ts.hbs Extends the v3 RequestConfig declaration with an optional enableValidation flag and corresponding documentation.
src/main/resources/templates/ts/typings/v3/index.d.ts.hbs Adds enableValidation to the main v3 Config type with detailed JSDoc and declares the ChargebeeZodValidationError class exposing Zod error details.
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingTests.java Updates v2 typings tests to expect the new enableValidation property and its doc comment in the generated TypeScript declarations.
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java Updates v3 typings tests to include enableValidation and ChargebeeZodValidationError in the expected declaration output for index and core typings.

@hivel-marco

hivel-marco Bot commented May 8, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

…erred types

Emit Zod validators as flat src/schema/<resource>.schema.ts files (plus
shared.schema.ts) instead of per-action paths under src/validation/. Each
resource module includes all validateable actions in sort order, with blank
lines between sections for readability.

- Use PascalCase for body and nested schema const names (ZodNamingStrategy).
- Add export type <Action><Resource>Body = z.infer<typeof …BodySchema> per action
  via new JsNode.TypeInferExport and TsPrinter support.
- Rename shared bundle to shared.schema.ts; update index barrel and docs.

Tests and VALIDATOR_GENERATOR.md are updated. Consumers (e.g. chargebee-node)
must point VALIDATOR_ZOD at src/schema and update the runtime schema loader.
@cb-alish
cb-alish force-pushed the validator/chargebee-node branch from d3de84e to 26a8b5e Compare May 11, 2026 05:24
…y files

Update chargebee_cjs.ts.hbs and chargebee_esm.ts.hbs templates to export
the ChargebeeZodValidationError class alongside webhook utilities, ensuring
validation error is available to SDK consumers in both module systems.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hivel-marco

hivel-marco Bot commented May 11, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

2 similar comments
@hivel-marco

hivel-marco Bot commented May 11, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

@hivel-marco

hivel-marco Bot commented May 11, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

@hivel-marco

hivel-marco Bot commented May 13, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

@cb-alish
cb-alish merged commit fd7fa04 into main May 20, 2026
5 checks passed
@cb-alish
cb-alish deleted the validator/chargebee-node branch May 20, 2026 04:52
@hivel-marco

hivel-marco Bot commented May 20, 2026

Copy link
Copy Markdown
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/test/java/com/chargebee/sdk/ts/typings/TypeScriptTypingV3Tests.java
LineTypePreview
93Secret: Passwordpassword:__string,__...
377Secret: Passwordpassword:__string,__...
Password2
PR has too many lines changed - Skipping review. Please keep lines changed under 2000 for high quality reviews

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants