Skip to content

feat: Core IR extraction, OpenAPI support, and package restructuring#26

Merged
panesofglass merged 9 commits intomasterfrom
001-core-extraction
Feb 7, 2026
Merged

feat: Core IR extraction, OpenAPI support, and package restructuring#26
panesofglass merged 9 commits intomasterfrom
001-core-extraction

Conversation

@panesofglass
Copy link
Collaborator

Summary

This PR implements a major architectural refactoring that splits the library into a three-package family with target-agnostic Core IR and OpenAPI support.

Package Structure (All at 3.0.0)

  1. FSharp.Data.JsonSchema.Core - Target-agnostic JSON Schema IR and type analyzer

    • SchemaNode discriminated union (11 variants)
    • SchemaAnalyzer.analyze for recursive F# type analysis
    • No NJsonSchema or OpenAPI dependencies
    • Targets: netstandard2.0 through net10.0
  2. FSharp.Data.JsonSchema.NJsonSchema - NJsonSchema-based implementation (renamed from FSharp.Data.JsonSchema)

    • Built on Core IR via SchemaAnalyzer.analyze >> NJsonSchemaTranslator.translate
    • Existing API unchanged (Generator.Create, Validation module)
    • All existing schema output byte-identical
    • Targets: netstandard2.0 through net10.0
  3. FSharp.Data.JsonSchema.OpenApi - OpenAPI translator for ASP.NET Core

    • FSharpSchemaTransformer implements IOpenApiSchemaTransformer
    • Supports Microsoft.OpenApi 1.6.x (net9.0) and 2.0.x (net10.0)
    • Targets: net9.0 and net10.0
  4. FSharp.Data.JsonSchema [DEPRECATED] - Compatibility shim

    • References NJsonSchema package for backwards compatibility
    • Includes [<Obsolete>] attributes to guide migration
    • Will not receive updates beyond 3.0.0

Key Changes

Core IR Pipeline:

  • Introduced SchemaNode as intermediate representation
  • SchemaAnalyzer handles F# type reflection and analysis
  • Target translators convert SchemaNode → specific formats (NJsonSchema, OpenAPI)

Regression Fixes:
Fixed 11 types that previously worked in NJsonSchema but would fall back to class reflection in Core:

  • DateTime/DateTimeOffset → date-time format
  • DateOnly/TimeOnly → date/time formats
  • Guid → guid format
  • Uri → uri format
  • TimeSpan → duration format
  • byte[] → byte format (base64)
  • Map<string,T>/Dictionary<string,T> → additionalProperties
  • Set → array schema

Package Renaming:

  • FSharp.Data.JsonSchemaFSharp.Data.JsonSchema.NJsonSchema (go-forward name)
  • Unified all package versions to 3.0.0 for package family cohesion
  • Created deprecated wrapper for smooth migration

Test Results

All 151 tests passing

  • Core: 35 tests
  • OpenApi: 17 tests
  • Main (NJsonSchema): 99 tests

All existing snapshots remain byte-identical, ensuring zero behavioral regressions.

Migration Guide

For existing users of FSharp.Data.JsonSchema:

Replace:

<PackageReference Include="FSharp.Data.JsonSchema" Version="2.x.x" />

With:

<PackageReference Include="FSharp.Data.JsonSchema.NJsonSchema" Version="3.0.0" />

Code remains unchanged - namespace and API are identical. The deprecated package will continue to work but includes compiler warnings guiding migration.

Breaking Changes

BREAKING CHANGE: Package renamed for clearer naming convention. Functionality and API remain identical, but package name has changed.

Test Plan

  • All 151 existing tests pass
  • All schema snapshots remain byte-identical
  • Regression tests added for 11 format-annotated types
  • Build succeeds across all target frameworks (netstandard2.0 through net10.0)
  • OpenApi tests pass on both net9.0 (Microsoft.OpenApi 1.6.x) and net10.0 (2.0.x)

🤖 Generated with Claude Code

panesofglass and others added 9 commits February 5, 2026 23:24
…ture

Design specification for refactoring FSharp.Data.JsonSchema into a
three-package architecture (Core IR, NJsonSchema translator, OpenApi
target). Includes project constitution, feature spec with 25 functional
requirements across 5 user stories, implementation plan, data model,
API contracts, research decisions, quickstart guide, and 48 tasks.

Constitution v1.1.0 amended to support multi-package dependency rules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n fixes

This commit completes the core extraction refactoring (feature 001-core-extraction),
splitting the library into three packages while maintaining full backwards compatibility
and adding critical regression fixes for format-annotated types.

## New Packages

- **FSharp.Data.JsonSchema.Core 1.0.0**: Target-agnostic SchemaNode IR and type analyzer
  - Only depends on FSharp.Core + FSharp.SystemTextJson (no NJsonSchema)
  - Targets netstandard2.0 through net10.0
  - 35 tests covering IR generation for all F# type categories

- **FSharp.Data.JsonSchema 3.0.0**: Refactored to use Core IR + NJsonSchema translator
  - All 89 existing snapshot tests pass byte-identical
  - Internal implementation now: SchemaAnalyzer.analyze >> NJsonSchemaTranslator.translate
  - Public API unchanged (Generator.Create, Validation module, schema processors)

- **FSharp.Data.JsonSchema.OpenApi 1.0.0**: ASP.NET Core OpenAPI integration
  - FSharpSchemaTransformer implements IOpenApiSchemaTransformer
  - Supports Microsoft.OpenApi 1.6.x (net9.0) and 2.0.x (net10.0) via conditional compilation
  - 17 tests covering translator and integration

## Regression Fixes

Fixed 11 type regressions where SchemaAnalyzer would fall back to class reflection
instead of matching NJsonSchema's format annotations:

- DateTime/DateTimeOffset → string + "date-time" format
- DateOnly → string + "date" format (NET6+)
- TimeOnly → string + "time" format (NET6+)
- Guid → string + "guid" format
- Uri → string + "uri" format
- TimeSpan → string + "duration" format
- byte[] → string + "byte" format (base64, not array of integers)
- Map<string,T>/Dictionary<string,T> → object + additionalProperties schema
- Set<T> → array schema (via enhanced isArrayLike)

Added 10 new snapshot tests for regression coverage.

## Infrastructure Updates

- CI: Updated to test net8.0, net9.0, net10.0 and pack all 3 packages
- README: Documented new package structure with usage examples
- RELEASE_NOTES: Added version entries for all 3 packages

## Test Results

All 151 tests pass across all target frameworks:
- 99 main tests (89 existing + 10 new format tests)
- 35 Core tests
- 17 OpenApi tests

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…onSchema

BREAKING CHANGE: Package has been renamed for clearer naming convention.

Package Changes:
- Renamed FSharp.Data.JsonSchema → FSharp.Data.JsonSchema.NJsonSchema
- Created FSharp.Data.JsonSchema as deprecated compatibility shim
- Aligned all package versions to 3.0.0

New Package Structure:
1. FSharp.Data.JsonSchema.Core (3.0.0)
   - Target-agnostic JSON Schema IR and type analyzer
   - No breaking API changes

2. FSharp.Data.JsonSchema.NJsonSchema (3.0.0)
   - New name for the main NJsonSchema-based package
   - Formerly FSharp.Data.JsonSchema
   - No API changes, same functionality

3. FSharp.Data.JsonSchema.OpenApi (3.0.0)
   - OpenAPI schema translator for ASP.NET Core
   - No breaking API changes

4. FSharp.Data.JsonSchema (3.0.0) [DEPRECATED]
   - Thin compatibility wrapper that references NJsonSchema package
   - Includes [<Obsolete>] attributes to guide migration
   - Will not receive updates beyond 3.0.0

Migration:
Replace:
  <PackageReference Include="FSharp.Data.JsonSchema" Version="3.0.0" />

With:
  <PackageReference Include="FSharp.Data.JsonSchema.NJsonSchema" Version="3.0.0" />

Code remains unchanged - namespace and API are identical.

Test Results: All 151 tests passing (Core: 35, OpenApi: 17, Main: 99)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed focus from "opinionated NJsonSchema wrapper" to "pluggable
Core IR with multiple translation targets."

- Updated main description to emphasize extensible architecture
- Replaced "Why JSON Schema?" with "Why This Library?"
- Highlights F#-first type analysis and pluggable translators
- Positions NJsonSchema and OpenAPI as translation targets, not foundation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixes "Could not find a test logger with AssemblyQualifiedName,
URI or FriendlyName 'GitHubActions'" error in CI pipeline.

The CI workflow uses --logger "GitHubActions;report-warnings=false"
but Core.Tests and OpenApi.Tests were missing the package reference.

Added GitHubActionsTestLogger v1.1.0 to:
- test/FSharp.Data.JsonSchema.Core.Tests
- test/FSharp.Data.JsonSchema.OpenApi.Tests

(Main Tests already had this package)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ility

Fixes NETSDK1085 error: "The 'NoBuild' property was set to true
but the 'Build' target was invoked."

This is a known issue with .NET SDK 10.0.102 and multi-targeted
projects. Removing --no-build from the pack command is the
recommended workaround. Pack will still reuse existing build
artifacts from the Build step, so this doesn't cause unnecessary
rebuilds.

See: dotnet/sdk#44199

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The projects target netcoreapp3.1 and net6.0 which require their
respective SDKs to be installed. The CI was missing these, causing
pack failures.

SDKs now installed:
- .NET Core 3.1 (for netcoreapp3.1)
- .NET 6 (for net6.0)
- .NET 8 (for net8.0, testing)
- .NET 9 (for net9.0, testing)
- .NET 10 (for net10.0, testing)

netstandard2.0 and netstandard2.1 can be built with any modern SDK.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The .NET 10 SDK can build all target frameworks (netstandard2.0,
netcoreapp3.1, net6.0, etc.) by downloading targeting packs
automatically. Only need:

- .NET 9 SDK for net9.0 tests
- .NET 10 SDK for net10.0 tests and building all frameworks

The original NETSDK1085 error was from the --no-build flag bug,
not missing SDKs. Reverts unnecessary SDK additions from previous
commit.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@panesofglass panesofglass merged commit 4e22773 into master Feb 7, 2026
1 check passed
@panesofglass panesofglass deleted the 001-core-extraction branch February 7, 2026 18:25
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