Skip to main content

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 habarico from npmjs.com, required at >=7.2.0 as both peer and dev dependency, in place of @eluvia/habarico. Applications install habarico and import from it. (HAB-1034)

[7.0.0] — 2026-10-10​

Added​

  • Initial package, holding the paid features split out of @eluvia/habarico along the open-core boundary between the free and the paid library. (HAB-813)
  • EnterpriseSchemaAdmin — a drop-in replacement for SchemaAdmin that 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 adds preferences.dashboard to SchemaAdmin's preferencesWhitelist: 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: getEnterpriseDataProviderFactory adds aggregate and search, getEnterpriseSchemaProvider adds getAggregateSchema. 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 into SchemaAdmin's dataProviderFactory and schemaProviderFactory props — EnterpriseSchemaAdmin passes 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)
  • EnterpriseDataProvider declares aggregate and search as required — the factory always supplies them — and MaybeEnterpriseDataProvider is what reading code asks for, with the two optional. React Admin's useDataProvider<T>() is a plain assertion, so the optionality has to come from the type: useDataProvider<MaybeEnterpriseDataProvider>(). It is the counterpart of what the free useSchemaProvider<T>() does for the schema provider. (HAB-857)
  • Dashboard and widgets: SchemaDashboard, all six widget types and the definition wizard, plus enterpriseWidgetProvider and enterpriseWidgetTypes. The grid organism, the layout store and the widget vocabulary stay in the free package. (HAB-813)
  • The widget catalogue itself — WidgetCatalogProvider, useGetWidget and useSupportedWidgetTypes. Resolving a type to a widget used to be a free extension point (widgetProvider / supportedWidgetTypes on SchemaAdmin) that only this package ever reached, so it moved here with the dashboard that calls it. Its default value is the paid catalogue, which makes SchemaDashboard work with no wiring at all; wrap a subtree in WidgetCatalogProvider, or pass the same two values to EnterpriseSchemaAdmin, 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 / assertNoOverlaps and serializeGroupByItem. (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). AggregateFieldSchema is declared here too, as the contract has it: a shape of its own rather than the resource FieldSchema with the aggregation whitelists added, since the aggregate endpoint sends neither sortable / readOnly / required nor format. WidgetConfigStepProps.availableFields is a WidgetConfigField[] — 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: SchemaSearch and useGetServiceSearch, moved out of the free package. Pass SchemaSearch to SchemaAdmin's search prop, or render EnterpriseSchemaAdmin. 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 enterpriseButtonProvider and enterpriseInputProvider which register them for the ai-assistant action and the ai / ai-text formats. (HAB-813)
  • A 4000-character cap on the assistant's chat input, mirroring the server's ai_assistant_max_message_length default 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 enterpriseInputProvider and enterpriseFieldProvider for the czech-* formats. The czechBankAccount helpers and the Bank / BankAccount types 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-enterprise registers it through the core's registerChunkedUploadTransport, so a schema that sets options.upload works with no further wiring. uploadFileChunked is 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:storybook renders every story in headless Chromium and runs in CI, same as the free package. (HAB-813)

Changed​

  • BREAKING: the package is renamed from habarico-enterprise to @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/habarico it extends, and requires @eluvia/habarico >=7.0.0 as 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)
  • FiltersPicker in the widget definition wizard now renders its rows through the free package's FormTable instead of a hand-rolled Stack — 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 the sm breakpoint, 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)
  • lodash replaced with lodash-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.cjs 1 086 kB → 543 kB, lib/index.esm.js 1 080 kB → 537 kB); lodash-es is bundled in, not externalized, so the CJS build stays plain CommonJS. lodash-es is also declared in dependencies now — lodash never was, and the build only worked because a hoisted copy happened to be there. (HAB-949)

Fixed​

  • EnterpriseSchemaAdmin no longer drops the paid providers when the application passes one of its own. fieldProvider, inputProvider and buttonProvider were handed to SchemaAdmin ahead 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, the ai / ai-text inputs, the ai-assistant button) 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 returns undefined for. null still 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 (SchemaAdmin plus the individual exports) composes them itself, as before — return enterpriseFieldProvider(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 ConfigStep also keeps focus while typing instead of remounting on every keystroke. (HAB-1010)
  • CzechIdCardNumberInput no longer reports an invalid value as "Must match a specific format (regexp): [object Object]". The validator borrowed the message of React Admin's regex(), 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/habarico translates; against a release without the key it reads "Invalid ID document number". (HAB-970)
  • CzechBankAccountInput no 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 CzechBankAccountInput works 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/0800 into the prefix) is refused. Whitespace in the pasted text is ignored. (HAB-968)
  • A failed prediction no longer escapes as an unhandled promise rejection. SchemaPredictiveTextInput awaited 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's extractErrorMessage the same way useSubmitForm and the auth forms do. (HAB-907)
  • The published package no longer ships lib/dts/ — the intermediate declarations rollup bundles into lib/index.d.ts. They carried 224 files of internal structure, including typings for the test suite and the Storybook helpers. lib/index.d.ts never referenced them. (HAB-812)

Security​

  • getEnterpriseDataProviderFactory's search method now percent-encodes the search query instead of interpolating it into ?search=... unescaped, and CzechIcoInput does the same for the IČO it sends to the ARES endpoint. (HAB-919)
  • Fixed the decode-uri-component transitive vulnerability via an overrides entry pinning it to ≥0.5.0 (not reachable through npm audit fix alone). (HAB-896)
  • The AI assistant no longer applies suggestion keys it never offered. SchemaAiAssistantFormDialog called setValue for 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 the aiFields sent in the request. (HAB-909, HAB-896)