Skip to content

refactor!: explicit pipeline abstractions and typed JS surface - #7

Merged
pkurcx merged 17 commits into
AVSystem:mainfrom
Andrzej-Swietek:refactor/pipeline-abstractions
Sep 16, 2026
Merged

pkurcx merged 17 commits into
AVSystem:mainfrom
Andrzej-Swietek:refactor/pipeline-abstractions

Conversation

@Andrzej-Swietek

@Andrzej-Swietek Andrzej-Swietek commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

The generator was correct but hard to change safely: no traits, diagnostics
threaded as &mut through 22 signatures, schema depth counted by convention
at each call site, four files past 400 lines. Two checks were wrong: a
repeated key under paths reported as a duplicate schema name, and the
fixture list regen-snapshots read had drifted from test/fixtures/.
Nothing type-checked the published JavaScript or the tests.

How to review

About 60% of the diff is mechanical. Skim: the src/irsrc/api_model
rename, module splits (operations.rs, services.rs, request.rs,
options.rs, typescript.rs), doc-comment trimming, scripts/*.mjs
*.ts, JSDoc in lib/ and bin/, and the 26 added snapshot files.

Read, in pipeline order:

File What changed
src/error.rs Reporter moves to RefCell; every stage takes &Reporter
src/parse/unique_map.rs, src/parse/input.rs duplicate keys rejected at decode; duplicate-schema-name routes on the exact components.schemas: prefix
src/api_model/normalize/walk.rs SchemaWalk replaces (context, depth, reporter) triples
src/subcode.rs closed subcode set, tested against index.d.ts.in
src/plan/artifact_plan/resolve.rs rejects group/method names that yield an empty file stem
src/emit/ts/{writer,types}.rs Writer, Render, Position
lib/wrapper-core.js, scripts/patch-types.ts InputFormat/ResponseType become runtime constants
scripts/lib/snapshot-layout.ts single fixture manifest; check-fixture-coverage gates CI

Behaviour changes

Generated output is unchanged. These are not covered by that claim:

  • A repeated key under paths now fails as E_INPUT_INVALID, not
    E_POLICY_VIOLATION — caught while decoding, before the policy pass.
  • A JSON input with a repeated key was last-wins and now fails. serde_json
    carries no field path, so in JSON a duplicate schema name gets no
    duplicate-schema-name subcode; YAML still routes it.
  • duplicate-schema-name now matches components.schemas: exactly, so a
    nested path like Pet.properties is a plain decode failure.
  • The anchor guard no longer passes a source whose Value parse failed on a
    duplicate key.
  • A group name with no letters or digits is rejected; it produced
    rest/.rest.ts and rest//index.ts.
  • InputFormat and ResponseType stop being const enum and are exported
    as runtime constants from both entries.
  • build:debug now runs postbuild, so a debug build leaves a clean tree.

Verified

  • 325 Rust tests, 400 ava tests; clippy --all-targets, fmt, oxlint and
    three typecheck projects clean.
  • 131 pre-existing snapshots unchanged; 26 snapshot files added for ten
    newly pinned fixtures plus bench-multi-tag.
  • templates/ byte-identical to main. native.js differs only in the
    napi version-check strings (0.4.00.6.0, matching package.json);
    browser.d.ts exports the two new runtime constants.
  • CLI output identical across 21 invocations against the base.
  • YAML throughput 1.6–2.2x, JSON unchanged — the win is the removed double
    parse.

Follow-ups (not in this PR)

@pkurcx pkurcx self-assigned this Sep 8, 2026

@pkurcx pkurcx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, this is a careful refactor and the structure is a clear improvement. I built both this head and its base commit (1f1944e) and ran every fixture in test/fixtures through both CLIs: generated files, stdout, stderr and exit codes are identical for all 73, except the disclosed duplicate-schema-name wording. That covers the ten newly pinned fixtures too, which the new snapshots alone cannot prove. Also confirmed: fmt/clippy/cargo test clean (305), typecheck/lint/coverage/ava clean (345), and all ten commits compile standalone.

Two things need fixing before merge, and one rebase hazard:

  1. Runtime enums are declared but not exported. index.d.ts now promises InputFormat and ResponseType as runtime constants; lib/index.js and lib/browser.js export only generate, GenerateError, EmitTarget. InputFormat.Yaml (shown in the node-api docs) type-checks and throws at runtime. Under the old const enum it was inlined and worked. Inline comment below.
  2. Inline-object depth is charged twice per level in schema/mod.rs, roughly halving the nesting cap. Inline comment below.
  3. Rebase onto main. main has moved (v0.6.0, #8): 20 files conflict. #8 also added a Layout const-enum rewrite to scripts/patch-types.mjs, which this PR deletes, so that rewrite has to be ported into patch-types.ts or it silently disappears. The ten new snapshot dirs need regenerating under the new model.ts / rest/<tag>.rest.ts names.

Smaller behaviour changes worth listing in the description, since they are not covered by the byte-identical claim:

  • JSON inputs with a repeated key were last-wins on the base and now fail with E_INPUT_INVALID (no subcode, so a duplicate schema name in JSON never gets duplicate-schema-name).
  • A repeated key under paths changes code from E_POLICY_VIOLATION to E_INPUT_INVALID, not only its message.
  • default_group now returns Default for tags: [""] where the base fell through to the path segment.
  • Re-export lines (export type { A as X, ... } from) now wrap at 100 columns.

Non-blocking: a few why-comments dropped in e60917d are worth restoring (the Params-suffix collision rationale in plan/naming/fixed.rs, the verbatim-brace-instead-of-panic note in emit/angular/request.rs, the alias-collision note in emit/model/emit_ts_models.rs). The Emitter trait has one impl per target and no second implementation planned, so a plain function would carry less indirection; fine to keep if you prefer the shape.

Comment thread index.d.ts
Comment thread src/api_model/normalize/schema/mod.rs Outdated
Comment thread src/parse/input.rs Outdated
Comment thread src/parse/input.rs
Comment thread Cargo.toml Outdated
Comment thread src/plan/naming/defaults.rs
Comment thread __test__/generate.spec.ts Outdated
Comment thread lib/browser.js Outdated
Comment thread scripts/patch-types.ts Outdated
@pkurcx pkurcx changed the title Refactored the generator into explicit abstractions and typed the JavaScript surface refactor!: explicit pipeline abstractions and typed JS surface Sep 16, 2026
@pkurcx
pkurcx merged commit c384341 into AVSystem:main Sep 16, 2026
38 checks 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.

2 participants