Skip to content

Add --useDeserializer opt-in code generation flag#396

Draft
afloren-palantir wants to merge 12 commits into
developfrom
afloren/null-safe-deserialization-flag
Draft

Add --useDeserializer opt-in code generation flag#396
afloren-palantir wants to merge 12 commits into
developfrom
afloren/null-safe-deserialization-flag

Conversation

@afloren-palantir

@afloren-palantir afloren-palantir commented Jun 30, 2026

Copy link
Copy Markdown

Summary

Adds --useDeserializer opt-in CLI flag (default false, non-breaking) that enables schema-driven response deserialization for all generated services. Addresses the serde layer requested in #48 and the downstream issues it would fix (#78, #156).

What the flag does

  • Each generated type (object, union, enum, flavorized alias) exports a _TypeName ConjureType descriptor constant alongside its existing type/class
  • Generated service methods wrap bridge.call(...) responses with deserialize(_ReturnTypeDescriptor, result) from conjure-client
  • Non-throwing (WithErrors) services similarly wrap results including deserialization
  • Streaming (application/octet-stream) endpoints are unaffected
  • Flag-off output is byte-identical to today — zero impact on existing consumers

§5.6 behaviours applied at runtime (via conjure-client engine)

Depends on: palantir/conjure-typescript-runtime#197 (the deserialize engine in conjure-client)

Test plan

  • yarn test passes with flag off — output unchanged from baseline
  • yarn test passes with flag on — _TypeName constants emitted, service calls wrapped with deserialize
  • --useDeserializer flag visible in --help output

🤖 Generated with Claude Code

When --nullSafeDeserialization is enabled (default off):
- Each generated type (object, union, enum, flavorized alias) exports a
  ConjureType descriptor constant (_TypeName) alongside its type/class
- Generated service methods wrap bridge responses with
  deserialize(descriptor, result) from conjure-client
- Non-throwing services wrap with IConjureResult including deserialize
- Streaming (octet-stream) endpoints are unaffected

Flag-off output is byte-identical to today's output (non-breaking).
Requires conjure-client with the companion deserialization engine.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@changelog-app

changelog-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

Generate changelog in changelog/@unreleased

Type (Select exactly one)

  • Feature (Adding new functionality)
  • Improvement (Improving existing functionality)
  • Fix (Fixing an issue with existing functionality)
  • Break (Creating a new major version by breaking public APIs)
  • Deprecation (Removing functionality in a non-breaking way)
  • Migration (Automatically moving data/functionality to a new system)

Description

Add --useDeserializer opt-in code generation flag

Check the box to generate changelog(s)

  • Generate changelog entry

The flag is about enabling the full schema-driven deserializer, not
narrowly about null safety. Renaming to useDeserializer better conveys
the broader scope: integer/safelong range validation, double NaN
conversion, optional→undefined coercion, and null collection handling.

Updated CLI description to enumerate the §5.6 behaviours the engine
applies. Added references to issues #48, #78, #156 in the doc comment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@afloren-palantir afloren-palantir changed the title Add --nullSafeDeserialization opt-in code generation flag Add --useDeserializer opt-in code generation flag Jun 30, 2026
afloren-palantir and others added 5 commits June 30, 2026 13:06
Use Array<T> instead of T[] for non-simple (import-qualified) types
as required by the project's tslint array-type rule.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns with conjure-client renaming: string→stringType, boolean→booleanType,
any→anyType (avoids tslint keyword-clash violations in the runtime package).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- generateType.ts: use named ITypeName import instead of inline import()
  form; ITypeName[] is consistent with buildDescriptorExpr.ts
- generateThrowingEndpoint.ts: break long object argument over multiple lines
- generateNonThrowingEndpoint.ts: wrap long template literal argument

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@changelog-app

changelog-app Bot commented Jun 30, 2026

Copy link
Copy Markdown

Successfully generated changelog entry!

Need to regenerate?

Simply interact with the changelog bot comment again to regenerate these entries.


📋Changelog Preview

✨ Features

  • Add --useDeserializer opt-in code generation flag (#396)

@afloren-palantir afloren-palantir marked this pull request as draft June 30, 2026 21:39
afloren-palantir and others added 5 commits June 30, 2026 17:54
Tests cover all four type generators (enum, object, union, flavorized
alias) verifying descriptor constants are emitted with the correct
builder expressions when useDeserializer is true, and are absent when
the flag is off. Also tests throwing and non-throwing service generators
for the deserialize() wrapping, cross-type reference() descriptors,
void/binary exemptions, and flag-off regression.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pplyFromJson

Replaces the monolithic useDeserializer flag with three composable, incrementally-adoptable flags:

- generateJsonTypes: emits IFooJSON interfaces with wire-accurate nullability (collections
  become T | null | undefined; object/union references use IBarJSON). Zero runtime cost.
- generateFromJson: emits fromFooJson(json: IFooJSON): IFoo per-type deserializer functions
  applying Conjure 5.6 rules (null collections -> empty, recursive object deserialization).
  Implicitly enables generateJsonTypes. (Future: toFooJson serializer follows the same pattern.)
- applyFromJson: automatically pipes service responses through the appropriate fromFooJson
  by updating the bridge call generic and appending .then(fromFooJson). Exempt for binary
  (octet-stream) endpoints. Addresses #48.

Removes:
- src/utils/buildDescriptorExpr.ts (ConjureType descriptor machinery)
- _TypeName descriptor constants
- deserialize() service response wrapping
- --useDeserializer CLI flag

Adds:
- src/utils/resolveJsonTsType.ts: JSON-accurate type string resolution
- src/utils/buildFromJsonExpr.ts: field-level and service-level expression builders

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ith _

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rts lint rule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant