Skip to content

fix(select): add empty string as option when not required#40

Open
Dominik Kadera (dominikkadera) wants to merge 4 commits intomainfrom
fix-select-empty
Open

fix(select): add empty string as option when not required#40
Dominik Kadera (dominikkadera) wants to merge 4 commits intomainfrom
fix-select-empty

Conversation

@dominikkadera
Copy link
Member

Add support for '' to be valid option of non-required selects as it prevents mishaps with JSON Schema alignments.

@dominikkadera Dominik Kadera (dominikkadera) marked this pull request as ready for review March 6, 2026 12:50
@dominikkadera Dominik Kadera (dominikkadera) requested a review from a team as a code owner March 6, 2026 12:50
Copilot AI review requested due to automatic review settings March 6, 2026 12:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for using '' as the “no selection” value for non-required select-like fields to better align generated JSON Schema with common form submission semantics, while updating tests and roundtrip behavior accordingly.

Changes:

  • Update JSON Schema generation to prepend '' as an allowed option for non-required select-like fields and set default: '' (plus a standard description when none is provided).
  • Update validator logic to treat '' as an empty value (and handle placeholder-nested selects with '' as “no selection”).
  • Add/adjust Jest test coverage (including a new spec file) for schema generation, validation, and roundtrip behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/forman.ts Injects empty-string option/default/description for non-required select-like fields; changes placeholder-nested injected option from null to ''.
src/validator.ts Treats '' as an empty value and extends placeholder-nested select handling to support ''.
src/json.ts Attempts to prevent roundtrip leakage by filtering out injected '' option and hiding the injected description when converting back to Forman schema.
test/empty-select-option.spec.ts New tests for schema generation, validation, and roundtrip behavior around optional empty-string select options.
test/placeholder-nested.spec.ts Updates placeholder-nested schema expectations to use '' and adds validation coverage for empty-string.
test/validator-extended.spec.ts Updates expectations so optional empty file path '' is treated as valid.
test/test.spec.ts Updates expected schema fragments to include default: '' and description for optional select-like fields.
test/directives/rpc.spec.ts Updates expected JSON schema output for RPC-backed selects to include default: '' and description.
test/directives/nested.spec.ts Updates expected nested directive schemas to include empty option/default/description for non-required select-like fields.
test/directives/grouped.spec.ts Updates expected grouped select schemas to include empty option/default/description.
test/composites/udttype.spec.ts Updates expected option count and default for udttype composite select output.
test/composites/__snapshots__/udttype.spec.ts.snap Snapshot updated for injected empty option/default in udttype output.
Comments suppressed due to low confidence (1)

src/validator.ts:318

  • This change makes '' behave like “no value” for all optional fields (not just selects): the validator returns valid: true early and skips type checks and field-level validations (pattern/min/max/etc). If the intent is only to support empty-string for non-required selects (and path-like selectors), consider narrowing this condition to those field types; otherwise, add focused tests that assert the new empty-string semantics for other optional field types with validations.
    if (value == null || value === '') {
        // When a select field has placeholder.nested, null/'' means "no selection" and we need to validate the nested fields
        if (normalizedField.type === 'select' && hasPlaceholderNested(normalizedField)) {
            return handleSelectType(value, normalizedField, context);
        }
        return {
            valid: true,
            errors: [],
        };
    }

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

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