⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components (#13940)

* ⬆️ chore: Migrate off deprecated @ariakit/react-core to @ariakit/react-components

@ariakit/react-core and its dependency @ariakit/core are deprecated (split into successor packages) and emit install-time warnings. @ariakit/react already ships the non-deprecated @ariakit/react-components transitively; the only direct use of react-core was the SelectRenderer deep import in ControlCombobox, which is now sourced from @ariakit/react-components/select/select-renderer (identical symbol and subpath). Both deprecated packages drop out of the lockfile and react-components dedupes to the single version @ariakit/react pins.

*  test: Resolve ESM-only @ariakit split packages in jest

@ariakit/react-components and its peers are ESM-only (type: module) and declare only an import export condition, so jest's CJS resolver can't load them when @librechat/client's CJS build requires SelectRenderer. Add a custom jest resolver that resolves these @ariakit/* split packages with the import condition, and extend transformIgnorePatterns so babel transpiles them to CJS. Applied to both the client and packages/client jest configs.
This commit is contained in:
Danny Avila 2026-06-24 23:13:57 -04:00 committed by GitHub
parent 1dffa100bb
commit 5c5ef37e30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 45 additions and 30 deletions

View file

@ -36,13 +36,14 @@ module.exports = {
restoreMocks: true,
testResultsProcessor: 'jest-junit',
coverageReporters: ['text', 'cobertura', 'lcov'],
resolver: '<rootDir>/jest.resolver.cjs',
transform: {
'\\.[jt]sx?$': 'babel-jest',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'jest-file-loader',
},
transformIgnorePatterns: [
'/node_modules/(?!(@zattoo/use-double-click|@dicebear|@react-dnd|react-dnd.*|dnd-core|filenamify|filename-reserved-regex|heic-to|lowlight|highlight\\.js|fault|react-markdown|unified|bail|trough|devlop|is-.*|parse-entities|stringify-entities|character-.*|trim-lines|style-to-object|inline-style-parser|html-url-attributes|escape-string-regexp|longest-streak|zwitch|ccount|markdown-table|comma-separated-tokens|space-separated-tokens|web-namespaces|property-information|remark-.*|rehype-.*|recma-.*|hast.*|mdast-.*|unist-.*|vfile.*|micromark.*|estree-util-.*|decode-named-character-reference)/)/',
'/node_modules/(?!(@ariakit/react-components|@ariakit/react-utils|@ariakit/react-store|@ariakit/components|@ariakit/store|@ariakit/utils|@zattoo/use-double-click|@dicebear|@react-dnd|react-dnd.*|dnd-core|filenamify|filename-reserved-regex|heic-to|lowlight|highlight\\.js|fault|react-markdown|unified|bail|trough|devlop|is-.*|parse-entities|stringify-entities|character-.*|trim-lines|style-to-object|inline-style-parser|html-url-attributes|escape-string-regexp|longest-streak|zwitch|ccount|markdown-table|comma-separated-tokens|space-separated-tokens|web-namespaces|property-information|remark-.*|rehype-.*|recma-.*|hast.*|mdast-.*|unist-.*|vfile.*|micromark.*|estree-util-.*|decode-named-character-reference)/)/',
],
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect', '<rootDir>/test/setupTests.js'],
clearMocks: true,

17
client/jest.resolver.cjs Normal file
View file

@ -0,0 +1,17 @@
/**
* The modern @ariakit/* split packages (react-components and its peers) are ESM-only and
* declare only an `import` export condition, which jest's CJS resolver can't match. Resolve
* those with the `import` condition; babel (see transformIgnorePatterns) transpiles them to CJS.
*/
const ESM_ONLY_ARIAKIT =
/^@ariakit\/(react-components|react-utils|react-store|components|store|utils)(\/|$)/;
module.exports = (request, options) => {
if (ESM_ONLY_ARIAKIT.test(request)) {
return options.defaultResolver(request, {
...options,
conditions: [...(options.conditions ?? []), 'import'],
});
}
return options.defaultResolver(request, options);
};

View file

@ -30,7 +30,7 @@
"homepage": "https://librechat.ai",
"dependencies": {
"@ariakit/react": "^0.4.29",
"@ariakit/react-core": "^0.4.26",
"@ariakit/react-components": "^0.1.2",
"@codesandbox/sandpack-react": "^2.19.10",
"@dicebear/collection": "^9.4.1",
"@dicebear/core": "^9.4.1",

27
package-lock.json generated
View file

@ -414,7 +414,7 @@
"license": "ISC",
"dependencies": {
"@ariakit/react": "^0.4.29",
"@ariakit/react-core": "^0.4.26",
"@ariakit/react-components": "^0.1.2",
"@codesandbox/sandpack-react": "^2.19.10",
"@dicebear/collection": "^9.4.1",
"@dicebear/core": "^9.4.1",
@ -773,13 +773,6 @@
"@ariakit/utils": "0.1.2"
}
},
"node_modules/@ariakit/core": {
"version": "0.4.20",
"resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.20.tgz",
"integrity": "sha512-DJbUnui0fM+2ZgiWLOMuFOmlWSJDNV3f6tqghIYRTWEm51TN/LoU6uM8og6/g7Nrwl4Uo5l8AoQT9Kkr/i/uRg==",
"deprecated": "This package has been split into smaller packages. Use @ariakit/components, @ariakit/store, or @ariakit/utils depending on the APIs you need.",
"license": "MIT"
},
"node_modules/@ariakit/react": {
"version": "0.4.29",
"resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.29.tgz",
@ -815,22 +808,6 @@
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@ariakit/react-core": {
"version": "0.4.26",
"resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.26.tgz",
"integrity": "sha512-/Peh1KiVpjj79nCJIa6lEdzSTT9P9FZoy+CxByIFKL3YKdlXmDIIhS1E/tAqKbDq4ODVdynnqmrIDxE5wCoZYw==",
"deprecated": "This package has been split into smaller packages. Use @ariakit/react-components or @ariakit/react-utils depending on the APIs you need.",
"license": "MIT",
"dependencies": {
"@ariakit/core": "0.4.20",
"@floating-ui/dom": "^1.0.0",
"use-sync-external-store": "^1.6.0"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@ariakit/react-store": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@ariakit/react-store/-/react-store-0.1.2.tgz",
@ -43056,7 +43033,7 @@
},
"peerDependencies": {
"@ariakit/react": "^0.4.29",
"@ariakit/react-core": "^0.4.26",
"@ariakit/react-components": "^0.1.2",
"@dicebear/collection": "^9.4.1",
"@dicebear/core": "^9.4.1",
"@headlessui/react": "^2.1.2",

View file

@ -22,9 +22,12 @@ export default {
// React component testing requires jsdom environment
testEnvironment: 'jsdom',
testEnvironmentOptions: { url: 'http://localhost:3080' },
resolver: '<rootDir>/jest.resolver.cjs',
transform: {
'^.+\\.(ts|tsx|js|jsx)$': 'babel-jest',
},
transformIgnorePatterns: ['node_modules/(?!(@tanstack|lucide-react|@dicebear)/)'],
transformIgnorePatterns: [
'node_modules/(?!(@tanstack|lucide-react|@dicebear|@ariakit/react-components|@ariakit/react-utils|@ariakit/react-store|@ariakit/components|@ariakit/store|@ariakit/utils)/)',
],
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};

View file

@ -0,0 +1,17 @@
/**
* The modern @ariakit/* split packages (react-components and its peers) are ESM-only and
* declare only an `import` export condition, which jest's CJS resolver can't match. Resolve
* those with the `import` condition; babel (see transformIgnorePatterns) transpiles them to CJS.
*/
const ESM_ONLY_ARIAKIT =
/^@ariakit\/(react-components|react-utils|react-store|components|store|utils)(\/|$)/;
module.exports = (request, options) => {
if (ESM_ONLY_ARIAKIT.test(request)) {
return options.defaultResolver(request, {
...options,
conditions: [...(options.conditions ?? []), 'import'],
});
}
return options.defaultResolver(request, options);
};

View file

@ -37,7 +37,7 @@
},
"peerDependencies": {
"@ariakit/react": "^0.4.29",
"@ariakit/react-core": "^0.4.26",
"@ariakit/react-components": "^0.1.2",
"@dicebear/collection": "^9.4.1",
"@dicebear/core": "^9.4.1",
"@headlessui/react": "^2.1.2",

View file

@ -2,7 +2,7 @@ import { useMemo, useState, useRef, memo, useEffect, MemoExoticComponent } from
import * as Ariakit from '@ariakit/react';
import { matchSorter } from 'match-sorter';
import { Search, ChevronDown } from 'lucide-react';
import { SelectRenderer } from '@ariakit/react-core/select/select-renderer';
import { SelectRenderer } from '@ariakit/react-components/select/select-renderer';
import type { OptionWithIcon } from '~/common';
import './AnimatePopover.css';
import { JSX } from 'react/jsx-runtime';