Repository navigation
Releases: parisek/definition-kit
Releases · parisek/definition-kit
Release list
v0.26.0
What's Changed
Added
- Drupal:
geofield,office_hours,color_field_typeandvideo_embed_fieldin the bundled type map.
geofieldandoffice_hoursare anopen: trueobjectorlist.
color_field_typeandvideo_embed_fieldare atext. The defaults come
from the module sources (Geofield 8.x-1.67, Office Hours 8.x-1.29, Color Field
3.0.2, Video Embed Field 8.x-2.7).drupal.settingscarries the settings
that change the data:backend;exceptions,seasons,all_day,
comment,cardinality_per_day;format,opacity;allowed_providers.
A new type-map key,checkbox_settings, marks a setting that acheckboxes
form stores with0for each unchecked option, so{youtube: '0'}and[]
read the same. Another,schema_settings, marks a setting that shapes the
database column (format,backend): the generator sets it on a new field
and refuses to change it on an existing one. - Drupal: the four common contrib paragraph field types (#106).
fields-migrate --drupal-config,fields-lint-drupaland
fields-generate --target=drupalnow mapdouble_field,address,
webformandlanguage_field. Before, each stopped the migration, so a
site put the field names indrupal.ignore_fields, and the definitions
lost those fields on every bundle. Each type pins its storage in
drupal.storage:double_fieldis alist(several values,max:is the cardinality
limit) or anobject(one value) with the partsfirstandsecond.
A part is typed after its subfield storage type, or is aselectwhen
the instance gives it a fixed list. The lint checks the part names and
types. The generator builds the subfield types, labels, required flags
and options of a new field from the parts, and refuses a part that the
subfield of an existing field cannot hold.addressis anopen: trueobject(orlist).webformis areferencewithof: entity:webform.language_fieldis atext,multiple: truefor several values.
drupal.settingson a field and on adouble_fieldpart. A closed map of
the settings that change what the field does: an address's
available_countries,langcode_overrideandfield_overrides; a
language_field'slanguage_range,included_languages,
excluded_languagesandgroups; a double_field part'smaxlength,
precision,scale,datetime_type,min,maxand, for a boolean part,
on_labelandoff_label, each only for the subfield types that use it. The deprecated addressfieldssetting is read
as the equivalentfield_overrides. The migration writes
the ones that differ from the default, the lint compares them, the generator
applies them. A double_field part also pins its exact subfield storage type
indrupal.storage(integer,uri,email, ...), and the lint always
compares that subfield type, so a part without its pin is drift.drupal.type_mapindefinition-kit.yaml. A project file, relative to
definition-kit.yaml, merged overschemas/drupal-type-map.yaml. A project
can map a contrib storage type the kit does not know without a kit release.
The overlay passes the same checks as the bundled map, and a malformed one
stops the command (exit 2) with the file and the entry.kit_typeslists
append to the bundled lists, other sections replace entries by name. See
README, Drupal paragraphs.storage_typesentries merge key by key, so an
overlay can change one nested setting. Akit_typeskey must be a known kit type, and
a structured type must be listed under bothobjectandlist.
Changed
- The error for an unknown Drupal storage type names
drupal.type_mapas the
fix, next todrupal.ignore_fields. DrupalTypeMap::forSettings()builds the map with the project overlay. The
reader, the linter, the spec builder and the planner build it from their
DrupalSettingswhen no map is passed.DrupalSettingshas atypeMap
property.- An unpinned
text,reference,objectorlistfield now accepts the
contrib storage types listed under it in the map. The lint finding for a
storage type mismatch lists them too.
Fixed
- Drupal: a stale
field_config_cardinalityoverride no longer beats the
storage. The module only narrows: it offers "unlimited" on an unlimited
storage alone and a limit up to the storage's own. An override outside that
range (a storage of 1 with-1, seen on a real site) now reads as the
storage value, and0or a number below-1reads as no override. Before,
the lint expected alistfor a single-value field, and the generator
refused the "cardinality change". - Drupal:
fields-migrate --drupal-displayno longer stops with "both X and
X are taken". A field the display class never pairs falls back to its
natural prop name. When another field's evidence path already used that
name, the migration stopped, or put the mapped field on the wrong name. The
evidence now keeps its names and the unpaired field gets<name>_field,
pinned bydrupal.field. A new name is also free of every other field's natural name.
Pull Requests
- #107 — feat(drupal): map eight contrib field types, add drupal.type_map, fix cardinality and display-evidence collisions
Full Changelog: v0.25.0...v0.26.0
v0.25.0
What's Changed
Added
fields-validatewarns when a block leavespostTypesopen without a reason
(#104). An empty or missingwp.block.acf.postTypesputs the block in the
inserter of every post type. That is right for a footer in a reusable
wp_block, and usually a forgotten default elsewhere. The new
PostTypesLinterstays silent for a restricted block and for an open block
with a rootdevitem that starts withpost-types: open, <reason>. It
warns on any other open block, and on the marker with no reason.devmay be
one string or a list. The marker and its reason must sit in the same item.
It is a warning, sofields-generateis not blocked. A Drupal project and a
non-block definition are skipped.
Pull Requests
- #103 — ci: pin all actions to commit SHAs
- #105 — feat(validate): warn when a block leaves postTypes open without a reason
Full Changelog: v0.24.0...v0.25.0
v0.24.0
What's Changed
Added
fields-validatewarns on awp.blockkey the generator ignores. The
schema keepswpopen, andBlockJsonGeneratorreplays onlydescription,
keywords,acf,supports,attributesandexample. Any other key,
such asiconortitle, was dropped without a trace. The new
WpBlockKeyLinternames the key and lists the ones that work. It is a
warning, sofields-generateis not blocked. A new end-to-end test also
pins the #51 round trip:descriptionandkeywordssurvive
fields-migrateandfields-generate, andfields-lintreports no drift.
Fixed
fields-fixturesno longer crashes onparisek/styleguide1.32.0. From
1.32.0,componentDirectories()reportshasTemplate: truefor a folder
that holds only<id>.yamlorstyleguide.twig. The auditor read the flag
as "has<id>.twig". It then audited a.yaml-only folder, hit a
TypeErroron a list-shapedfields:, and printed nothing. The auditor now
checks for<id>.twigon disk.
Pull Requests
- #98 — docs: add security policy, contributing guide and GitHub templates
- #99 — fix(fixtures): detect a component's own twig on disk, not via hasTemplate
- #100 — chore(deps): update parisek/acf-json-schema requirement from ^0.6 to ^0.6 || ^0.9 in the composer-minor-patch group
- #101 — chore(deps): bump actions/checkout from 5 to 7
- #102 — fix(validate): warn on a wp.block key the generator ignores
Full Changelog: v0.23.0...v0.24.0
v0.23.0
What's Changed
Added
fields-validatewarns onwp.wpml_cf_preferencesset by hand on a leaf
field. The key overrides thetranslatablemapping and nothing checked
it. A hand-written3means Copy once in WPML, not Translate, so the field
copies its value to every language. The newLeafWpmlPreferenceLinterwarns
on3or0(non-canonical for a leaf) and namestranslatable: trueas
the way to write Translate. A1or2gets a softer "redundant" warning.
Containers and fields without the key stay clean. Nested rows, groups and
flexible layouts are walked. A warning never fails validation. Measured on
about 100 projects: 5 have leaf value fields on3, one of them 46 of 538
and another 34 of 48.
Pull Requests
- #97 — feat(lint): warn on wp.wpml_cf_preferences set by hand on a leaf field
Full Changelog: v0.22.0...v0.23.0
v0.22.0
What's Changed
Added
unknown-return-key: a read below akind: filefield is checked against
what the field returns (#43). The contract check stopped at a declared
leaf, socontent.video.urlfor a file that returnssrcwas accepted and
rendered empty.schemas/type-return-shapes.yamllists the eleven keys
parisek/timber-kit'sformatFile()returns; the first key below the leaf
must be one of them. A type without an entry (kind: image,kind: gallery)
keeps the old behaviour. A project's owntype-return-shapes.yamlnext to
the components root replaces the table (a type it omits is unchecked), so a
project on another framework is not judged against timber-kit's shape. The
note fails the component, like the other two read-side defects. Measured on two downstream themes: no read falls outside
the list.
Pull Requests
- #95 — feat(contract): check reads below a kind: file leaf against its return shape
Full Changelog: v0.21.0...v0.22.0
v0.21.0
What's Changed
Added
aliases:on a component, page or doc. An array of extra search names
forparisek/styleguide's upcoming alias search: a string opens the entry
itself,{name, variant}opens a specific variant tile. Schema-only —
schemas/component.fields.schema.json,schemas/page.schema.jsonand
schemas/doc.schema.jsonall accept it via a shared$defs/aliases; no
generator, migration or lint tool needs to learn the key, since it has no
CMS projection and no legacy twig front-comment representation. An older
parisek/styleguideignores the key.variants_order:on a component, page or doc. A variant tile id, or a
list of them, to show first in the catalogue; the rest keep file-name
order. Same treatment asaliases:— a shared$defs/variantsOrderin all
three schemas, no other tool needs to learn it.
Full Changelog: v0.20.0...v0.21.0
v0.20.0
What's Changed
Fixed
FixtureAudit\Auditordistinguishes a failed render again. Since
parisek/styleguide1.18.0,Renderer::render()stopped setting
http_response_code()as a side effect — the signalAuditorused to
detect a render failure.component/broken({{ 1 / 0 }}) silently read
back as a successful render (broken OK) instead oferror render-failed.Auditor::renderFixture()now reads$result['status']
fromStyleguide::renderObserved()(statusadded in
parisek/styleguide 1.20.0, parisek/styleguide#152). Fixes #89.
Changed
- Raised the
parisek/styleguidefloor to^1.20. The>=1.11 <1.18
cap from #90 is gone — there is no version of styleguide where both the
oldhttp_response_code()signal and the newstatuskey exist, so
Auditorrequires the floor that hasstatusrather than branching on
which signal is available.
Pull Requests
- #93 — fix(fixture-audit): read render status from renderObserved(), not http_response_code()
Full Changelog: v0.19.1...v0.20.0
v0.19.1
What's Changed
Fixed
TwigMetadataReader::read()no longer carries an explicitly empty
quoted value (description: "") forward as''. Its emptiness check
ran on the still-quoted two-character literal"", before unquoting,
so it never caught it; every other reader on this path
(EntryMetadataMigrator,AcfJsonReader) drops an empty value instead
of carrying it forward. Surfaced by thefields-migrate --strip-comment
(#84/#87) dry run against a 49-component Drupal project: 5 components
were refused as a false mismatch (description: comment has '', yaml has no such key) purely because their yaml, correctly, omits an empty
description:that the comment still states as"".
Pull Requests
- #92 — fix(migrate): drop an empty quoted twig metadata value, not just an empty one
Full Changelog: v0.19.0...v0.19.1
v0.19.0
What's Changed
Fixed
- Pinned
parisek/styleguideto>=1.11,<1.18(#89).parisek/styleguide
1.18.0 (PR parisek/styleguide#144) changedRenderer::render()from
returning an HTML string plus anhttp_response_code()side effect to
returning aResultobject carrying the status, but
Styleguide::renderObserved()— the methodFixtureAudit\Auditoruses —
was not updated to forward that status: it takes only->bodyfrom the
Resultand its own return array has no status key at all.
Auditor::renderFixture()detects a fixture render failure by resetting
http_response_code(200)and reading it back after the render (documented
byRenderer::render()itself as the stable signal); with nothing calling
http_response_code()any more,Auditorcan no longer tell a failed
render (component/broken's{{ 1 / 0 }}) from a successful one — every
fixture reads backOKregardless of whether it actually rendered.
fields-contract's render-failure detection has no other signal to fall
back on without an upstream change torenderObserved()'s return shape, so
the constraint is capped below1.18.0(last known-good:1.17.0) until
parisek/styleguiderestores an observable status. Confirmed
parisek/styleguide1.17.0 through 1.19.0-adjacent CI drift was the sole
cause:composer installfrom a clean checkout ofmainreproduced the
same 5AuditorTestfailures purely from the unpinned constraint floating
onto 1.19.0, with no other change involved. fields-migrateon a component now strips the twig front-comment once
<name>.yamlis written, the same way page/doc migration always has
(#84). Component migration used to leave the comment on the twig, so every
migrated component carried its metadata twice — proven downstream on a
49-component Drupal project where every already-migrated component still
opened with the samename:/usage:/category:block its<name>.yaml
already recorded. The strip happens only after the yaml write completes,
mirroring the existing page/doc write-then-strip order.
Added
fields-migrate --strip-comment [--write] <component-dir>|--root=<root>
retires the front-comment on a component that was already migrated before
the fix above, without re-deriving anything. It removes the comment only
when every key it carries matches<name>.yaml— normalising a
comma-separatedusage:against a yaml list — and refuses the component,
per key, when the yaml disagrees or is missing a key, printing what
differs. Dry run by default, like--rename-structural-types.
Pull Requests
- #88 — fix(migrate): strip a component's twig front-comment after migration
- #90 — fix(deps): cap parisek/styleguide below the render-status regression
Full Changelog: v0.18.1...v0.19.0
v0.18.1
What's Changed
Fixed
- A Drupal
entity_referenceto an entity type outsidepost/term/media
(a config entity such aswebform, or a content entity Drupal-side only)
now has anof:vocabulary —entity:<target_type>[:<bundle>,…](ADR
0009).fields-migrate --drupal-configused to write such a field with no
of:at all, which every consumer read back as'', an unhandled value
AbstractTypeReverseMapper::reference()threw aDomainExceptionfor —
uncaught, since that reverse mapper runs unconditionally inside
fields-validate/fields-generate(both build the WP reconstruction tree
as a key-resolution check regardless of target). A Drupal-only project
therefore could not validate its own migrated output for such a field.
Fixed at the source (DrupalParagraphReader::reference()now writes a
validof:) and defensively (AbstractTypeReverseMapper::reference()
falls back to an unrestrictedpost_objectforentity:instead of
throwing;bin/fields-validatealso now catches\DomainException
around itsFieldsGenerator::generate()call and reports a cleanFAIL
instead of crashing, for any other cause of the same shape). - Omitting
entity:<target_type>'s bundle list is a declared "any
bundle", andfields-lint-drupal/fields-generate --target=drupalnow
treat it consistently with the real Drupaltarget_bundles: null
sentinel.DrupalTypeMap::expectedTargetBundles()returns[](compared
against the field's real, equally empty bundle list) rather thannull
(which means "the definition does not say — skip the check"), and
DrupalConfigPlannernow writes real Drupalnullback for an empty
wanted-bundles list wherever it buildshandler_settings.target_bundles—
previously a literal[], which is not the same sentinel and round-tripped
to DRIFT against itself. Together these give arkero'sfield_webforma
correctof: entity:webformwith 0 DRIFT and 0 UPDATE, replacing the
semantically wrongof: 'post:any'workaround (a webform is not a post)
that still left both.
Pull Requests
- #86 — fix(drupal): entity_reference vocabulary for non-post/term/media targets
Full Changelog: v0.18.0...v0.18.1