Skip to content

feat(types): add advanced field tracking to toJSONSchema#54

Merged
Dominik Kadera (dominikkadera) merged 4 commits into
mainfrom
dka/advanced-fields-skip-by-default
May 25, 2026
Merged

feat(types): add advanced field tracking to toJSONSchema#54
Dominik Kadera (dominikkadera) merged 4 commits into
mainfrom
dka/advanced-fields-skip-by-default

Conversation

@dominikkadera

@dominikkadera Dominik Kadera (dominikkadera) commented May 25, 2026

Copy link
Copy Markdown
Member

Summary

Non-breaking minor (v1.14.0) addition for working with Forman fields marked advanced: true.

  • toJSONSchema(field, options?) continues to return a bare JSONSchema7 — fully backward-compatible. Existing callers don't need to change anything.
  • Fields marked advanced: true are now stamped with x-advanced: true on the JSON Schema output, and round-trip through toFormanSchema (which restores advanced: true).
  • New option excludeAdvancedFields?: boolean (default false). When true, advanced sub-fields of a collection are omitted from the schema.
  • New function toJSONSchemaAdvanced(field, options?) returns { schema: JSONSchema7, skippedPaths?: { advanced?: string[] } }. Use it when you also need to know which advanced fields were dropped (e.g. to render a "show advanced" toggle). toJSONSchema delegates to it internally and returns just .schema.

Backward compatibility

Surface Behavior change Breaking?
toJSONSchema return type Bare JSONSchema7 (unchanged) No
toJSONSchema default behavior Advanced fields still emitted (unchanged) No
x-advanced: true stamp on output New on advanced fields Technically observable in JSON.stringify, but x-* is reserved for JSON Schema extensions — practically not breaking
toFormanSchema reads x-advanced Only triggers when input carries the marker No
New toJSONSchemaAdvanced, FormanJsonSchemaOptions, FormanJsonSchemaResult exports Pure additions No

Implementation notes

  • Filter point is handleCollectionType.addField — a single insertion that uniformly covers main form, nested-by-option fields, array items, RPC param panels, and composite expansions (udtspec/udttype).
  • Path tracking uses a collectionPath helper that omits the segment for synthetic anonymous collection wrappers (so [] array paths don't get a literal "undefined" segment).
  • Composite types memoize internally — advanced fields inside a composite (e.g. udtspec's label) are recorded in skippedPaths once per toJSONSchemaAdvanced call, not per usage.
  • Round-trip via toFormanSchema recovers advanced from x-advanced in a top-level wrapper, so all branches (composites, primitives, objects, arrays) inherit it uniformly.

Test plan

  • New test/advanced-fields.spec.ts covers: default include + x-advanced stamp, opt-out via excludeAdvancedFields, toJSONSchema vs toJSONSchemaAdvanced parity, path correctness (incl. array [] no-undefined), nested-by-option same-level paths, composite filtering, composite cache deduplication, cross-domain buffered fields, required+advanced interaction, top-level always rendered, single-spec array.
  • Round-trip test in test/test.spec.ts confirms Forman → JSON Schema → Forman preserves advanced: true.
  • All existing tests continue to assert against the bare JSONSchema7 return shape; no destructuring needed.
  • npm run lint clean, npm test 338/338 pass, npm run build succeeds.

BREAKING CHANGE: toJSONSchema now returns { schema, skippedPaths? }
instead of a bare JSONSchema7. Fields marked advanced: true are
skipped by default; pass { includeAdvancedFields: true } for previous
behavior. Included advanced fields are stamped with x-advanced: true
and round-trip through toFormanSchema.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 25, 2026 10:26
@dominikkadera Dominik Kadera (dominikkadera) requested a review from a team as a code owner May 25, 2026 10:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a breaking change to the Forman → JSON Schema conversion API by making advanced: true fields omitted by default, while providing opt-in inclusion and reporting skipped paths so callers can request the advanced surface when needed. It also adds round-trip fidelity for advanced fields by stamping included fields with x-advanced: true and teaching toFormanSchema to recover advanced: true from that marker.

Changes:

  • Change toJSONSchema to return { schema, skippedPaths? } and add FormanJsonSchemaOptions / FormanJsonSchemaResult types.
  • Implement default advanced-field skipping with skippedPaths.advanced tracking, plus x-advanced: true stamping when advanced fields are included.
  • Update/migrate tests and snapshots, and add a dedicated advanced-field behavior test suite; bump package version to 2.0.0.

Reviewed changes

Copilot reviewed 27 out of 29 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/validator-extended.spec.ts Formatting-only update; no behavior change.
test/test.spec.ts Migrates to new toJSONSchema(...).schema API and adds round-trip test for advanced: true.
test/scenario.spec.ts Migrates callsites to destructure { schema }.
test/redefine.spec.ts Migrates callsites to destructure { schema }.
test/radio.spec.ts Migrates callsites to destructure { schema } and minor expectation formatting.
test/placeholder-nested.spec.ts Migrates callsites to destructure { schema }.
test/nested.spec.ts Migrates callsites to destructure { schema }.
test/list.spec.ts Migrates callsites to destructure { schema }.
test/filestorage.spec.ts Migrates callsites to destructure { schema }.
test/empty-select-option.spec.ts Migrates callsites to destructure { schema }.
test/domains.spec.ts Migrates callsites to destructure { schema }.
test/directives/rpc.spec.ts Migrates callsites to destructure { schema }.
test/directives/nested.spec.ts Migrates callsites to destructure { schema }.
test/directives/grouped.spec.ts Migrates callsites to destructure { schema }.
test/directives/filter.spec.ts Migrates callsites to destructure { schema }.
test/composites/udttype.spec.ts Migrates callsites to destructure { schema } and updates one test to include advanced fields.
test/composites/udtspec.spec.ts Migrates callsites to destructure { schema } and updates tests to include advanced fields where needed.
test/composites/snapshots/udttype.spec.ts.snap Snapshot updated to include x-advanced: true marker.
test/composites/snapshots/udtspec.spec.ts.snap Snapshot updated to include x-advanced: true marker.
test/advanced-fields.spec.ts New test suite for default advanced skipping, path tracking, and x-advanced stamping behavior.
src/types.ts Adds FormanJsonSchemaOptions and FormanJsonSchemaResult public types.
src/json.ts Wraps toFormanSchema to restore advanced: true from x-advanced: true.
src/index.ts Updates toJSONSchema signature/return type and emits skippedPaths from conversion context.
src/forman.ts Adds includeAdvancedFields/skippedPaths to context and implements advanced filtering at collection insertion point.
README.md Documents breaking change, migration guidance, and new advanced-field behavior.
package.json Bumps version to 2.0.0.
package-lock.json Bumps lockfile package version to 2.0.0.
AGENTS.md Updates internal contributor docs for the new API/options and x-advanced marker.
.gitignore Ignores .claude/*.lock files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread AGENTS.md Outdated
Comment thread README.md Outdated
Comment thread src/index.ts Outdated
…dPaths

When a composite type (e.g. udtspec) is used multiple times, the addField
filter only runs during the first expansion, so only the first usage's
path is recorded in skippedPaths.advanced. Subsequent usages share the
same definition via $ref and are not re-walked. Documented at the cache
site in src/forman.ts and in the corresponding test.

Also rewrote the array-with-non-array-spec test as a negative behavior
contract: `advanced` on a single-primitive item type has no sibling
context to hide from; to hide the array, mark the array field itself.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… marker framing

- README + toJSONSchema JSDoc now scope advanced filtering precisely:
  applies to collection sub-fields (incl. nested, array-of-collection,
  composites, cross-domain); does NOT apply to top-level or single-
  primitive array item types.
- AGENTS.md section title corrected: x-* markers are mostly
  enumerable: true (only x-filestorage is non-enumerable). Renamed
  "Non-enumerable properties" → "x-* round-trip markers" and explained
  why defineProperty is used.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reshape the previous breaking change to ship as a minor (1.14.0):

- Add new toJSONSchemaAdvanced(field, options?) returning
  { schema, skippedPaths? }. toJSONSchema keeps its original bare
  JSONSchema7 return shape and now delegates to the new function.
- Flip the default: advanced fields are now INCLUDED by default.
  Rename the option to excludeAdvancedFields (default false). Pass
  { excludeAdvancedFields: true } to omit them.
- Included advanced fields still get x-advanced: true on the JSON
  Schema and round-trip through toFormanSchema.
- Revert the ~50 test callsite destructurings, drop the now-obsolete
  includeAdvancedFields flags from composite tests.
- Rewrite test/advanced-fields.spec.ts around the new model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dominikkadera Dominik Kadera (dominikkadera) changed the title feat(types)!: skip advanced fields by default in toJSONSchema feat(types): add advanced field tracking to toJSONSchema May 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 15 changed files in this pull request and generated 4 comments.

Comment thread AGENTS.md
Comment thread AGENTS.md
Comment thread README.md
Comment thread src/index.ts
@dominikkadera Dominik Kadera (dominikkadera) merged commit 97728c3 into main May 25, 2026
5 checks passed
@dominikkadera Dominik Kadera (dominikkadera) deleted the dka/advanced-fields-skip-by-default branch May 25, 2026 12:05
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.

4 participants