Minor Changes
-
c5765df: A misspelled config key now says so, starting where it costs most
ssewas the only configuration whose keys were checked. Every other one
accepted anything in silence — including the top level, where the cost is
highest: a misspelled key there does not degrade a feature, it removes a whole
section of configuration.securty:means no security config at all, so
every check falls through to its default and the app is open where its author
believed it closed. TypeScript catches that; consumers whose module files are
plain JavaScript get nothing.Unknown keys are now reported for
KernelOptionsand forsecurity, in the
shape #1898 established: the warning names what happens instead, because
"ignored" reads as "no effect" rather than "falls back to something else".Suggestions got better in the process, and
sseinherits it: the old matcher
only caught case differences and prefixes, sosecurtysuggested nothing at
all. It now tolerates a missing, inserted, substituted or transposed letter.Deliberately not validated:
debugBar, whose extra keys are forwarded to
the DebugModule on purpose. A warning that cries wolf is worse than none, and
this is not "validate everything" — see
ADR 0011.The known-key list is compared against the
KernelOptionsinterface by a
test, so it cannot quietly fall behind and start warning about options that do
work. -
0bb730c:
./gen's runtime factory is renamedcreateGeneratedManagers— it collided with the root's owncreateManagersTwo public entry points exported the same name for different functions. The
root'screateManagerstakes(config, context)and returns a plain object;
./gen's took a single generated config and returned aMap. Whoever reached
for the wrong import got no warning at all — the mistake surfaced at the first
.get(), several frames from its cause.The documentation had absorbed the confusion too:
docs/gen.mdshowed the
ROOT's signature under the./genimport, and promised aRecordwhere a
Mapcomes back. Corrected.Nothing breaks:
createManagersis still exported from./genas a
deprecated alias. New code should usecreateGeneratedManagers.This is the naming half of the problem only.
./genremains a source entry
that Node cannot load on its own — splitting the build-time codegen from the
runtime factory is a larger change with, so far, no one asking for it. -
b05d52c: One singularizer instead of two, and a navigation to a missing route now says so
crud()NAMED routes with six hand-rolled lines whileEntityManager.routePrefix
LOOKED THEM UP through the vendoredpluralize. Two engines, and they
disagreed:crud()postedpeople-showwhileuseListPageasked for
person-show, sorouter.hasRoute()was false everywhere. No error at boot,
nothing at all until someone clicked and the row simply did not open.They agreed on every regular plural —
books,categories,statuses,
boxes,addresses— which is precisely why it went unnoticed.crud()now
uses the same engine as everything else.Who this changes. Only entities whose plural is irregular:
people,
children,analyses,criteria,indices,men,feet. For those, three
derived values change, not one:Derived from the entity name Before After Route prefix people-showperson-showParent route param peopleIdpersonIdChild foreign key people_idperson_idThe last one goes on the wire to your backend, so read it carefully if you
have such an entity. An explicitforeignKey,parentParamorroutePrefix
still wins over the derived value, as before.An app with an irregular-plural entity cannot have been working without
pinning something already — the two sides disagreed, so navigation was broken.
If you pinnedroutePrefixon the EntityManager to match the old hand-rolled
output, remove the pin or align both sides.And the class of failure is no longer silent.
goToShow,goToEditand
goToCreatenow warn, once per route name, when the name they are about to
push does not exist — naming the name, the fact that nothing will happen, and
the prefix they derived it from. The check sits at the moment of navigation
rather than auditing prefixes upfront, because an entity that only ever
appears as a child of another legitimately has no routes under its own prefix,
and a warning nobody trusts is worse than none. -
ad6a6be: Five Kernel registries now exist the moment the Kernel does
Seventeen public
Kernelproperties werenulluntilcreateApp(), through
a window nothing documented. Someone wiredkernel.signalsright after
new Kernel(), gotnull, andnull?.emit?.()swallowed it without a word.Five of them had no reason to wait — they depend on nothing but
optionsand
each other — and are now built in the constructor:signals,hookRegistry,
zoneRegistry,deferred,permissionRegistry. Every creator is idempotent,
so the calls still made duringcreateApp()keep these instances rather than
orphaning whatever was registered on them in between.Their types drop
| null. That is the breaking part, and it is the point:
the contract stops advertising a danger that no longer exists. Code written as
kernel.signals?.emit(...)keeps working — optional chaining on a non-null
value is merely redundant — but a consumer whose types saidSignalBus | null
and who branched on it will find that branch unreachable.strictNullChecks
users may see narrowing they relied on disappear.Closing the window beats warning about it: this removes defensive code rather
than adding any._setupSecurityno longer rebuilds a registry that might be
missing, and_createDeferredRegistryno longer reaches through?.for a
bus that is always there.The properties that genuinely cannot exist before the app is mounted —
vueApp,router,moduleLoader,orchestratorand the rest — are
untouched. They are a different problem: the answer there is to refuse the
read with a message naming the moment, not to fake a value. -
fef45ca:
vanilla-jsoneditoris a real optional peer now — installing qdadm no longer drags in svelteEvery consumer inherited three
npm auditadvisories they could not resolve,
with our package named in their output, for a JSON editor most consoles
never open. Measured on a clean install of the packed tarball: a consumer now
gets novanilla-jsoneditor, nosvelte, andnpm auditreports 0
vulnerabilities.Two declarations were wrong, in opposite directions:
vanilla-jsoneditorsat inoptionalDependencies, which npm installs by
default — "optional" there only means "do not fail the install if it
cannot be fetched". Everyone got it.- It also had a
peerDependenciesMeta.optionalentry while not being a peer
dependency at all, so the intent "optional peer" was written but never
implemented.
It is now an optional
peerDependency, where that meta entry finally takes
effect, matching the/editorssubpath that was always opt-in.BREAKING in practice. An app that imports
@quazardous/qdadm/editors
without declaringvanilla-jsoneditorwill fail to build after this upgrade.
That is the correct behaviour — it was depending on something it never asked
for — but it will not fail quietly:npm install -D vanilla-jsoneditor
The pin moves from
^0.23.0to^3.13.0, three majors on. That is what
clears the advisories: 0.23 pulls svelte 4 and its six XSS notices, 3.13 pulls
svelte 5 and is clean. The editor's own API changed with it —
new JSONEditor(...)is deprecated in favour ofcreateJSONEditor(...)— and
qdadm's wrapper is migrated, so consumers usingVanillaJsonEditoror
JsonStructuredFieldsee no difference. Consumers calling the library
directly should read its 1.x/2.x/3.x notes.Also fixed while in there:
peerDependenciesMeta.sass-embedded.optionalwas
the string"true"rather than the boolean, so that optionality had never
applied either. -
343e387:
showis a real layout now, instead of a name nothing could honourcrud({ show })has always registered its detail route with
meta: { layout: 'show' }— for a layout that existed nowhere.LAYOUT_TYPES
knew four names andshowwas not among them; the Kernel built its layout map
as a closed four-key literal, so alayouts: { show }an app passed was
dropped without a word; and no name pattern could reach it either. The
resolver returned'show', found no component under that key, and fell back
tobase— gracefully, which is exactly what made it invisible. The only way
to dress a detail page was to lie and declare it a form.showis now a layout like the others, reachable four ways:meta.layout, a
layouts: { show }(orShowLayout) on the kernel, a*-showroute name, or
a*Showcomponent name. The last two matter more than they look: an app that
declares its detail route by hand rather than throughcrud({ show })has no
meta.layoutto go on, and they are its only path.Inert unless you ask for it. With no
showlayout supplied, resolution
reaches'show', findsnull, and falls back tobaseexactly as before. No
existing page changes appearance. To use it, passlayouts: { show }.
Patch Changes
- Updated dependencies [05a334c]
- @quazardous/qdcore@1.2.0