Zod Validator Generator — sdk-generator - #81
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
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
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
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_ZODand aValidatorZodLanguageimplementation that invokes aValidatorEmitterto 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.tsfiles, ashared.validation.tsfor shared$refschemas, and anindex.tsbarrel, usingz.looseObjectfor 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 optionalenableValidationflag 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$refhandling, 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.looseObjectvs.passthrough()); future Zod changes could require emitter adjustments. - The emitter assumes POST actions with
application/x-www-form-urlencodedbodies; 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 ofchargebee-node; mismatches could cause runtime module resolution issues. - The new
enableValidationflag 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 Schema → ValidationNode 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. |
There was a problem hiding this comment.
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
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
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?: booleanproperty to theConfigtype (andRequestConfigin tests) in the TypeScript typings, documenting that when enabled, POST action arguments are validated against Zod schemas before the HTTP call. - Introduces a
ChargebeeZodValidationErrorclass in the typings, carryingactionNameand the originalZodErrorto allow programmatic handling of validation failures. - Updates TypeScript typing generation tests to match the new
enableValidationoption andChargebeeZodValidationErrordeclarations in the generatedindex.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
enableValidationis 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. |
e03ad48 to
09581cd
Compare
There was a problem hiding this comment.
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
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
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, aValidatorEmitterimplementation that:- Emits per-resource, per-action
.validation.tsfiles for POST bodies and GET query parameters, using Zod schemas derived from the OpenAPI spec andValidationIRBuilder. - Builds a shared
shared.validation.tsfile for reusable$refschemas and a barrelindex.tsthat re-exports shared and per-action validators. - For GET operations, synthesizes an
ObjectSchemafrom query parameters (withrequiredinferred fromParameter.required) and always treats the top-level body/query object as allowing unknown keys.
- Emits per-resource, per-action
- Adds
enableValidation?: booleantoRequestConfigtypings (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
enableValidationflag on the mainConfigtype with detailed JSDoc explaining behavior (validation ofparamsas{}, error shape, and separate path-id checks). - Defines a new
ChargebeeZodValidationErrorclass in v3 typings, carryingactionNameand the underlyingimport('zod').ZodErrorfor programmatic error handling when validation fails. - Updates TypeScript typing tests to reflect the new
enableValidationfields and theChargebeeZodValidationErrortype 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
requiredflags) 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. |
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
…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.
d3de84e to
26a8b5e
Compare
…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>
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
2 similar comments
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
|
| File | Types | Count | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| 93 | Secret: Password | password:__string,__... |
| 377 | Secret: Password | password:__string,__... |
Zod Validator Generator — sdk-generator
Overview
The validator generator is a subsystem inside
sdk-generatorthat automatically producesZod validation files for
chargebee-node(v3) andchargebee-typescript-typings(v3)from the same OpenAPI specification used to generate the SDK itself.
The design is intentionally split into two independent layers:
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.