Conversation
WalkthroughAdds multipart/form-data and application/x-www-form-urlencoded support: new OpenAPI spec and tests, content-type-aware request-body selection, nameMap-aware request-type resolution, refined Zod schema generation for defaults/optionality, and runtime-safe binary handling. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/zenko/src/core/schema-generator.ts (1)
159-169:.default()on required properties changes requiredness (likely unintended)
In Zod,.default(x)acceptsundefinedinput (i.e., it effectively makes the field optional). As written, required OpenAPI properties that also havedefaultwill become optional at runtime. If you want to preserve requiredness, only apply defaults for non-required properties (or gate with an option). Based on learnings, keep required/optional semantics crisp.- const finalType = applyDefaultModifier(withOptionality, propSchema as any) + const finalType = isRequired + ? withOptionality + : applyDefaultModifier(withOptionality, propSchema as any)Also applies to: 233-236
🧹 Nitpick comments (5)
packages/zenko/src/utils/collect-inline-types.ts (2)
71-85: Good content-type-aware request schema selection; consider deduping shared logic
This is a solid extension for multipart and urlencoded bodies, and the!schemaguard avoids accidental generation on missing content. One follow-up: the operation lookup building (paths + webhooks) is duplicated in bothcollectInlineRequestTypesandcollectInlineResponseTypes; consider extracting a small helper to reduce drift risk.
90-105: Prefer a shared constant/helper for preferred request content-types (also used in operation-parser.ts)
preferredTypesis now defined here and again inpackages/zenko/src/core/operation-parser.ts. Consider exporting a single constant (e.g., fromutils/schema-utils.ts) to keep ordering consistent across the generator pipeline.packages/zenko/src/core/operation-parser.ts (1)
140-173: Deduplicate requestBody schema selection logic across modules
getRequestBodySchema()duplicatesfindRequestBodySchema()inpackages/zenko/src/utils/collect-inline-types.ts(same preferredTypes order). Consider moving this to a shared util (or exporting one from the other) to avoid future mismatches.packages/zenko/src/resources/form-data.yaml (1)
135-252: ConsidermaxItemsfor arrays (or suppress Checkov for test specs)
CKV_OPENAPI_21 flags arrays likeMultiFileUpload.filesandDocumentUpload.tags. If you want to satisfy the rule, add reasonablemaxItemsvalues; otherwise consider excluding this spec from that rule since it’s for codegen coverage, not an operational API contract.packages/zenko/src/__tests__/form-data.test.ts (1)
6-216: DRY loading/generation; prefer snapshots for output verification per guidelines
Nearly every test repeats read → parse → generate, and many assertions are broadtoContainchecks. Consider a sharedgetGenerated()helper (orbeforeAll) and snapshot the relevant sections (schemas, operations) to reduce brittleness and runtime. As per coding guidelines.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
packages/zenko/src/__tests__/__snapshots__/form-data.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (7)
packages/zenko/src/__tests__/form-data.test.ts(1 hunks)packages/zenko/src/core/__tests__/operation-parser.test.ts(1 hunks)packages/zenko/src/core/operation-parser.ts(3 hunks)packages/zenko/src/core/schema-generator.ts(3 hunks)packages/zenko/src/resources/form-data.yaml(1 hunks)packages/zenko/src/utils/__tests__/collect-inline-types.test.ts(1 hunks)packages/zenko/src/utils/collect-inline-types.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Organize imports in order: built-in → third-party → local; always use double quotes
Use 2-space indentation with no semicolons and trailing commas (ES5 style) with 80 character line width
Use camelCase for variable and function names; use PascalCase for classes and types
Prefer Result-style returns or descriptive throws for error handling
Files:
packages/zenko/src/core/__tests__/operation-parser.test.tspackages/zenko/src/utils/__tests__/collect-inline-types.test.tspackages/zenko/src/core/operation-parser.tspackages/zenko/src/core/schema-generator.tspackages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/utils/collect-inline-types.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Export inferred Zod types and maintain strict TypeScript settings with
noUncheckedIndexedAccessandnoUnusedLocalsenabled
Files:
packages/zenko/src/core/__tests__/operation-parser.test.tspackages/zenko/src/utils/__tests__/collect-inline-types.test.tspackages/zenko/src/core/operation-parser.tspackages/zenko/src/core/schema-generator.tspackages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/utils/collect-inline-types.ts
packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Store test specifications in
packages/zenko/src/__tests__and use snapshots for output verification
Files:
packages/zenko/src/__tests__/form-data.test.ts
🧠 Learnings (4)
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx} : Store test specifications in `packages/zenko/src/__tests__` and use snapshots for output verification
Applied to files:
packages/zenko/src/core/__tests__/operation-parser.test.tspackages/zenko/src/utils/__tests__/collect-inline-types.test.tspackages/zenko/src/__tests__/form-data.test.ts
📚 Learning: 2025-10-16T00:11:55.898Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 15
File: packages/zenko/src/zenko.ts:917-921
Timestamp: 2025-10-16T00:11:55.898Z
Learning: In packages/zenko/src/zenko.ts, the `response` field in operation objects can contain TypeScript type expressions like `z.ZodArray<typeof SchemaName>` for inline array responses. These expressions are intended for type definitions and type checking, not for runtime validation. Users should not attempt to use these type expressions as runtime Zod schemas.
Applied to files:
packages/zenko/src/core/__tests__/operation-parser.test.tspackages/zenko/src/utils/__tests__/collect-inline-types.test.tspackages/zenko/src/core/operation-parser.tspackages/zenko/src/core/schema-generator.tspackages/zenko/src/utils/collect-inline-types.ts
📚 Learning: 2025-10-31T22:24:57.504Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 34
File: packages/zenko/src/__tests__/config-options.test.ts:473-556
Timestamp: 2025-10-31T22:24:57.504Z
Learning: In the zenko package, the `optionalType` configuration option has three distinct behaviors aligned with Zod semantics: `optional` generates `.optional()` (field can be undefined/omitted), `nullable` generates `.nullable()` (field must be present but can be null), and `nullish` generates `.nullish()` (field can be undefined OR null). The `nullable` option intentionally does NOT add `.optional()`, as that would change the required/optional nature of the field.
Applied to files:
packages/zenko/src/core/schema-generator.ts
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to **/*.{ts,tsx} : Export inferred Zod types and maintain strict TypeScript settings with `noUncheckedIndexedAccess` and `noUnusedLocals` enabled
Applied to files:
packages/zenko/src/core/schema-generator.ts
🧬 Code graph analysis (3)
packages/zenko/src/core/operation-parser.ts (2)
packages/zenko/src/utils/topological-sort.ts (1)
extractRefName(62-64)packages/zenko/src/utils/string-utils.ts (2)
capitalize(15-17)toCamelCase(5-9)
packages/zenko/src/__tests__/form-data.test.ts (1)
packages/examples/generate.js (1)
specContent(14-14)
packages/zenko/src/utils/collect-inline-types.ts (1)
packages/zenko/src/utils/string-utils.ts (2)
capitalize(15-17)toCamelCase(5-9)
🪛 Checkov (3.2.334)
packages/zenko/src/resources/form-data.yaml
[high] 1-357: Ensure that the global security field has rules defined
(CKV_OPENAPI_4)
[high] 1-357: Ensure that security operations is not empty.
(CKV_OPENAPI_5)
[medium] 142-148: Ensure that arrays have a maximum number of items
(CKV_OPENAPI_21)
🔇 Additional comments (6)
packages/zenko/src/utils/__tests__/collect-inline-types.test.ts (1)
175-175: Test name update matches expanded content-type support.Rename accurately reflects that request schemas may now be collected from JSON or form content types; no further changes needed here.
packages/zenko/src/core/schema-generator.ts (1)
181-186: Binary handling is pragmatic; verify Zod + runtime expectations
TheBlobguard keeps this generator output safe across runtimes, andFileshould also satisfyinstanceof Blobin browsers. Please double-check this aligns with your intended request-body runtime validation behavior (especially if Node < 18 is a target, whereBlobmay not exist).packages/zenko/src/core/operation-parser.ts (1)
19-54: nameMap propagation for requestType is a good consistency win
PassingnameMapthroughparseOperationstogetRequestTypekeeps request/response naming aligned (matches the updated test expectation).Also applies to: 58-94
packages/zenko/src/core/__tests__/operation-parser.test.ts (1)
156-165: Test expectation update matches new nameMap-based request type resolutionpackages/zenko/src/resources/form-data.yaml (2)
44-64: No action required. Theencoding.avatar.contentTypeformat is valid per OpenAPI 3.0 specification, which explicitly allows comma-separated media type values in the Encoding Object's contentType field.
1-357: The original review comment raises a concern about Checkov OpenAPI security findings (CKV_OPENAPI_4/5) breaking CI, but this is not applicable to this codebase. Investigation reveals:
No Checkov in CI: The CI pipeline (
.github/workflows/ci.yml) does not run Checkov or any OpenAPI-specific security validation. It runs formatting, linting, type checking, and tests only.Test spec convention: The
form-data.yamlfile is a test/example OpenAPI specification alongside other similar specs inpackages/zenko/src/resources/(e.g.,petstore.yaml,date-enum.yaml,string-formats.yaml, etc.). Most of these test specs lack security definitions, which is appropriate for test data.Project context: Zenko is a TypeScript code generator from OpenAPI specs, not a service that requires security validation of test fixtures.
Adding security schemes to test data is unnecessary and inconsistent with the existing codebase patterns.
Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
packages/zenko/src/__tests__/form-data.test.ts (3)
1-1: Consider sorting destructured imports alphabetically for consistency.The destructured imports from
"bun:test"could be alphabetically ordered asdescribe, expect, testrather thandescribe, test, expect.Apply this diff:
-import { describe, test, expect } from "bun:test" +import { describe, expect, test } from "bun:test"
10-13: Extract common spec loading and parsing to reduce duplication.The pattern of reading the spec file, parsing YAML, and calling
generate()is repeated across all 13 test cases. Extract this to a helper function or use a shared setup to improve maintainability.Example refactor:
describe("Form Data", () => { const specPath = path.join(import.meta.dir, "../resources/form-data.yaml") const loadAndGenerate = (options = {}) => { const specContent = fs.readFileSync(specPath, "utf8") const specYaml = jsYaml.load(specContent) as OpenAPISpec return generate(specYaml, options) } test("generates complete TypeScript output", () => { const result = loadAndGenerate() expect(result).toMatchSnapshot("form-data-complete-output") }) // ... other tests using loadAndGenerate() })
194-204: Clarify test intent or add assertions for password format handling.The test checks that the
passwordfield exists but doesn't verify any special handling. If the password format should have specific behavior (e.g., specific Zod validators, patterns, or constraints), add assertions to verify it. Otherwise, clarify the test's purpose or consider whether it's needed.packages/zenko/src/core/schema-generator.ts (1)
241-244:applyDefaultModifier: consider guarding for non-JSON-safe defaults (or fail loudly)
JSON.stringify(schema.default)can produce surprising output for non-JSON values (e.g.,Infinity→null) and will throw on some inputs. If OpenAPI defaults are guaranteed JSON-safe in your pipeline, this is fine; otherwise consider validating and throwing a descriptive error (or falling back to no default) to avoid silently generating incorrect code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/zenko/src/__tests__/form-data.test.ts(1 hunks)packages/zenko/src/core/schema-generator.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Organize imports in order: built-in → third-party → local; always use double quotes
Use 2-space indentation with no semicolons and trailing commas (ES5 style) with 80 character line width
Use camelCase for variable and function names; use PascalCase for classes and types
Prefer Result-style returns or descriptive throws for error handling
Files:
packages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/core/schema-generator.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Export inferred Zod types and maintain strict TypeScript settings with
noUncheckedIndexedAccessandnoUnusedLocalsenabled
Files:
packages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/core/schema-generator.ts
packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Store test specifications in
packages/zenko/src/__tests__and use snapshots for output verification
Files:
packages/zenko/src/__tests__/form-data.test.ts
🧠 Learnings (4)
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx} : Store test specifications in `packages/zenko/src/__tests__` and use snapshots for output verification
Applied to files:
packages/zenko/src/__tests__/form-data.test.ts
📚 Learning: 2025-10-31T22:24:57.504Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 34
File: packages/zenko/src/__tests__/config-options.test.ts:473-556
Timestamp: 2025-10-31T22:24:57.504Z
Learning: In the zenko package, the `optionalType` configuration option has three distinct behaviors aligned with Zod semantics: `optional` generates `.optional()` (field can be undefined/omitted), `nullable` generates `.nullable()` (field must be present but can be null), and `nullish` generates `.nullish()` (field can be undefined OR null). The `nullable` option intentionally does NOT add `.optional()`, as that would change the required/optional nature of the field.
Applied to files:
packages/zenko/src/core/schema-generator.ts
📚 Learning: 2025-10-16T00:11:55.898Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 15
File: packages/zenko/src/zenko.ts:917-921
Timestamp: 2025-10-16T00:11:55.898Z
Learning: In packages/zenko/src/zenko.ts, the `response` field in operation objects can contain TypeScript type expressions like `z.ZodArray<typeof SchemaName>` for inline array responses. These expressions are intended for type definitions and type checking, not for runtime validation. Users should not attempt to use these type expressions as runtime Zod schemas.
Applied to files:
packages/zenko/src/core/schema-generator.ts
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to **/*.{ts,tsx} : Export inferred Zod types and maintain strict TypeScript settings with `noUncheckedIndexedAccess` and `noUnusedLocals` enabled
Applied to files:
packages/zenko/src/core/schema-generator.ts
🧬 Code graph analysis (1)
packages/zenko/src/__tests__/form-data.test.ts (1)
packages/examples/generate.js (1)
specContent(14-14)
🔇 Additional comments (1)
packages/zenko/src/__tests__/form-data.test.ts (1)
7-8: Path resolution issue has been fixed.The previous review concern about cwd-dependent path resolution has been addressed. Using
import.meta.dir(Bun's built-in property) correctly resolves the spec path relative to the test file, ensuring tests work regardless of the process working directory.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
packages/zenko/src/core/schema-generator.ts (2)
162-175: Inline the redundantfinalTypevariable.The
finalTypevariable is assigned once and used immediately. Inline it directly into theproperties.pushcall for clarity.Apply this diff:
- const finalType = isRequired ? baseType : withDefault - - properties.push(` ${formatPropertyName(propName)}: ${finalType},`) + properties.push(` ${formatPropertyName(propName)}: ${isRequired ? baseType : withDefault},`)
189-192: Use double quotes for the generated string literal (guideline compliance).The coding guidelines require double quotes. Change the outer quotes from single to double.
Apply this diff:
- return '(typeof Blob === "undefined" ? z.unknown() : z.instanceof(Blob))' + return "(typeof Blob === \"undefined\" ? z.unknown() : z.instanceof(Blob))"
🧹 Nitpick comments (1)
packages/zenko/src/__tests__/form-data.test.ts (1)
1-5: Reorder imports to follow coding guidelines.Imports should be organized as built-in → third-party → local. Move
fsandpathto the top.Apply this diff:
-import { describe, test, expect } from "bun:test" import * as fs from "fs" import * as path from "path" +import { describe, test, expect } from "bun:test" import jsYaml from "js-yaml" import { generate, type OpenAPISpec } from "../zenko"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/zenko/src/__tests__/form-data.test.ts(1 hunks)packages/zenko/src/core/schema-generator.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Organize imports in order: built-in → third-party → local; always use double quotes
Use 2-space indentation with no semicolons and trailing commas (ES5 style) with 80 character line width
Use camelCase for variable and function names; use PascalCase for classes and types
Prefer Result-style returns or descriptive throws for error handling
Files:
packages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/core/schema-generator.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Export inferred Zod types and maintain strict TypeScript settings with
noUncheckedIndexedAccessandnoUnusedLocalsenabled
Files:
packages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/core/schema-generator.ts
packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Store test specifications in
packages/zenko/src/__tests__and use snapshots for output verification
Files:
packages/zenko/src/__tests__/form-data.test.ts
🧠 Learnings (4)
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to packages/zenko/src/__tests__/**/*.{ts,tsx,test.ts,test.tsx,spec.ts,spec.tsx} : Store test specifications in `packages/zenko/src/__tests__` and use snapshots for output verification
Applied to files:
packages/zenko/src/__tests__/form-data.test.ts
📚 Learning: 2025-10-16T00:11:55.898Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 15
File: packages/zenko/src/zenko.ts:917-921
Timestamp: 2025-10-16T00:11:55.898Z
Learning: In packages/zenko/src/zenko.ts, the `response` field in operation objects can contain TypeScript type expressions like `z.ZodArray<typeof SchemaName>` for inline array responses. These expressions are intended for type definitions and type checking, not for runtime validation. Users should not attempt to use these type expressions as runtime Zod schemas.
Applied to files:
packages/zenko/src/__tests__/form-data.test.tspackages/zenko/src/core/schema-generator.ts
📚 Learning: 2025-10-31T22:24:57.504Z
Learnt from: RawToast
Repo: RawToast/zenko PR: 34
File: packages/zenko/src/__tests__/config-options.test.ts:473-556
Timestamp: 2025-10-31T22:24:57.504Z
Learning: In the zenko package, the `optionalType` configuration option has three distinct behaviors aligned with Zod semantics: `optional` generates `.optional()` (field can be undefined/omitted), `nullable` generates `.nullable()` (field must be present but can be null), and `nullish` generates `.nullish()` (field can be undefined OR null). The `nullable` option intentionally does NOT add `.optional()`, as that would change the required/optional nature of the field.
Applied to files:
packages/zenko/src/core/schema-generator.ts
📚 Learning: 2025-11-24T15:55:12.838Z
Learnt from: CR
Repo: RawToast/zenko PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T15:55:12.838Z
Learning: Applies to **/*.{ts,tsx} : Export inferred Zod types and maintain strict TypeScript settings with `noUncheckedIndexedAccess` and `noUnusedLocals` enabled
Applied to files:
packages/zenko/src/core/schema-generator.ts
🧬 Code graph analysis (1)
packages/zenko/src/__tests__/form-data.test.ts (1)
packages/examples/generate.js (1)
specContent(14-14)
🔇 Additional comments (2)
packages/zenko/src/core/schema-generator.ts (1)
240-243: LGTM!The
applyDefaultModifierhelper is well-designed. It correctly guards against undefined schemas and usesJSON.stringifyto safely serialize default values into the generated code.packages/zenko/src/__tests__/form-data.test.ts (1)
7-228: Excellent test coverage for form-data handling!The test suite comprehensively validates multipart/form-data and application/x-www-form-urlencoded scenarios, including binary handling, nested objects, arrays, encoding specifications, and validation constraints. All previously flagged assertion gaps have been addressed.
|
@coderabbitai generate docstrings |
✅ Actions performedInitiated docstring generation; will generate only if new commits exist. |
|
Note Docstrings generation - SUCCESS |
Docstrings generation was requested by @RawToast. * #44 (comment) The following files were modified: * `packages/zenko/src/core/operation-parser.ts` * `packages/zenko/src/core/schema-generator.ts` * `packages/zenko/src/utils/collect-inline-types.ts`
Docstrings generation was requested by @RawToast. * #44 (comment) The following files were modified: * `packages/zenko/src/core/operation-parser.ts` * `packages/zenko/src/core/schema-generator.ts` * `packages/zenko/src/utils/collect-inline-types.ts`
Summary by CodeRabbit
New Features
Tests
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.