v10.0.0-rc.16
Pre-releaseFixed
-
The single "install with Yarn Classic and check for a duplicate" verification
build/verify-npm-single-copy.mjsperforms for issue #211 ran only after both Angular publish
steps inrelease.yml, so a real duplicate reaching consumers would be reported only once the
damage was already done - the same failure shapev10.0.0-rc.14's own post-publish crash exposed:
the check runs at all, but by the time it can fail, everything is already live on npmjs and GitHub
Packages, and a failure there can only skip the draft GitHub Release, not stop a bad publish.
verify-npm-single-copy.mjsnow supports two modes.packedinstalls the five tarballs the
workflow's ownnpm packsteps already produce, pointing each@dignite/*dependency at its
tarball with afile:path instead of a registry range - Yarn Classic resolves afile:
dependency's version from the tarball's ownpackage.jsonand reconciles it against every other
edge in the graph exactly as it would a registry-resolved copy, so it exercises the same
duplicate-vs-dedupe logic without anything published yet. A new "Verify packed Angular packages
install as a single copy each" step runs this immediately after the last pack step, with noif:
guard, so both aworkflow_dispatchpreview build and a tagged release get the real gate.
publishedis the previous behavior, kept as a lighter step after the npm publish - it still
catches what a local tarball cannot, such as a dist-tag pointing at the wrong version, but a
failure there is no longer the only line of defense. -
The new
packedmode above failed outright the first time it ran against a version that had
never been published anywhere (Couldn't find any versions for "@dignite/ng.file-explorer" that matches "^10.0.0-rc.16"), because it only pointed the top-level dependency at each tarball's
file:path - a sibling package's own packedpackage.json(e.g.
flex-fields-file-explorerdepending onflex-fields) still declares that edge as a plain semver
range, and Yarn Classic resolves afile:request and a semver-range request for the same package
name as two independent lookups rather than reusing one to satisfy the other. It went to the npm
registry for the range and failed, since nothing at that version exists there yet - exactly the
case this check exists to run before.verify-npm-single-copy.mjs'spackedmode now also sets
resolutionsto the same fivefile:paths, forcing every occurrence of a name in the tree onto
the local tarball regardless of what range asked for it. This doesn't weaken the check:
verify-version-lockstep.ps1already rejects a drifted internal range before this step ever runs,
so every internal@dignite/*range is already^<the current version>by the timepackedmode
installs. -
This repository's own
flex-fields/angularandfile-storing/angulardemo apps were themselves
carrying the exactng-zorro-antdduplicate6f039efdocumented as an accepted cost of
@abp/ng.componentspinning that package at~21.0.0-next.1(i.e.<21.1.0):21.3.3at each
workspace root, declared there only for the demo's own use, and21.0.2nested under
node_modules/@abp/ng.components/node_modules- two module-scopedNZ_CONFIG/NzConfigService
tokens, so a root-levelprovideNzConfig()/provideNzI18n()never reached the copy
@abp/ng.components's own controls (e.g.abp-tree) resolve. That duplication is inherent to
@dignite/ng.flex-fields's and@dignite/ng.file-explorer's published^21.0.0peer range - a
real downstream host may need21.3.xfor reasons the packages can't rule out, which is why that
peer range is untouched - but nothing required these two demo apps to actually be such a host:
they exist to exercise the published packages, not to prove a wide peer range works.ng-zorro-antd
is now narrowed to~21.0.2in bothflex-fields/angular/package.jsonand
file-storing/angular/package.json- inside@abp/ng.components's ceiling, and the same version
that was already nested - which collapses both workspaces back to a single copy. Both demo apps'
production builds (yarn build:prod) pass unchanged at the older version. A new
build/check-angular-package-duplicates.mjs, wired intoci.ymlimmediately after each of the
three Angular workspaces'yarn install --frozen-lockfilesteps, generalizes
verify-npm-single-copy.mjs's duplicate check from the five@dignite/*packages it covers to any
bare-or-scoped target list -ng-zorro-antdand@angular/cdkfor now, the latter reaching these
same packages by the same@abp/ng.componentsroute even though no version conflict currently
splits it.notifications/angularis checked too even though it declares neither package itself:
it depends on@abp/ng.components, which pulls both in transitively, so it is exposed to the same
failure mode the moment something else in that workspace narrows either range. Like its sibling
script, a target that matches nothing installed fails the run rather than passing vacuously - a
typo'd target or a check pointed at the wrongnode_modulesis otherwise indistinguishable from a
clean tree.
Added
flex-fields
- Two new built-in field types,
MatrixandTable— the first composite ones, whose
configuration declares whole field definitions inline.Matrixis a repeatable list of
polymorphic blocks (the admin declares named block types up front, each with its own sub-fields);
Tableis a homogeneous grid over one shared column schema. Both were written and proven in
Dignite.Site'sDignite.FlexFields.Siteand are ported here with the wire format unchanged —
registration keysMatrix/Table, configuration keysMatrix.BlockTypes/Table.Columns, and
camelCase{blockTypeName, values}/{values}value arrays — so fields already stored against
the Site implementation keep working as-is. They ship as built-ins rather than a bolt-on package
because, unlikeFileExplorerorCKEditor, they depend on nothing outside the kernel's own
vocabulary; what made them worth moving is that the two contracts below have to be answerable
without knowing either concrete type.Dignite.Abp.FlexFields.AbstractionsgainsMatrixFieldType/TableFieldTypeand their
configuration types, plus four kernel contracts they share:ICompositeFieldType
(GetInlineFields, so a host can ask "does this type contain other fields, and which" without
naming a concrete type — an interface rather than anIsCompositebool, because every caller
that asks also has to walk those fields),INormalizesValue(Normalize, the canonical wire
shape — deliberately not folded intoValidate, which returns only errors and never the parsed
value, so a value with the wrong key casing would otherwise validate cleanly and then be stored
verbatim and be unreadable to every camelCase reader downstream),InlineFieldDefinition
(one inline field; carriesRequired, which aFlexFieldDatacannot), and
CompositeFieldNesting(MaxDepth = 3and the bounded measurement that enforces it — a
configuration is a tree of unbounded depth and every reader of it recurses, so it is capped once
on write instead of guarded in each reader).Dignite.Abp.FlexFields.WebgainsViews/Shared/FlexFields/Matrix.cshtmlandTable.cshtml,
which recurse through the existing<flex-field-view>dispatch for each sub-field rather than
re-implementing rendering per type. NoSearch/partials: both types have
IndexValueType == null— a list of composite objects has no typed index column to decompose
into — so neither can be markedSearchable.@dignite/ng.flex-fieldsgains the matching config / control / view components
(ff-matrix-config|control|view,ff-table-config|control|view), registered in
BUILT_IN_FIELD_TYPES, so an existingprovideFlexFields()call already covers them.
FieldTypeDefinitiongains an optionalcompositeflag, which Matrix and Table set and the
config editors use to stop offering composite types once the nesting limit is reached; the
server'sCompositeFieldNestingremains the authority, that mirror is a courtesy.- Neither contract is invoked by the kernel — a host calls them, and the demo now shows both:
ProductAppServicenormalizes the value bag before validating and saving, and
ProductFieldAppServicerefuses a too-deeply-nested configuration on create and update. - Localization moved with them: the
FieldType:Matrix/FieldType:Table,Matrix:*,Table:*
andValidate:Matrix:*/Validate:Table:*texts now live in theFlexFieldsresource
(Dignite.Abp.FlexFields.Abstractions) instead of Site's ownFlexFieldsSiteresource, in all
four shipped cultures (en,ja,zh-Hans,zh-Hant). Three general validation keys the
Angular side's shared error-message helper needs came along with them:Validate:MinValue,
Validate:MaxValueandValidate:MaxLength.