Skip to content

[TypeGen]: support external Zod schema overrides - #21

Merged
MistyKuu merged 3 commits into
MistyKuu:masterfrom
RejectKid:zod-schema-overrides
Sep 24, 2026
Merged

MistyKuu merged 3 commits into
MistyKuu:masterfrom
RejectKid:zod-schema-overrides

Conversation

@RejectKid

Copy link
Copy Markdown
Contributor

Summary

Adds a Zod-specific property override for C# types whose runtime validator is supplied by a frontend package or shared schema module.

[TsType] remains responsible for static TypeScript typing. The new [ZodSchema] attribute supplies the runtime Zod expression and optional named import:

[TsType("Point", ImportFrom = "geojson")]
[ZodSchema("GeoJSONPointSchema", ImportFrom = "zod-geojson")]
public Point? DeliveryAreaPoint { get; init; }

The same configuration is available fluently for referenced models:

b.ForType<OrderDto>()
    .Property(x => x.DeliveryAreaPoint)
    .ZodSchema("GeoJSONPointSchema", "zod-geojson");

Generated output:

import { GeoJSONPointSchema } from 'zod-geojson';

export const OrderDtoSchema = z.object({
    deliveryAreaPoint: GeoJSONPointSchema.nullish(),
});

Behavior

  • Replaces the inferred property validator, avoiding the current z.unknown() fallback.
  • Supports [ZodSchema("expression", ImportFrom = "module")] and both fluent overloads.
  • Supports inline expressions without imports, such as z.string().startsWith('ord_').
  • Groups and deduplicates external named imports in file-per-class and single-file layouts.
  • Preserves nullable, optional, read-only, and PatchField<T> modifiers after the override.
  • Treats the explicit schema as authoritative instead of appending inferred format or validation constraints.
  • Removes overridden C# property types from internal schema dependency, cycle, and topological-order analysis.
  • Works with z.compile(...), inferred types, generated guards, and TanStack payload validation.

The documentation also explains that z.toZod<T>() requires exact type equality. A schema merely assignable to a [TsType] type may not satisfy conformance. For zod-geojson, its own GeoJSONPoint and GeoJSONFeature inferred aliases support exact conformance.

Closes #20.

Affected package(s)

  • ZibStack.NET.TypeGen
  • ZibStack.NET.TypeGen.Abstractions
  • TypeGen sample and documentation

Type of change

  • Bug fix
  • New feature
  • Generator / generated-code behavior change
  • Analyzer / diagnostic change
  • Docs only
  • Build / tooling

Examples and documentation

  • The sample demonstrates attribute and fluent overrides using zod-geojson.
  • The package README includes installation and client syntax.
  • The Zod emitter documentation covers generated imports, inline expressions, modifier behavior, inference, and conformance.
  • Type-mapping and configurator documentation distinguish static [TsType] overrides from runtime [ZodSchema] validation.

How was this verified?

  • dotnet test ... --filter "FullyQualifiedName!~CompilationTests" — 262 passed.
  • Zod compilation tests — 7 passed, including real zod@4.6.1, zod-geojson@1.7.1, @types/geojson, and tsc compilation.
  • TypeScript compilation tests — 2 passed.
  • Focused emitter, parser, and configurator tests — 63 passed.
  • TypeGen sample rebuilt successfully and generated the expected GeoJSONPointSchema / GeoJSONFeatureSchema imports and usages.
  • dotnet build ZibStack.NET.slnx --no-restore — succeeded with 0 errors and no new warnings.

The Astro documentation build was attempted, but the existing local docs/node_modules contains files that Windows reports as access denied. No documentation-source error was reported before that environment failure.

Checklist

  • Branched from master, focused on a single change
  • Tests added or updated (generator behavior asserted where applicable)
  • Docs updated under docs/src/content/docs/ and the package README
  • Build is clean — no new warnings
  • Commit subjects use the [Package]: … prefix

@MistyKuu MistyKuu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Hey, thanks for this! Splitting TsType (static) and ZodSchema (runtime) makes sense, and the tests pass locally. I left a few inline notes. The import extraction one is the main blocker.

Heads up: ci.yml doesn't run ZibStack.NET.TypeGen.Tests at all, so the green check here doesn't cover your tests. Mind adding a step for it while you're at it?

Comment thread packages/ZibStack.NET.TypeGen/src/ZibStack.NET.TypeGen/Emitters/ZodEmitter.cs Outdated
Comment thread packages/ZibStack.NET.TypeGen/src/ZibStack.NET.TypeGen/Emitters/ZodEmitter.cs Outdated
Comment thread packages/ZibStack.NET.TypeGen/src/ZibStack.NET.TypeGen/Emitters/ZodEmitter.cs Outdated
Comment thread packages/ZibStack.NET.TypeGen/src/ZibStack.NET.TypeGen/Emitters/ZodEmitter.cs Outdated
Comment thread packages/ZibStack.NET.TypeGen/README.md
@RejectKid

Copy link
Copy Markdown
Contributor Author

Addressed all six inline review comments in 38d1cd5, including explicit compound-expression imports, local schema references and cycles, collision aliases, parenthesized modifiers, documentation, and compilation tests. CI now runs the TypeGen suite with its Node/Python prerequisites. The first Linux run exposed a pre-existing case-sensitive filename assumption in SampleApiBuildTests; corrected in cfc5ea3. The latest build-and-test check is green (all steps, including TypeGen).

@MistyKuu
MistyKuu merged commit 6573b42 into MistyKuu:master Sep 24, 2026
1 check passed
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.

TsType attribute is unused by Zod Emitter

2 participants