github hamzahamidi/ajsf v19.0.0
19.0.0

3 hours ago

@ajsf/bootstrap3 @ajsf/bootstrap4 @ajsf/bootstrap5 @ajsf/core @ajsf/material published at 19.0.0 on the latest dist-tag.

npm install @ajsf/core@19.0.0

Upgrading from 18.x

@ajsf/* 19 targets Angular 19. Update the Angular packages first, then all
five @ajsf/* packages together: they version in lockstep, and each framework
package depends on its exact matching @ajsf/core.

Eight commits in this series changed behaviour a form could have been built
around, carrying twelve distinct changes between them, grouped below by theme.
Most are corrections, so a form affected by one was already getting a wrong
answer. Dropping draft 1 to 3 support is not: it withdraws something that
worked, deliberately, and is the one change here that can require editing a
schema. Read the sections below before upgrading a form in production.

Validation and drafts

Validation moved to ajv 8, and ajv-formats comes with it. Between ajv 6 and
ajv 8, format validation had stopped running: ajv 6 rejected not-an-email for
format: email and ajv 8 without ajv-formats accepts it. Formats are
enforced again, so a schema using format may now report errors it did not
report in 18.x.

The draft is read from $schema and is no longer inferred from legacy
keywords. Seven inference rules are gone, including the one that read a single
optional: true as draft 2 and made every other property required. A new
defaultDraft input supplies the draft when a schema declares no $schema,
defaulting to 7, and a declared $schema still wins. Converted schemas are
stamped draft 7 rather than draft 6.

Drafts 1 to 3 are no longer supported, with draft 4 as the floor. A
property-level required, optional or requires is still removed, because
those forms are invalid from draft 4 onward and ajv rejects the whole schema
rather than ignoring the keyword, but removing one now logs a warning naming
the properties. Six example schemas that demonstrated the old conversions were
removed: json-schema-draft01, 02 and 03, jsf-schema-required,
jsf-fields-radios and jsf-fields-select.

Converting id to $id no longer appends -CONVERTED-TO-DRAFT-06# to the
value. Any $ref written against a schema's own id resolves again.

Arrays and tuples

A fixed tuple position no longer renders a remove button. Every child of an
array node that was not addressed through the list placeholder was typed as a
list item and marked removable, and those children are exactly the fixed slots,
so the button appeared and deleted a position the schema declares as fixed.
This withdraws a control that renders in 18.x.

Adding an item to a tuple array builds the new item from additionalItems
rather than cloning the last existing item. On a tuple the last item is the
final fixed slot, so every added item used to duplicate it and could not be
removed.

Schema merging

Merging allOf members handles additionalProperties correctly in two places.
A member declaring additionalProperties: false now overrides the other value
instead of being ignored and leaving a junk key in the merged schema, and
additionalProperties is read beside properties rather than inside it, where
the check was really asking whether a property happened to be named after the
keyword.

Two schemas that both give items as an array now merge slot by slot instead
of intersecting by value. Set semantics on a positional keyword dropped slots:
merging [{type: string}, {type: number}] with
[{type: string}, {type: boolean}] returned a single slot, turning a two slot
tuple into a one slot tuple.

Widgets

The select widget hands back typed values. It round-tripped every selection
through the DOM, which coerces option values to strings, so the automatic None
option wrote the string "null" into the control. Since "null" is not in the
enum, clearing an optional field made the whole form invalid. A numeric enum
stored strings on the same path.

An explicit disabled option no longer arrives by default on a
layout-declared submit button. The widget treats disabled as an override that
wins over disableInvalidSubmit, and the default carried disabled: false
into every layout node, so the button stayed enabled on an invalid form and
clicking it emitted null. An explicit disabled: true or false in a layout
keeps meaning exactly what it says.

Validators

minProperties and maxProperties count values the user entered rather than
every declared key. A form group carries all its declared keys from the moment
it is built, so an untouched group passed any minProperties, and a group with
maxProperties below its declared size was invalid before the user typed
anything and stayed that way. Undefined, null and the empty string do not
count; false and 0 do.

What's Changed

Full Changelog: v18.3.0...v19.0.0

Don't miss a new ajsf release

NewReleases is sending notifications on new releases.