Node library (premium)
Changes to @eluvia/habarico-enterprise, the paid layer of the JavaScript library. The free core is
habarico — its changelog lives in the habarico repository, in node/CHANGELOG.md.
Format follows Keep a Changelog.
[7.2.0] — 2026-10-19
Changed
- BREAKING: The free library is the unscoped
habaricofrom npmjs.com, required at>=7.2.0as both peer and dev dependency, in place of@eluvia/habarico. Applications installhabaricoand import from it. (HAB-1034)
[7.0.0] — 2026-10-10
Added
- Initial package, holding the paid features split out of
@eluvia/habaricoalong the open-core boundary between the free and the paid library. (HAB-813) EnterpriseSchemaAdmin— a drop-in replacement forSchemaAdminthat pre-wires every paid provider, the dashboard and the search slot. Changing one import is the whole integration; anything the application passes itself still wins. It also addspreferences.dashboardtoSchemaAdmin'spreferencesWhitelist: the key stays a free preference on both backends, but only this package can produce it. (HAB-813, HAB-857)- The paid data and schema providers:
getEnterpriseDataProviderFactoryaddsaggregateandsearch,getEnterpriseSchemaProvideraddsgetAggregateSchema. All three call endpoints only a habarico-enterprise backend serves, and all three moved out of the free package, which had no caller for any of them. Both are drop-in replacements with the same signature as their free counterparts, so they go straight intoSchemaAdmin'sdataProviderFactoryandschemaProviderFactoryprops —EnterpriseSchemaAdminpasses both by default, so neither has to be named. There is one provider of each kind, not a base and an extension. Every method is optional at the point of use: an application still running the free providers reports aggregations and global search as unsupported — the widgets render their existing unsupported state and the search overlay stays empty — rather than throwing on a method that is not there. (HAB-857) EnterpriseDataProviderdeclaresaggregateandsearchas required — the factory always supplies them — andMaybeEnterpriseDataProvideris what reading code asks for, with the two optional. React Admin'suseDataProvider<T>()is a plain assertion, so the optionality has to come from the type:useDataProvider<MaybeEnterpriseDataProvider>(). It is the counterpart of what the freeuseSchemaProvider<T>()does for the schema provider. (HAB-857)- Dashboard and widgets:
SchemaDashboard, all six widget types and the definition wizard, plusenterpriseWidgetProviderandenterpriseWidgetTypes. The grid organism, the layout store and the widget vocabulary stay in the free package. (HAB-813) - The widget catalogue itself —
WidgetCatalogProvider,useGetWidgetanduseSupportedWidgetTypes. Resolving a type to a widget used to be a free extension point (widgetProvider/supportedWidgetTypesonSchemaAdmin) that only this package ever reached, so it moved here with the dashboard that calls it. Its default value is the paid catalogue, which makesSchemaDashboardwork with no wiring at all; wrap a subtree inWidgetCatalogProvider, or pass the same two values toEnterpriseSchemaAdmin, to add widget types of your own. (HAB-813) - The aggregate and dashboard hooks moved here with the dashboard they serve:
useAggregate,useSimpleAggregate,useGetAggregateSchema,useDashboardStore,overlaps/assertNoOverlapsandserializeGroupByItem. (HAB-857) - The wire and dashboard vocabulary they build on is now declared here rather than imported from
the free package —
AggregateSchema,AggregateBucket,AggregateParams,GroupByItem,AggregateFunctionType,TruncGranularity,ChartOptions,WidgetConfig,WidgetLayout,WidgetType,DashboardPreference, the search result types — together with the contract a widget component is registered and configured by (WidgetDefinition,AdminWidgetProvider,WidgetRenderProps,WidgetConfigStepProps,WidgetDataSource,WidgetConfigFormState/WidgetConfigFormSetters).AggregateFieldSchemais declared here too, as the contract has it: a shape of its own rather than the resourceFieldSchemawith the aggregation whitelists added, since the aggregate endpoint sends neithersortable/readOnly/requirednorformat.WidgetConfigStepProps.availableFieldsis aWidgetConfigField[]— exactly what a config step reads — so an aggregate schema's fields are passed to it unchanged, with no descriptor conversion in between. (HAB-857) - Global search:
SchemaSearchanduseGetServiceSearch, moved out of the free package. PassSchemaSearchtoSchemaAdmin'ssearchprop, or renderEnterpriseSchemaAdmin. The overlay, the toggle and the keyboard shortcut stay in the free design system — only the container that queries the endpoint is paid. (HAB-813) - AI assistant button and predictive text input, moved out of the free package, plus
enterpriseButtonProviderandenterpriseInputProviderwhich register them for theai-assistantaction and theai/ai-textformats. (HAB-813) - A 4000-character cap on the assistant's chat input, mirroring the server's
ai_assistant_max_message_lengthdefault so the one payload the endpoint still refuses cannot be produced from the UI by pasting. (HAB-907) - Czech localflavor inputs and the bank account field, moved out of the free package, registered
through
enterpriseInputProviderandenterpriseFieldProviderfor theczech-*formats. TheczechBankAccounthelpers and theBank/BankAccounttypes are exported too. (HAB-813) - Each paid provider delegates every format and action type it does not own to the matching free default, so passing one never changes free behaviour. (HAB-813)
- Chunked upload transport (S3 multipart and tus, over Uppy), moved out of the free package.
Importing
habarico-enterpriseregisters it through the core'sregisterChunkedUploadTransport, so a schema that setsoptions.uploadworks with no further wiring.uploadFileChunkedis also exported for a project that wants to wrap or replace it. (HAB-813) - Storybook, with the stories that came across with the components and a story harness of its own
(
src/admin/components/_storyKit.tsx) — the free package's harness is story-support code it deliberately does not export. Story titles are unchanged, so story ids and the documentation links built from them survive the move.npm run test:storybookrenders every story in headless Chromium and runs in CI, same as the free package. (HAB-813)
Changed
- BREAKING: the package is renamed from
habarico-enterpriseto@eluvia/habarico-enterprise, and the import path changes with it. npm resolves a private registry per scope only — an unscoped name has no way to point at the GitLab registry and always resolves from registry.npmjs.org. Nothing was ever published under the old name, so no installed version is affected. (HAB-812) - BREAKING: the package moves to version 7, the major of the
@eluvia/habaricoit extends, and requires@eluvia/habarico>=7.0.0as both peer and dev dependency. The two packages share their major from here on, so the version of the free package names the paid one that goes with it. (HAB-857, HAB-1019) FiltersPickerin the widget definition wizard now renders its rows through the free package'sFormTableinstead of a hand-rolledStack— the same add / remove / clear-all chrome and labels every other form array in the library uses. The free package made this change after the component had already moved here, so it never reached the paid copy. (HAB-857)SchemaDashboard's edit-mode toggle drops its label below thesmbreakpoint, leaving an icon-only button (styling unchanged, label shown as its tooltip instead) so it no longer crowds the dashboard title on mobile. (HAB-924)lodashreplaced withlodash-es. The two files that used it (CzechBankAccountField,SchemaPredictiveTextInput) now import the single function each one needs (import {get} from 'lodash-es') instead of the whole library through the_default import, so rollup tree-shakes the rest. Both bundles are roughly halved (lib/index.cjs1 086 kB → 543 kB,lib/index.esm.js1 080 kB → 537 kB);lodash-esis bundled in, not externalized, so the CJS build stays plain CommonJS.lodash-esis also declared independenciesnow —lodashnever was, and the build only worked because a hoisted copy happened to be there. (HAB-949)
Fixed
EnterpriseSchemaAdminno longer drops the paid providers when the application passes one of its own.fieldProvider,inputProviderandbuttonProviderwere handed toSchemaAdminahead of the{...props}spread, so a<EnterpriseSchemaAdmin fieldProvider={…} />replaced the paid provider instead of layering on top of it — and every format only this package renders (czech-bank-account, theai/ai-textinputs, theai-assistantbutton) silently stopped appearing, with no error anywhere. There is one admin-wide slot per registry and both sides need it, so the two providers are now composed rather than one replacing the other: the application's provider is asked first and the paid one answers for everything it returnsundefinedfor.nullstill renders nothing, so a field the application suppresses stays suppressed. Nothing changes for an application that passes no provider of its own — the paid one is passed through unwrapped, identity included. An application wiring the paid providers by hand (SchemaAdminplus the individual exports) composes them itself, as before — returnenterpriseFieldProvider(providerProps)at the end of your own. (HAB-1008)- The widget definition wizard no longer clips what reaches past its content edge: the floating label of a filled input at the top of a step (the source picker, the label field) is shown whole below the stepper, and the type list's radio buttons keep their full circle and hover halo. (HAB-1009)
- The widget definition wizard no longer refills a label the user cleared. The suggested
"
- " label is filled in once, on entering the configuration step, so the field can be emptied and retyped. The label-only configuration step of widgets without a ConfigStepalso keeps focus while typing instead of remounting on every keystroke. (HAB-1010) CzechIdCardNumberInputno longer reports an invalid value as "Must match a specific format (regexp): [object Object]". The validator borrowed the message of React Admin'sregex(), whose pattern arg does not survive the JSON the error is passed as, and which would only have named the nine-digit format out of four. It now returns its own message,ra.validation.czech_id_card_number, which@eluvia/habaricotranslates; against a release without the key it reads "Invalid ID document number". (HAB-970)CzechBankAccountInputno longer merges the prefix into the account number. A non-digit typed into the number (a space, say) was stored as-is, the value then failed to parse, and the prefix ended up inside the number. Non-digits are now dropped as they are typed. A full number or prefix also refuses more digits instead of dropping its last one, and clearing the number keeps the prefix and bank code. (HAB-968)- Pasting into
CzechBankAccountInputworks again. The paste handler cancelled every paste and only applied one that was a whole account with a prefix and a listed bank code, so bare digits, or an account without a prefix, could not be pasted into either part. A paste now edits like typing: the part pasted into gets the text at the caret, and a paste that would not fit is refused as a whole, like a keystroke into a full part. The other parts the text carries (19-2000145399/0800,2000145399/0800,19-2000145399) are filled in, while the ones it does not carry keep their value. Text without the part it is pasted into (2000145399/0800into the prefix) is refused. Whitespace in the pasted text is ignored. (HAB-968) - A failed prediction no longer escapes as an unhandled promise rejection.
SchemaPredictiveTextInputawaited the endpoint with no error handling at all, and the debounce that drives it calls the handler without awaiting, so a rejected request had nowhere to go. A prediction is an unrequested convenience, so a failure now just clears the suggestion. (HAB-907) - The AI assistant reports what actually went wrong. Every failure was replaced with the generic
ra.ai.error_message, discarding the message the data provider had already unpacked from the API error envelope — and which the backend translates. It now falls back to the generic text only when there is nothing to show, using core'sextractErrorMessagethe same wayuseSubmitFormand the auth forms do. (HAB-907) - The published package no longer ships
lib/dts/— the intermediate declarations rollup bundles intolib/index.d.ts. They carried 224 files of internal structure, including typings for the test suite and the Storybook helpers.lib/index.d.tsnever referenced them. (HAB-812)
Security
getEnterpriseDataProviderFactory'ssearchmethod now percent-encodes the search query instead of interpolating it into?search=...unescaped, andCzechIcoInputdoes the same for the IČO it sends to the ARES endpoint. (HAB-919)- Fixed the
decode-uri-componenttransitive vulnerability via anoverridesentry pinning it to ≥0.5.0 (not reachable throughnpm audit fixalone). (HAB-896) - The AI assistant no longer applies suggestion keys it never offered.
SchemaAiAssistantFormDialogcalledsetValuefor every key in the LLM response as-is, so a prompt-injected reply could write a hidden/read-only field or a__proto__path - including by nesting the payload (e.g.{address: {...}}), since the parent field name alone was also a valid match. Suggestions are now flattened to leaf dot-paths first and matched against theaiFieldssent in the request. (HAB-909, HAB-896)