Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3faec69
Issue #136 Document experimental JTD ESM codegen CLI
cursoragent Feb 5, 2026
7b71cc5
Issue #136 Add jtd-esm-codegen module and CLI generator
cursoragent Feb 5, 2026
82d8ddd
Issue #136 Fix JTD AST packaging to avoid javac warnings
cursoragent Feb 5, 2026
5975aab
Issue #136 Add nightly release workflow for jtd-esm-codegen
cursoragent Feb 5, 2026
be9c170
Issue #136 Make generated ESM output deterministic
cursoragent Feb 5, 2026
9c9d5e2
exhaustive tests
simbo1905 Feb 7, 2026
b19a9f7
Replace bun with junit-js for JS tests; fix inline validator generati…
simbo1905 Feb 7, 2026
52f92e1
Update CI test count to reflect new junit-js tests (639 total, 5 skip…
simbo1905 Feb 7, 2026
d058788
Refactor JtdToEsmCodegenTest to use GraalVM Polyglot instead of bun
simbo1905 Feb 7, 2026
c1805a9
JTD bytecode codegen via ClassFile API + RFC 8927 conformance
simbo1905 Feb 8, 2026
4364b0f
son-java21-transforms
simbo1905 Feb 8, 2026
a80cc68
Rename json-java21-transforms to json-java21-jdt (JSON Document Trans…
simbo1905 Feb 8, 2026
4f8e79f
Update CI test count to 673 tests, 0 skipped (added 33 JDT tests, 1 j…
simbo1905 Feb 8, 2026
a6195f0
Add .DS_Store to .gitignore and create README.md and AGENTS.md for js…
simbo1905 Feb 8, 2026
5be3a28
Clarify JDT means JSON Document Transforms, not Eclipse JDT
simbo1905 Feb 8, 2026
f629733
Merge origin/jtd-gen into jdt-transforms (resolve pom.xml module list…
simbo1905 Feb 8, 2026
3ca2b83
Add json-java21-jsonpath-codegen module: bytecode-generated JsonPath …
simbo1905 Feb 8, 2026
91cabac
Fix CI: exclude Java 24+ codegen modules from Java 21 build, fix logg…
simbo1905 Feb 8, 2026
8f8f5a3
Update CI test count to 1018 (JTD property tests expand in surefire XML)
simbo1905 Feb 8, 2026
c0452aa
Make JDT path resolution pluggable for compiled JsonPath support
simbo1905 Feb 8, 2026
40dd65c
Add JDT AST sealed interface hierarchy and parser
simbo1905 Feb 8, 2026
f39d837
Add JsonPath ESM renderer: AST to ES2020 module codegen
simbo1905 Feb 8, 2026
b96335a
Add JDT ESM renderer: AST to ES2020 module codegen
simbo1905 Feb 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
for k in totals: totals[k]+=int(r.get(k,'0'))
except Exception:
pass
exp_tests=611
exp_skipped=0
exp_tests=639
exp_skipped=5
if totals['tests']!=exp_tests or totals['skipped']!=exp_skipped:
print(f"Unexpected test totals: {totals} != expected tests={exp_tests}, skipped={exp_skipped}")
sys.exit(1)
Expand Down
142 changes: 142 additions & 0 deletions .github/workflows/jtd-esm-codegen-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: JTD-ESM-Codegen Nightly

on:
schedule:
- cron: '0 3 * * *' # 3 AM UTC daily
workflow_dispatch:

permissions:
contents: write

jobs:
build-uber-jar:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'maven'
- name: Build uber JAR
run: |
./mvnw -pl jtd-esm-codegen -am package
cp jtd-esm-codegen/target/jtd-esm-codegen.jar jtd-esm-codegen.jar
- uses: actions/upload-artifact@v4
with:
name: uber-jar
path: jtd-esm-codegen.jar

native-linux:
needs: build-uber-jar
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: uber-jar
path: .
- uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
components: 'native-image'
cache: 'maven'
- name: Build native image
run: |
native-image --no-fallback -jar jtd-esm-codegen.jar jtd-esm-codegen-linux-amd64
chmod +x jtd-esm-codegen-linux-amd64
- uses: actions/upload-artifact@v4
with:
name: native-linux-amd64
path: jtd-esm-codegen-linux-amd64

native-windows:
needs: build-uber-jar
runs-on: windows-latest
steps:
- uses: actions/download-artifact@v4
with:
name: uber-jar
path: .
- uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
components: 'native-image'
cache: 'maven'
- name: Build native image
run: |
native-image --no-fallback -jar jtd-esm-codegen.jar jtd-esm-codegen-windows-amd64
- uses: actions/upload-artifact@v4
with:
name: native-windows-amd64
path: jtd-esm-codegen-windows-amd64.exe

native-macos-intel:
needs: build-uber-jar
runs-on: macos-13 # Intel
steps:
- uses: actions/download-artifact@v4
with:
name: uber-jar
path: .
- uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
components: 'native-image'
cache: 'maven'
- name: Build native image
run: |
native-image --no-fallback -jar jtd-esm-codegen.jar jtd-esm-codegen-macos-amd64
chmod +x jtd-esm-codegen-macos-amd64
- uses: actions/upload-artifact@v4
with:
name: native-macos-amd64
path: jtd-esm-codegen-macos-amd64

native-macos-arm:
needs: build-uber-jar
runs-on: macos-14 # Apple Silicon
steps:
- uses: actions/download-artifact@v4
with:
name: uber-jar
path: .
- uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
components: 'native-image'
cache: 'maven'
- name: Build native image
run: |
native-image --no-fallback -jar jtd-esm-codegen.jar jtd-esm-codegen-macos-arm64
chmod +x jtd-esm-codegen-macos-arm64
- uses: actions/upload-artifact@v4
with:
name: native-macos-arm64
path: jtd-esm-codegen-macos-arm64

release:
needs: [native-linux, native-windows, native-macos-intel, native-macos-arm]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
- name: Create nightly release
uses: softprops/action-gh-release@v1
with:
tag_name: nightly-${{ github.run_number }}
name: Nightly Build ${{ github.run_number }}
prerelease: true
files: |
native-linux-amd64/jtd-esm-codegen-linux-amd64
native-windows-amd64/jtd-esm-codegen-windows-amd64.exe
native-macos-amd64/jtd-esm-codegen-macos-amd64
native-macos-arm64/jtd-esm-codegen-macos-arm64
uber-jar/jtd-esm-codegen.jar

33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ In addition to the core backport, this repo includes implementations of more adv
| --- | --- | --- |
| `json-java21-jtd` | JSON Type Definition (JTD) validator implementing RFC 8927 | [JTD validator](#json-type-definition-jtd-validator) |
| `json-java21-jsonpath` | JsonPath query engine over `java.util.json` values | [JsonPath](#jsonpath) |
| `jtd-esm-codegen` | Experimental JTD → ES2020 ESM validator code generator | [JTD → ESM codegen](#jtd-to-esm-validator-codegen-experimental) |

We welcome contributions to these incubating modules.

Expand Down Expand Up @@ -388,6 +389,38 @@ Features:
- ✅ Discriminator tag exemption from additional properties
- ✅ Stack-based validation preventing StackOverflowError

## JTD to ESM Validator Codegen (Experimental)

This repo also contains an **experimental** CLI tool that reads a JTD schema (RFC 8927) and generates a **vanilla ES2020 module** exporting a `validate(instance)` function. The intended use case is validating JSON event payloads in the browser (for example, across tabs using `BroadcastChannel`) without a build step.

### Supported JTD subset (flat schemas only)

This tool deliberately supports only:
- `properties` (required properties)
- `optionalProperties`
- `type` primitives (`string`, `boolean`, `timestamp`, `int8`, `int16`, `int32`, `uint8`, `uint16`, `uint32`, `float32`, `float64`)
- `enum`
- `metadata.id` (used for the output filename prefix)

It rejects other JTD features (`elements`, `values`, `discriminator`/`mapping`, `ref`/`definitions`) and also rejects **nested `properties`** (object schemas inside properties).
Comment on lines +398 to +405
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The implementation in the jtd-esm-codegen module appears to be more capable than what is described here. The JtdParser and EsmRenderer classes include logic for handling elements, values, discriminator, and ref, which are listed here as being rejected. It would be good to update the documentation to reflect the actual capabilities of the tool, or if these features are not fully supported, clarify their status.


When rejected, the error message is:

`Unsupported JTD feature: <feature>. This experimental tool only supports flat schemas with properties, optionalProperties, type, and enum.`

### Build and run

```bash
./mvnw -pl jtd-esm-codegen -am package
java -jar ./jtd-esm-codegen/target/jtd-esm-codegen.jar schema.jtd.json
```

The output file is written to the current directory as:

`<metadata.id>-<sha256_prefix_8>.js`

Where `<sha256_prefix_8>` is the first 8 characters of the SHA-256 hash of the input schema file bytes.

## Building

Requires JDK 21 or later. Build with Maven:
Expand Down
93 changes: 93 additions & 0 deletions json-java21-jdt/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.github.simbo1905.json</groupId>
<artifactId>parent</artifactId>
<version>0.1.9</version>
</parent>

<artifactId>java.util.json.jdt</artifactId>
<packaging>jar</packaging>
<name>java.util.json Java21 Backport JDT</name>
<url>https://simbo1905.github.io/java.util.json.Java21/</url>
<scm>
<connection>scm:git:https://github.com/simbo1905/java.util.json.Java21.git</connection>
<developerConnection>scm:git:git@github.com:simbo1905/java.util.json.Java21.git</developerConnection>
<url>https://github.com/simbo1905/java.util.json.Java21</url>
<tag>HEAD</tag>
</scm>
<description>JSON Document Transforms (JDT) implementation for the java.util.json Java 21 backport; transforms JSON documents using declarative transform specifications.</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
</properties>

<dependencies>
<dependency>
<groupId>io.github.simbo1905.json</groupId>
<artifactId>java.util.json</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.github.simbo1905.json</groupId>
<artifactId>java.util.json.jsonpath</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Treat all warnings as errors, enable all lint warnings -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-Werror</arg>
<arg>-Xdiags:verbose</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-ea</argLine>
<systemPropertyVariables>
<jdt.test.resources>${project.basedir}/src/test/resources</jdt.test.resources>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
Loading
Loading