ts_schema_codegen 0.1.4
ts_schema_codegen: ^0.1.4 copied to clipboard
Generate Dart code from a TypeScript data schema. Evaluates the TS entry file with Deno at build time and emits typed Dart constants via build_runner.
Changelog #
0.1.4 — 2026-04-24 #
Changed #
maptemplate now emitsconst Object schema = ...(non-nullable) when the evaluated TS export is non-null, andconst Object? schema = nullonly when the export is literallynull. Previously always emittedconst Object?, which trippedunnecessary_nullable_for_final_variable_declarationsin consumer projects that lint generated files.
Cleanup (non-semantic) #
- Removed unused
field_definition.dartimports fromexample/lib/main.dart,example/composed/lib/main.dart,example/multi/lib/main.dart. The.nameaccessor onFieldTypevalues doesn't require the type to be in scope. - Converted a handful of double-quoted strings in tests to single quotes
(
prefer_single_quotes).
Tests #
- 75 → 77. +2 emitter cases:
emits Object (non-nullable) when value is non-nullandemits Object? when value is literally null.
Result #
dart analyze over the whole package (lib + test + all four runnable
examples) now reports No issues found!.
0.1.3 — 2026-04-24 #
Changed (internal) #
-
Introduced an IR layer between the Deno JSON and the emitter (#7). Typed Dart classes
SchemaIR/FieldSetIR/FieldDefIR+ aFieldKindenum replace the rawObject?input that the emitter used to walk. Parsing (shape validation + normalization) now lives inparseFieldDefinitionsIR; the emitter trusts its typed input and focuses on string generation.This is a refactor-only release — no consumer-visible behavior change. The
field_definitionstemplate still emits the same per-fieldset lists + registry + routing switch. Parser errors carry a JSON-pointerpath(e.g.SCHEMA.ticket.fields[2].type) matching what the Deno validator produces, via a newSchemaShapeErrorclass.Why:
emitter.darthad shape-checking (is! Map,is! List) mixed in with string emission, which made adding templates require re-doing validation work each time. The IR split separates concerns, makes emitters unit-testable against hand-built IR fixtures, and sets up a clean extension point for future templates. -
emitFieldDefinitionssignature:schemais nowSchemaIRinstead ofObject?. Themaptemplate is unchanged (it takesObject?— raw JSON with no shape to enforce). Anyone callingemitFieldDefinitionsdirectly will need toparseFieldDefinitionsIR(raw)first; users who only go throughbuild_runnersee no change.
Tests #
- 67 → 75. +15 IR parser cases (
test/ir_test.dart), emitter tests rewritten to use IR fixtures (same 25 cases, now constructed via typed helpers instead of nested Map literals — ~40% less test boilerplate).
0.1.2 — 2026-04-24 #
Added #
- Multi-schema config (#5).
build.yamlnow accepts aschemaslist so one builder invocation can produce multiple outputs from multiple TS entries. Each entry has its ownsource,export,template,field_class_import, andoutput. The old single-schema shape (top-levelsource/export/etc.) is still accepted and defaults output tolib/ts_schema.g.dartfor backward compat. - Configurable output path (#5).
output:option per schema. Must start withlib/(build_runner constraint) and end with.dart. Duplicate outputs across schemas are rejected at config-parse time. - Zod-style boundary validation (#3). For
field_definitionsschemas, the Deno side now walks the export beforeJSON.stringifyand emits JSON-pointer errors (SCHEMA.ticket.fields[2].type: expected 'string' | 'array' | 'text', got 'txt'). Skipped formaptemplate since that accepts any JSON-serializable value. Exit code 6 distinguishes validation failures from other Deno errors. No network deps — the validator is ~80 lines of hand-rolled TS. - New
example/multi/runnable example demonstrating the multi-schema config with onefield_definitions+ onemapentry side by side.
Changed #
TsSchemaConfig.schemas: List<SchemaEntry>replaces the flatsource/export/template/... fields. External callers constructing the config programmatically (rare) will need to update; the build.yaml options surface stays backward-compatible.DenoRunner.evaluatetakes an optionaltemplateparameter (default'map') forwarded totool/ts_export.tsto drive validation.
Tests #
- 55 → 67. +7 config cases for multi-schema + backward compat, +5 validator pipeline cases (field-type typo, missing required keys, non-string in categories, happy path, map-template skip).
0.1.1 — 2026-04-24 #
Added #
- Typed authoring API (#2). Ship
types.tsat the repo root withdefineSchema,FieldSet,FieldDef,FieldType. Consumers import via pinned Deno URL (or vendor the ~40 lines) and wrap their schema indefineSchema(...)for IDE completion + edit-time typo detection. - Generated registry (#4, additive). The
field_definitionstemplate now emits aGeneratedFieldSetclass and aconst kFieldSets = <String, GeneratedFieldSet>{...}map alongside the existing per-fieldset lists and routing switch. Consumers can iteratekFieldSets, inspect metadata, and build custom routing without regenerating. Default routing path unchanged — this is purely additive. - Custom JSON replacer (#6) in
tool/ts_export.ts.Date,BigInt,Map, andSetnow cross the Deno → Dart boundary as tagged objects ({__type: 'Date', iso: '...'}etc.) instead of silently mangling. Plain templates pass them through; future templates can recognize__typemarkers to materialize as typed Dart values.
Fixed #
builder_impl.dartnow parses.dart_tool/package_config.jsonwithjsonDecodeinstead of a regex. The regex was brittle to any future field reordering; the typed lookup surfaces clearer errors (distinguishes a corrupt config from a missing dev-dependency).
Tests #
- 45 → 55. New cases: registry emission (5), JSON replacer roundtrips
(5). See
test/for the full list.
0.1.0 — 2026-04-23 #
Initial release.
Added #
build_runnerbuilder (ts_schema_codegen|ts_schema) triggered on$package$, emittinglib/ts_schema.g.dart.- Bundled Deno evaluator (
tool/ts_export.ts) for TS schema extraction. - Two templates:
map— nestedconst Object? schema = {...}for raw data.field_definitions— per-fieldsetconst <FieldDefinition>[...]lists + agetFieldsForCategoryGenerated(category, {subcategory})routing function. Consumer supplies theFieldDefinitionclass viafield_class_importoption.
- Typed config with validation (
TsSchemaConfig): fails the build with a clear pointer to the offendingbuild.yamloption on bad input. - Automatic
dart format --page-width 120on emitted output. - 45-test suite covering config validation, emitter output (both templates, Unicode, deep nesting, escape handling, insertion order), real-Deno integration, and full TS → Deno → emitter pipeline roundtrips.
- Three runnable examples under
example/:- primary (dynamic form schema,
field_definitions) map_config/(feature flags,maptemplate)composed/(multi-file TS composition via imports +Object.fromEntries)
- primary (dynamic form schema,
Known limitations #
- Requires Deno on
PATHat build time. A future release will bundle a WASM TS evaluator to remove this. - Fixed output path
lib/ts_schema.g.dart; not yet configurable. - Only two templates. A template-registry API is planned.