@verdaccio/ui-components 5.0.0-next-9.7 → 5.0.0-next-9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/ActionBar/ActionBarAction.mjs +2 -2
- package/build/components/ActionBar/ActionBarAction.mjs.map +1 -1
- package/build/components/ErrorBoundary/ErrorBoundary.d.ts +1 -1
- package/build/components/Package/Package.mjs +2 -2
- package/build/components/Package/Package.mjs.map +1 -1
- package/build/components/Search/Search.js +15 -30
- package/build/components/Search/Search.js.map +1 -1
- package/build/components/Search/Search.mjs +15 -30
- package/build/components/Search/Search.mjs.map +1 -1
- package/build/components/Search/utils.d.ts +21 -0
- package/build/components/Search/utils.js +37 -0
- package/build/components/Search/utils.js.map +1 -1
- package/build/components/Search/utils.mjs +37 -1
- package/build/components/Search/utils.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -9,7 +9,7 @@ import Tooltip from "@mui/material/Tooltip";
|
|
|
9
9
|
import { useCallback } from "react";
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
import { useTranslation } from "react-i18next";
|
|
12
|
-
import
|
|
12
|
+
import BugReportIcon from "@mui/icons-material/BugReport";
|
|
13
13
|
import DownloadIcon from "@mui/icons-material/CloudDownload";
|
|
14
14
|
import HomeIcon from "@mui/icons-material/Home";
|
|
15
15
|
import RawOnIcon from "@mui/icons-material/RawOn";
|
|
@@ -52,7 +52,7 @@ var ActionBarAction = ({ type, link, action }) => {
|
|
|
52
52
|
variant: "button",
|
|
53
53
|
children: /* @__PURE__ */ jsx(Fab, {
|
|
54
54
|
size: "small",
|
|
55
|
-
children: /* @__PURE__ */ jsx(
|
|
55
|
+
children: /* @__PURE__ */ jsx(BugReportIcon, {})
|
|
56
56
|
})
|
|
57
57
|
})
|
|
58
58
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionBarAction.mjs","names":[],"sources":["../../../src/components/ActionBar/ActionBarAction.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport BugReportIcon from '@mui/icons-material/BugReport';\nimport DownloadIcon from '@mui/icons-material/CloudDownload';\nimport HomeIcon from '@mui/icons-material/Home';\nimport RawOnIcon from '@mui/icons-material/RawOn';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport FabMUI from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { common } from '@mui/material/colors';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport type { Theme } from '../../Theme';\nimport { greyMedium } from '../../Theme/colors';\nimport { useDownload, useVersion } from '../../providers';\nimport LinkExternal from '../LinkExternal';\n\nexport const Fab = styled(FabMUI)<{ theme?: Theme }>(({ theme }) => ({\n backgroundColor:\n theme.palette.mode === 'dark' ? theme.palette.secondary.main : theme.palette.primary.main,\n '&:hover': {\n backgroundColor: theme.palette.mode === 'dark' ? greyMedium : undefined,\n color: theme.palette.mode === 'light' ? theme.palette.primary.main : common.white,\n },\n color: common.white,\n}));\n\ntype ActionType = 'VISIT_HOMEPAGE' | 'OPEN_AN_ISSUE' | 'DOWNLOAD_TARBALL' | 'RAW_DATA';\n\nexport interface ActionBarActionProps {\n type: ActionType;\n link?: string;\n action?: () => void;\n}\n\nconst ActionBarAction: React.FC<ActionBarActionProps> = ({ type, link, action }) => {\n const { t } = useTranslation();\n const { isLoading } = useVersion();\n const { downloadTarball } = useDownload();\n\n const handleDownload = useCallback(async () => {\n downloadTarball?.({ link: link as string });\n }, [link, downloadTarball]);\n\n switch (type) {\n case 'VISIT_HOMEPAGE':\n return (\n <Tooltip title={t('action-bar-action.visit-home-page') as string}>\n <LinkExternal to={link} variant=\"button\">\n <Fab color=\"primary\" size=\"small\">\n <HomeIcon />\n </Fab>\n </LinkExternal>\n </Tooltip>\n );\n case 'OPEN_AN_ISSUE':\n return (\n <Tooltip title={t('action-bar-action.open-an-issue') as string}>\n <LinkExternal to={link} variant=\"button\">\n <Fab size=\"small\">\n <BugReportIcon />\n </Fab>\n </LinkExternal>\n </Tooltip>\n );\n case 'DOWNLOAD_TARBALL':\n return (\n <Tooltip title={t('action-bar-action.download-tarball') as string}>\n {isLoading ? (\n <CircularProgress sx={{ marginX: 0 }} />\n ) : (\n <Fab data-testid=\"download-tarball-btn\" onClick={handleDownload} size=\"small\">\n <DownloadIcon />\n </Fab>\n )}\n </Tooltip>\n );\n case 'RAW_DATA':\n return (\n <Tooltip title={t('action-bar-action.raw') as string}>\n <Fab data-testid=\"raw-btn\" onClick={action} size=\"small\">\n <RawOnIcon />\n </Fab>\n </Tooltip>\n );\n }\n};\n\nexport default ActionBarAction;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,IAAa,MAAM,OAAO,OAAO,EAAqB,EAAE,aAAa;CACnE,iBACE,MAAM,QAAQ,SAAS,SAAS,MAAM,QAAQ,UAAU,OAAO,MAAM,QAAQ,QAAQ;CACvF,WAAW;EACT,iBAAiB,MAAM,QAAQ,SAAS,SAAS,aAAa,KAAA;EAC9D,OAAO,MAAM,QAAQ,SAAS,UAAU,MAAM,QAAQ,QAAQ,OAAO,OAAO;EAC7E;CACD,OAAO,OAAO;CACf,EAAE;AAUH,IAAM,mBAAmD,EAAE,MAAM,MAAM,aAAa;CAClF,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,cAAc,YAAY;CAClC,MAAM,EAAE,oBAAoB,aAAa;CAEzC,MAAM,iBAAiB,YAAY,YAAY;AAC7C,oBAAkB,EAAQ,MAAgB,CAAC;IAC1C,CAAC,MAAM,gBAAgB,CAAC;AAE3B,SAAQ,MAAR;EACE,KAAK,iBACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,oCAAoC;aACpD,oBAAC,cAAD;IAAc,IAAI;IAAM,SAAQ;cAC9B,oBAAC,KAAD;KAAK,OAAM;KAAU,MAAK;eACxB,oBAAC,UAAD,EAAY,CAAA;KACR,CAAA;IACO,CAAA;GACP,CAAA;EAEd,KAAK,gBACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,kCAAkC;aAClD,oBAAC,cAAD;IAAc,IAAI;IAAM,SAAQ;cAC9B,oBAAC,KAAD;KAAK,MAAK;eACR,oBAAC,
|
|
1
|
+
{"version":3,"file":"ActionBarAction.mjs","names":[],"sources":["../../../src/components/ActionBar/ActionBarAction.tsx"],"sourcesContent":["import styled from '@emotion/styled';\nimport BugReportIcon from '@mui/icons-material/BugReport';\nimport DownloadIcon from '@mui/icons-material/CloudDownload';\nimport HomeIcon from '@mui/icons-material/Home';\nimport RawOnIcon from '@mui/icons-material/RawOn';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport FabMUI from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport { common } from '@mui/material/colors';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport type { Theme } from '../../Theme';\nimport { greyMedium } from '../../Theme/colors';\nimport { useDownload, useVersion } from '../../providers';\nimport LinkExternal from '../LinkExternal';\n\nexport const Fab = styled(FabMUI)<{ theme?: Theme }>(({ theme }) => ({\n backgroundColor:\n theme.palette.mode === 'dark' ? theme.palette.secondary.main : theme.palette.primary.main,\n '&:hover': {\n backgroundColor: theme.palette.mode === 'dark' ? greyMedium : undefined,\n color: theme.palette.mode === 'light' ? theme.palette.primary.main : common.white,\n },\n color: common.white,\n}));\n\ntype ActionType = 'VISIT_HOMEPAGE' | 'OPEN_AN_ISSUE' | 'DOWNLOAD_TARBALL' | 'RAW_DATA';\n\nexport interface ActionBarActionProps {\n type: ActionType;\n link?: string;\n action?: () => void;\n}\n\nconst ActionBarAction: React.FC<ActionBarActionProps> = ({ type, link, action }) => {\n const { t } = useTranslation();\n const { isLoading } = useVersion();\n const { downloadTarball } = useDownload();\n\n const handleDownload = useCallback(async () => {\n downloadTarball?.({ link: link as string });\n }, [link, downloadTarball]);\n\n switch (type) {\n case 'VISIT_HOMEPAGE':\n return (\n <Tooltip title={t('action-bar-action.visit-home-page') as string}>\n <LinkExternal to={link} variant=\"button\">\n <Fab color=\"primary\" size=\"small\">\n <HomeIcon />\n </Fab>\n </LinkExternal>\n </Tooltip>\n );\n case 'OPEN_AN_ISSUE':\n return (\n <Tooltip title={t('action-bar-action.open-an-issue') as string}>\n <LinkExternal to={link} variant=\"button\">\n <Fab size=\"small\">\n <BugReportIcon />\n </Fab>\n </LinkExternal>\n </Tooltip>\n );\n case 'DOWNLOAD_TARBALL':\n return (\n <Tooltip title={t('action-bar-action.download-tarball') as string}>\n {isLoading ? (\n <CircularProgress sx={{ marginX: 0 }} />\n ) : (\n <Fab data-testid=\"download-tarball-btn\" onClick={handleDownload} size=\"small\">\n <DownloadIcon />\n </Fab>\n )}\n </Tooltip>\n );\n case 'RAW_DATA':\n return (\n <Tooltip title={t('action-bar-action.raw') as string}>\n <Fab data-testid=\"raw-btn\" onClick={action} size=\"small\">\n <RawOnIcon />\n </Fab>\n </Tooltip>\n );\n }\n};\n\nexport default ActionBarAction;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,IAAa,MAAM,OAAO,OAAO,EAAqB,EAAE,aAAa;CACnE,iBACE,MAAM,QAAQ,SAAS,SAAS,MAAM,QAAQ,UAAU,OAAO,MAAM,QAAQ,QAAQ;CACvF,WAAW;EACT,iBAAiB,MAAM,QAAQ,SAAS,SAAS,aAAa,KAAA;EAC9D,OAAO,MAAM,QAAQ,SAAS,UAAU,MAAM,QAAQ,QAAQ,OAAO,OAAO;EAC7E;CACD,OAAO,OAAO;CACf,EAAE;AAUH,IAAM,mBAAmD,EAAE,MAAM,MAAM,aAAa;CAClF,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,EAAE,cAAc,YAAY;CAClC,MAAM,EAAE,oBAAoB,aAAa;CAEzC,MAAM,iBAAiB,YAAY,YAAY;AAC7C,oBAAkB,EAAQ,MAAgB,CAAC;IAC1C,CAAC,MAAM,gBAAgB,CAAC;AAE3B,SAAQ,MAAR;EACE,KAAK,iBACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,oCAAoC;aACpD,oBAAC,cAAD;IAAc,IAAI;IAAM,SAAQ;cAC9B,oBAAC,KAAD;KAAK,OAAM;KAAU,MAAK;eACxB,oBAAC,UAAD,EAAY,CAAA;KACR,CAAA;IACO,CAAA;GACP,CAAA;EAEd,KAAK,gBACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,kCAAkC;aAClD,oBAAC,cAAD;IAAc,IAAI;IAAM,SAAQ;cAC9B,oBAAC,KAAD;KAAK,MAAK;eACR,oBAAC,eAAD,EAAiB,CAAA;KACb,CAAA;IACO,CAAA;GACP,CAAA;EAEd,KAAK,mBACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,qCAAqC;aACpD,YACC,oBAAC,kBAAD,EAAkB,IAAI,EAAE,SAAS,GAAG,EAAI,CAAA,GAExC,oBAAC,KAAD;IAAK,eAAY;IAAuB,SAAS;IAAgB,MAAK;cACpE,oBAAC,cAAD,EAAgB,CAAA;IACZ,CAAA;GAEA,CAAA;EAEd,KAAK,WACH,QACE,oBAAC,SAAD;GAAS,OAAO,EAAE,wBAAwB;aACxC,oBAAC,KAAD;IAAK,eAAY;IAAU,SAAS;IAAQ,MAAK;cAC/C,oBAAC,WAAD,EAAa,CAAA;IACT,CAAA;GACE,CAAA"}
|
|
@@ -11,6 +11,6 @@ export default class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBo
|
|
|
11
11
|
state: ErrorBoundaryState;
|
|
12
12
|
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
13
13
|
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
14
|
-
render(): string | number | boolean | Iterable<ReactNode> | React.JSX.Element | null | undefined;
|
|
14
|
+
render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
|
|
15
15
|
}
|
|
16
16
|
export {};
|
|
@@ -20,7 +20,7 @@ import Tooltip from "@mui/material/Tooltip";
|
|
|
20
20
|
import { useCallback } from "react";
|
|
21
21
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
22
22
|
import { useTranslation } from "react-i18next";
|
|
23
|
-
import
|
|
23
|
+
import BugReportIcon from "@mui/icons-material/BugReport";
|
|
24
24
|
import DownloadIcon from "@mui/icons-material/CloudDownload";
|
|
25
25
|
import HomeIcon from "@mui/icons-material/Home";
|
|
26
26
|
import CircularProgress from "@mui/material/CircularProgress";
|
|
@@ -75,7 +75,7 @@ var Package = ({ author: { name: authorName, avatar: authorAvatar }, bugs, descr
|
|
|
75
75
|
"aria-label": t("package.bugs"),
|
|
76
76
|
color: "primary",
|
|
77
77
|
size: "large",
|
|
78
|
-
children: /* @__PURE__ */ jsx(
|
|
78
|
+
children: /* @__PURE__ */ jsx(BugReportIcon, {})
|
|
79
79
|
})
|
|
80
80
|
})
|
|
81
81
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Package.mjs","names":[],"sources":["../../../src/components/Package/Package.tsx"],"sourcesContent":["import { css } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport BugReport from '@mui/icons-material/BugReport';\nimport DownloadIcon from '@mui/icons-material/CloudDownload';\nimport HomeIcon from '@mui/icons-material/Home';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Grid from '@mui/material/Grid';\nimport List from '@mui/material/List';\nimport ListItem from '@mui/material/ListItem';\nimport Tooltip from '@mui/material/Tooltip';\nimport { common, grey } from '@mui/material/colors';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport type { Theme } from '../../';\nimport { Link, LinkExternal, useDownload, useManifests } from '../../';\nimport { FileBinary, Law, Time, Version } from '../../components/Icons';\nimport { getConfiguration } from '../../configuration';\nimport type { Author as PackageAuthor } from '../../providers/ManifestsProvider/ManifestsProvider';\nimport type { PackageMetaInterface } from '../../types/packageMeta';\nimport { Route, url, utils } from '../../utils';\nimport KeywordListItems from '../Keywords/KeywordListItems';\nimport {\n Author,\n Avatar,\n Description,\n Details,\n GridRightAligned,\n IconButton,\n OverviewItem,\n PackageListItemText,\n PackageTitle,\n Published,\n Wrapper,\n WrapperLink,\n} from './styles';\n\ninterface Bugs {\n url: string;\n}\n\ninterface Dist {\n unpackedSize: number;\n tarball: string;\n}\n\nexport interface PackageInterface {\n name: string;\n version: string;\n time?: number | string;\n author: PackageAuthor;\n description?: string;\n keywords?: PackageMetaInterface['latest']['keywords'];\n license?: PackageMetaInterface['latest']['license'];\n homepage?: string;\n bugs?: Bugs;\n dist?: Dist;\n showDownload?: boolean;\n}\n\nconst Package: React.FC<PackageInterface> = ({\n author: { name: authorName, avatar: authorAvatar },\n bugs,\n description,\n dist,\n homepage,\n keywords,\n license,\n name: packageName,\n time,\n showDownload = true,\n version,\n}) => {\n const config = getConfiguration();\n const { t } = useTranslation();\n const { isLoading } = useManifests();\n const { downloadTarball } = useDownload();\n\n const handleDownload = useCallback(\n async (tarballDist: string) => {\n // FIXME: check, the dist might be different thant npmjs\n const link = tarballDist.replace(`https://registry.npmjs.org/`, config.base);\n downloadTarball?.({ link });\n },\n [config, downloadTarball]\n );\n\n const renderVersionInfo = (): React.ReactNode =>\n version && (\n <OverviewItem>\n <StyledVersion />\n {t('package.version', { version })}\n </OverviewItem>\n );\n\n const renderAuthorInfo = (): React.ReactNode => {\n const name = utils.getAuthorName(authorName);\n return (\n <OverviewItem>\n <Author>\n <Avatar alt={name} src={authorAvatar} />\n <Details>{name}</Details>\n </Author>\n </OverviewItem>\n );\n };\n\n const renderFileSize = (): React.ReactNode =>\n dist?.unpackedSize && (\n <OverviewItem>\n <StyledFileBinary />\n {utils.fileSizeSI(dist.unpackedSize)}\n </OverviewItem>\n );\n\n const renderLicenseInfo = (): React.ReactNode =>\n license && (\n <OverviewItem>\n <StyledLaw />\n {license as string}\n </OverviewItem>\n );\n\n const renderPublishedInfo = (): React.ReactNode =>\n time && (\n <OverviewItem>\n <StyledTime />\n <Published title={utils.formatDate(time)}>\n {t('package.published-on', { time: utils.formatDateDistance(time) })}\n </Published>\n </OverviewItem>\n );\n\n const renderHomePageLink = (): React.ReactNode =>\n homepage &&\n url.isURL(homepage) && (\n <LinkExternal to={homepage}>\n <Tooltip aria-label={t('package.homepage')} title={t('package.visit-home-page')}>\n <IconButton aria-label={t('package.homepage')} color=\"primary\" size=\"large\">\n <HomeIcon />\n </IconButton>\n </Tooltip>\n </LinkExternal>\n );\n\n const renderBugsLink = (): React.ReactNode =>\n bugs?.url &&\n url.isURL(bugs.url) && (\n <LinkExternal to={bugs.url}>\n <Tooltip aria-label={t('package.bugs')} title={t('package.open-an-issue')}>\n <IconButton aria-label={t('package.bugs')} color=\"primary\" size=\"large\">\n <BugReport />\n </IconButton>\n </Tooltip>\n </LinkExternal>\n );\n\n const renderDownloadLink = (): React.ReactNode =>\n dist?.tarball &&\n url.isURL(dist.tarball) && (\n <Link\n onClick={() => {\n handleDownload(dist.tarball);\n }}\n to=\"#\"\n >\n <Tooltip\n aria-label={t('package.download', { what: t('package.the-tar-file') })}\n title={t('package.tarball')}\n >\n <IconButton\n aria-label={t('package.download')}\n color=\"primary\"\n data-testid=\"download-tarball\"\n size=\"large\"\n >\n {isLoading ? <CircularProgress size={13} /> : <DownloadIcon />}\n </IconButton>\n </Tooltip>\n </Link>\n );\n\n const renderPrimaryComponent = (): React.ReactNode => {\n return (\n <Grid alignItems=\"center\" container={true} size={{ xs: 12 }} wrap=\"wrap\">\n <Grid size=\"grow\">\n <WrapperLink to={`${Route.DETAIL}${packageName}`}>\n <PackageTitle className=\"package-title\" data-testid=\"package-title\">\n {packageName}\n </PackageTitle>\n </WrapperLink>\n </Grid>\n <GridRightAligned size=\"auto\">\n {renderHomePageLink()}\n {renderBugsLink()}\n {showDownload && renderDownloadLink()}\n </GridRightAligned>\n </Grid>\n );\n };\n\n const renderSecondaryComponent = (): React.ReactNode => <Description>{description}</Description>;\n\n const renderPackageListItemText = (): React.ReactNode => (\n <PackageListItemText\n primary={renderPrimaryComponent()}\n secondary={renderSecondaryComponent()}\n />\n );\n\n const renderKeywords = (): React.ReactNode => (\n <ListItem alignItems={'flex-start'} sx={{ py: 0, my: 0 }}>\n <List sx={{ p: 0, my: 0 }}>\n <KeywordListItems keywords={keywords} />\n </List>\n </ListItem>\n );\n\n return (\n <Wrapper className={'package'} data-testid=\"package-item-list\">\n <ListItem alignItems={'flex-start'} sx={{ mb: 0 }}>\n {renderPackageListItemText()}\n </ListItem>\n {keywords && keywords?.length > 0 ? renderKeywords() : null}\n <ListItem alignItems={'flex-start'} sx={{ mt: 0 }}>\n {renderAuthorInfo()}\n {renderVersionInfo()}\n {renderPublishedInfo()}\n {renderFileSize()}\n {renderLicenseInfo()}\n </ListItem>\n </Wrapper>\n );\n};\n\nexport default Package;\n\nconst iconStyle = ({ theme }: { theme: Theme }) => css`\n margin: 0 10px 0 0;\n fill: ${theme.palette.mode === 'light' ? grey[900] : common.white};\n`;\n\nconst StyledVersion = styled(Version)`\n ${iconStyle};\n`;\n\nconst StyledFileBinary = styled(FileBinary)`\n ${iconStyle};\n`;\n\nconst StyledLaw = styled(Law)`\n ${iconStyle};\n`;\n\nconst StyledTime = styled(Time)`\n ${iconStyle};\n`;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Package.mjs","names":[],"sources":["../../../src/components/Package/Package.tsx"],"sourcesContent":["import { css } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport BugReport from '@mui/icons-material/BugReport';\nimport DownloadIcon from '@mui/icons-material/CloudDownload';\nimport HomeIcon from '@mui/icons-material/Home';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport Grid from '@mui/material/Grid';\nimport List from '@mui/material/List';\nimport ListItem from '@mui/material/ListItem';\nimport Tooltip from '@mui/material/Tooltip';\nimport { common, grey } from '@mui/material/colors';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport type { Theme } from '../../';\nimport { Link, LinkExternal, useDownload, useManifests } from '../../';\nimport { FileBinary, Law, Time, Version } from '../../components/Icons';\nimport { getConfiguration } from '../../configuration';\nimport type { Author as PackageAuthor } from '../../providers/ManifestsProvider/ManifestsProvider';\nimport type { PackageMetaInterface } from '../../types/packageMeta';\nimport { Route, url, utils } from '../../utils';\nimport KeywordListItems from '../Keywords/KeywordListItems';\nimport {\n Author,\n Avatar,\n Description,\n Details,\n GridRightAligned,\n IconButton,\n OverviewItem,\n PackageListItemText,\n PackageTitle,\n Published,\n Wrapper,\n WrapperLink,\n} from './styles';\n\ninterface Bugs {\n url: string;\n}\n\ninterface Dist {\n unpackedSize: number;\n tarball: string;\n}\n\nexport interface PackageInterface {\n name: string;\n version: string;\n time?: number | string;\n author: PackageAuthor;\n description?: string;\n keywords?: PackageMetaInterface['latest']['keywords'];\n license?: PackageMetaInterface['latest']['license'];\n homepage?: string;\n bugs?: Bugs;\n dist?: Dist;\n showDownload?: boolean;\n}\n\nconst Package: React.FC<PackageInterface> = ({\n author: { name: authorName, avatar: authorAvatar },\n bugs,\n description,\n dist,\n homepage,\n keywords,\n license,\n name: packageName,\n time,\n showDownload = true,\n version,\n}) => {\n const config = getConfiguration();\n const { t } = useTranslation();\n const { isLoading } = useManifests();\n const { downloadTarball } = useDownload();\n\n const handleDownload = useCallback(\n async (tarballDist: string) => {\n // FIXME: check, the dist might be different thant npmjs\n const link = tarballDist.replace(`https://registry.npmjs.org/`, config.base);\n downloadTarball?.({ link });\n },\n [config, downloadTarball]\n );\n\n const renderVersionInfo = (): React.ReactNode =>\n version && (\n <OverviewItem>\n <StyledVersion />\n {t('package.version', { version })}\n </OverviewItem>\n );\n\n const renderAuthorInfo = (): React.ReactNode => {\n const name = utils.getAuthorName(authorName);\n return (\n <OverviewItem>\n <Author>\n <Avatar alt={name} src={authorAvatar} />\n <Details>{name}</Details>\n </Author>\n </OverviewItem>\n );\n };\n\n const renderFileSize = (): React.ReactNode =>\n dist?.unpackedSize && (\n <OverviewItem>\n <StyledFileBinary />\n {utils.fileSizeSI(dist.unpackedSize)}\n </OverviewItem>\n );\n\n const renderLicenseInfo = (): React.ReactNode =>\n license && (\n <OverviewItem>\n <StyledLaw />\n {license as string}\n </OverviewItem>\n );\n\n const renderPublishedInfo = (): React.ReactNode =>\n time && (\n <OverviewItem>\n <StyledTime />\n <Published title={utils.formatDate(time)}>\n {t('package.published-on', { time: utils.formatDateDistance(time) })}\n </Published>\n </OverviewItem>\n );\n\n const renderHomePageLink = (): React.ReactNode =>\n homepage &&\n url.isURL(homepage) && (\n <LinkExternal to={homepage}>\n <Tooltip aria-label={t('package.homepage')} title={t('package.visit-home-page')}>\n <IconButton aria-label={t('package.homepage')} color=\"primary\" size=\"large\">\n <HomeIcon />\n </IconButton>\n </Tooltip>\n </LinkExternal>\n );\n\n const renderBugsLink = (): React.ReactNode =>\n bugs?.url &&\n url.isURL(bugs.url) && (\n <LinkExternal to={bugs.url}>\n <Tooltip aria-label={t('package.bugs')} title={t('package.open-an-issue')}>\n <IconButton aria-label={t('package.bugs')} color=\"primary\" size=\"large\">\n <BugReport />\n </IconButton>\n </Tooltip>\n </LinkExternal>\n );\n\n const renderDownloadLink = (): React.ReactNode =>\n dist?.tarball &&\n url.isURL(dist.tarball) && (\n <Link\n onClick={() => {\n handleDownload(dist.tarball);\n }}\n to=\"#\"\n >\n <Tooltip\n aria-label={t('package.download', { what: t('package.the-tar-file') })}\n title={t('package.tarball')}\n >\n <IconButton\n aria-label={t('package.download')}\n color=\"primary\"\n data-testid=\"download-tarball\"\n size=\"large\"\n >\n {isLoading ? <CircularProgress size={13} /> : <DownloadIcon />}\n </IconButton>\n </Tooltip>\n </Link>\n );\n\n const renderPrimaryComponent = (): React.ReactNode => {\n return (\n <Grid alignItems=\"center\" container={true} size={{ xs: 12 }} wrap=\"wrap\">\n <Grid size=\"grow\">\n <WrapperLink to={`${Route.DETAIL}${packageName}`}>\n <PackageTitle className=\"package-title\" data-testid=\"package-title\">\n {packageName}\n </PackageTitle>\n </WrapperLink>\n </Grid>\n <GridRightAligned size=\"auto\">\n {renderHomePageLink()}\n {renderBugsLink()}\n {showDownload && renderDownloadLink()}\n </GridRightAligned>\n </Grid>\n );\n };\n\n const renderSecondaryComponent = (): React.ReactNode => <Description>{description}</Description>;\n\n const renderPackageListItemText = (): React.ReactNode => (\n <PackageListItemText\n primary={renderPrimaryComponent()}\n secondary={renderSecondaryComponent()}\n />\n );\n\n const renderKeywords = (): React.ReactNode => (\n <ListItem alignItems={'flex-start'} sx={{ py: 0, my: 0 }}>\n <List sx={{ p: 0, my: 0 }}>\n <KeywordListItems keywords={keywords} />\n </List>\n </ListItem>\n );\n\n return (\n <Wrapper className={'package'} data-testid=\"package-item-list\">\n <ListItem alignItems={'flex-start'} sx={{ mb: 0 }}>\n {renderPackageListItemText()}\n </ListItem>\n {keywords && keywords?.length > 0 ? renderKeywords() : null}\n <ListItem alignItems={'flex-start'} sx={{ mt: 0 }}>\n {renderAuthorInfo()}\n {renderVersionInfo()}\n {renderPublishedInfo()}\n {renderFileSize()}\n {renderLicenseInfo()}\n </ListItem>\n </Wrapper>\n );\n};\n\nexport default Package;\n\nconst iconStyle = ({ theme }: { theme: Theme }) => css`\n margin: 0 10px 0 0;\n fill: ${theme.palette.mode === 'light' ? grey[900] : common.white};\n`;\n\nconst StyledVersion = styled(Version)`\n ${iconStyle};\n`;\n\nconst StyledFileBinary = styled(FileBinary)`\n ${iconStyle};\n`;\n\nconst StyledLaw = styled(Law)`\n ${iconStyle};\n`;\n\nconst StyledTime = styled(Time)`\n ${iconStyle};\n`;\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
|
|
2
2
|
const require_routes = require("../../utils/routes.js");
|
|
3
3
|
require("../../utils/index.js");
|
|
4
|
-
const require_AppConfigurationProvider = require("../../providers/AppConfigurationProvider/AppConfigurationProvider.js");
|
|
5
4
|
const require_SearchProvider = require("../../providers/SearchProvider/SearchProvider.js");
|
|
6
5
|
const require_AutoComplete = require("./AutoComplete/AutoComplete.js");
|
|
7
6
|
require("./AutoComplete/index.js");
|
|
7
|
+
const require_utils = require("./utils.js");
|
|
8
8
|
const require_SearchItem = require("./SearchItem.js");
|
|
9
9
|
const require_styles = require("./styles.js");
|
|
10
10
|
require("../../index.js");
|
|
@@ -25,8 +25,6 @@ var Search = () => {
|
|
|
25
25
|
const { t } = (0, react_i18next.useTranslation)();
|
|
26
26
|
const navigate = (0, react_router.useNavigate)();
|
|
27
27
|
const { searchResults, isLoading, doSearch } = require_SearchProvider.useSearch();
|
|
28
|
-
const { configOptions: { flags } } = require_AppConfigurationProvider.useConfig();
|
|
29
|
-
const searchRemote = flags?.searchRemote ?? false;
|
|
30
28
|
const abortControllerRef = (0, react.useRef)(null);
|
|
31
29
|
const cancelAllSearchRequests = (0, react.useCallback)(() => {
|
|
32
30
|
if (abortControllerRef.current) {
|
|
@@ -41,10 +39,10 @@ var Search = () => {
|
|
|
41
39
|
const handleClickSearch = (0, react.useCallback)((event, value, reason) => {
|
|
42
40
|
event.stopPropagation();
|
|
43
41
|
if (reason === "selectOption") {
|
|
44
|
-
const
|
|
45
|
-
navigate(`${require_routes.Route.DETAIL}${
|
|
42
|
+
const { name } = require_utils.normalizeSearchOption(value);
|
|
43
|
+
if (name) navigate(`${require_routes.Route.DETAIL}${name}`);
|
|
46
44
|
}
|
|
47
|
-
}, [navigate
|
|
45
|
+
}, [navigate]);
|
|
48
46
|
const doSearchRef = (0, react.useRef)(doSearch);
|
|
49
47
|
doSearchRef.current = doSearch;
|
|
50
48
|
/**
|
|
@@ -76,29 +74,16 @@ var Search = () => {
|
|
|
76
74
|
}, [debouncedFetch, cancelAllSearchRequests]);
|
|
77
75
|
const renderOption = (props, option) => {
|
|
78
76
|
const { key, ...otherProps } = props;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
isRemote,
|
|
90
|
-
name: item?.name,
|
|
91
|
-
version: item?.version
|
|
92
|
-
}, key);
|
|
93
|
-
} else {
|
|
94
|
-
const item = option.package;
|
|
95
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SearchItem.default, {
|
|
96
|
-
...otherProps,
|
|
97
|
-
description: item?.description,
|
|
98
|
-
name: item?.name,
|
|
99
|
-
version: item?.version
|
|
100
|
-
}, key);
|
|
101
|
-
}
|
|
77
|
+
const { name, version, description, isPrivate, isCached, isRemote } = require_utils.normalizeSearchOption(option);
|
|
78
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_SearchItem.default, {
|
|
79
|
+
...otherProps,
|
|
80
|
+
description,
|
|
81
|
+
isCached,
|
|
82
|
+
isPrivate,
|
|
83
|
+
isRemote,
|
|
84
|
+
name,
|
|
85
|
+
version
|
|
86
|
+
}, key);
|
|
102
87
|
};
|
|
103
88
|
const renderInput = (params) => {
|
|
104
89
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles.StyledTextField, {
|
|
@@ -116,7 +101,7 @@ var Search = () => {
|
|
|
116
101
|
});
|
|
117
102
|
};
|
|
118
103
|
const getOptionLabel = (option) => {
|
|
119
|
-
return option
|
|
104
|
+
return require_utils.normalizeSearchOption(option).name;
|
|
120
105
|
};
|
|
121
106
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AutoComplete.default, {
|
|
122
107
|
getOptionLabel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Search.js","names":[],"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["import SearchMui from '@mui/icons-material/Search';\nimport { debounce } from 'lodash-es';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport
|
|
1
|
+
{"version":3,"file":"Search.js","names":[],"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["import SearchMui from '@mui/icons-material/Search';\nimport { debounce } from 'lodash-es';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport { useSearch } from '../../';\nimport { Route } from '../../utils';\nimport AutoComplete from './AutoComplete';\nimport SearchItem from './SearchItem';\nimport { StyledInputAdornment, StyledTextField } from './styles';\nimport { normalizeSearchOption } from './utils';\n\nconst CONSTANTS = {\n API_DELAY: 300,\n ABORT_ERROR: 'AbortError',\n};\n\nconst Search: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { searchResults, isLoading, doSearch } = useSearch();\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const cancelAllSearchRequests = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const handleOnBlur = useCallback(\n (event: React.SyntheticEvent) => {\n event.stopPropagation();\n cancelAllSearchRequests();\n },\n [cancelAllSearchRequests]\n );\n\n const handleClickSearch = useCallback(\n (event: React.SyntheticEvent, value: any, reason: string): void => {\n event.stopPropagation();\n if (reason === 'selectOption') {\n const { name } = normalizeSearchOption(value);\n if (name) {\n navigate(`${Route.DETAIL}${name}`);\n }\n }\n },\n [navigate]\n );\n\n // Use a ref to always access the latest doSearch without re-creating the debounced function\n const doSearchRef = useRef(doSearch);\n doSearchRef.current = doSearch;\n\n /**\n * Stable fetch function that reads the latest doSearch from a ref,\n * avoiding dependency changes that would break the debounce.\n */\n const handleFetchPackages = useCallback(\n async ({ value }: { value: string }) => {\n if (value?.trim() !== '') {\n // Abort any previous pending request before starting a new one\n cancelAllSearchRequests();\n\n // Create a new controller for the current request\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n try {\n await doSearchRef.current?.({\n text: value,\n signal: controller.signal,\n });\n } catch (err: any) {\n if (err.name === CONSTANTS.ABORT_ERROR) {\n console.warn('Search request aborted');\n } else {\n console.error('Search error:', err);\n }\n }\n }\n },\n [cancelAllSearchRequests]\n );\n\n // Memoize the debounced function so a single instance is reused across renders,\n // ensuring the debounce timer works correctly instead of creating a new timer per render.\n const debouncedFetch = useMemo(\n () => debounce(handleFetchPackages, CONSTANTS.API_DELAY),\n [handleFetchPackages]\n );\n\n useEffect(() => {\n return () => {\n debouncedFetch.cancel?.();\n cancelAllSearchRequests();\n };\n }, [debouncedFetch, cancelAllSearchRequests]);\n\n const renderOption = (props, option) => {\n const { key, ...otherProps } = props;\n const { name, version, description, isPrivate, isCached, isRemote } =\n normalizeSearchOption(option);\n return (\n <SearchItem\n key={key}\n {...otherProps}\n description={description}\n isCached={isCached}\n isPrivate={isPrivate}\n isRemote={isRemote}\n name={name}\n version={version}\n />\n );\n };\n\n const renderInput = (params) => {\n return (\n <StyledTextField\n {...params}\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <StyledInputAdornment position=\"start\">\n <SearchMui />\n </StyledInputAdornment>\n ),\n }}\n label=\"\"\n placeholder={t('search.packages')}\n variant=\"standard\"\n />\n );\n };\n\n const getOptionLabel = (option) => {\n return normalizeSearchOption(option).name;\n };\n\n return (\n <AutoComplete\n getOptionLabel={getOptionLabel}\n onCleanSuggestions={handleOnBlur}\n onSelectItem={handleClickSearch}\n onSuggestionsFetch={debouncedFetch}\n placeholder={t('search.packages')}\n renderInput={renderInput}\n renderOption={renderOption}\n suggestions={searchResults}\n suggestionsLoading={isLoading}\n />\n );\n};\n\nexport default Search;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAaA,IAAM,YAAY;CAChB,WAAW;CACX,aAAa;CACd;AAED,IAAM,eAAyB;CAC7B,MAAM,EAAE,OAAA,GAAA,cAAA,iBAAsB;CAC9B,MAAM,YAAA,GAAA,aAAA,cAAwB;CAC9B,MAAM,EAAE,eAAe,WAAW,aAAa,uBAAA,WAAW;CAE1D,MAAM,sBAAA,GAAA,MAAA,QAAoD,KAAK;CAE/D,MAAM,2BAAA,GAAA,MAAA,mBAA4C;AAChD,MAAI,mBAAmB,SAAS;AAC9B,sBAAmB,QAAQ,OAAO;AAClC,sBAAmB,UAAU;;IAE9B,EAAE,CAAC;CAEN,MAAM,gBAAA,GAAA,MAAA,cACH,UAAgC;AAC/B,QAAM,iBAAiB;AACvB,2BAAyB;IAE3B,CAAC,wBAAwB,CAC1B;CAED,MAAM,qBAAA,GAAA,MAAA,cACH,OAA6B,OAAY,WAAyB;AACjE,QAAM,iBAAiB;AACvB,MAAI,WAAW,gBAAgB;GAC7B,MAAM,EAAE,SAAS,cAAA,sBAAsB,MAAM;AAC7C,OAAI,KACF,UAAS,GAAG,eAAA,MAAM,SAAS,OAAO;;IAIxC,CAAC,SAAS,CACX;CAGD,MAAM,eAAA,GAAA,MAAA,QAAqB,SAAS;AACpC,aAAY,UAAU;;;;;CAMtB,MAAM,uBAAA,GAAA,MAAA,aACJ,OAAO,EAAE,YAA+B;AACtC,MAAI,OAAO,MAAM,KAAK,IAAI;AAExB,4BAAyB;GAGzB,MAAM,aAAa,IAAI,iBAAiB;AACxC,sBAAmB,UAAU;AAE7B,OAAI;AACF,UAAM,YAAY,UAAU;KAC1B,MAAM;KACN,QAAQ,WAAW;KACpB,CAAC;YACK,KAAU;AACjB,QAAI,IAAI,SAAS,UAAU,YACzB,SAAQ,KAAK,yBAAyB;QAEtC,SAAQ,MAAM,iBAAiB,IAAI;;;IAK3C,CAAC,wBAAwB,CAC1B;CAID,MAAM,kBAAA,GAAA,MAAA,gBAAA,GAAA,UAAA,UACW,qBAAqB,UAAU,UAAU,EACxD,CAAC,oBAAoB,CACtB;AAED,EAAA,GAAA,MAAA,iBAAgB;AACd,eAAa;AACX,kBAAe,UAAU;AACzB,4BAAyB;;IAE1B,CAAC,gBAAgB,wBAAwB,CAAC;CAE7C,MAAM,gBAAgB,OAAO,WAAW;EACtC,MAAM,EAAE,KAAK,GAAG,eAAe;EAC/B,MAAM,EAAE,MAAM,SAAS,aAAa,WAAW,UAAU,aACvD,cAAA,sBAAsB,OAAO;AAC/B,SACE,iBAAA,GAAA,kBAAA,KAAC,mBAAA,SAAD;GAEE,GAAI;GACS;GACH;GACC;GACD;GACJ;GACG;GACT,EARK,IAQL;;CAIN,MAAM,eAAe,WAAW;AAC9B,SACE,iBAAA,GAAA,kBAAA,KAAC,eAAA,iBAAD;GACE,GAAI;GACJ,YAAY;IACV,GAAG,OAAO;IACV,gBACE,iBAAA,GAAA,kBAAA,KAAC,eAAA,sBAAD;KAAsB,UAAS;eAC7B,iBAAA,GAAA,kBAAA,KAAC,2BAAA,SAAD,EAAa,CAAA;KACQ,CAAA;IAE1B;GACD,OAAM;GACN,aAAa,EAAE,kBAAkB;GACjC,SAAQ;GACR,CAAA;;CAIN,MAAM,kBAAkB,WAAW;AACjC,SAAO,cAAA,sBAAsB,OAAO,CAAC;;AAGvC,QACE,iBAAA,GAAA,kBAAA,KAAC,qBAAA,SAAD;EACkB;EAChB,oBAAoB;EACpB,cAAc;EACd,oBAAoB;EACpB,aAAa,EAAE,kBAAkB;EACpB;EACC;EACd,aAAa;EACb,oBAAoB;EACpB,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Route as Route$1 } from "../../utils/routes.mjs";
|
|
2
2
|
import "../../utils/index.mjs";
|
|
3
|
-
import { useConfig } from "../../providers/AppConfigurationProvider/AppConfigurationProvider.mjs";
|
|
4
3
|
import { useSearch } from "../../providers/SearchProvider/SearchProvider.mjs";
|
|
5
4
|
import AutoComplete from "./AutoComplete/AutoComplete.mjs";
|
|
6
5
|
import "./AutoComplete/index.mjs";
|
|
6
|
+
import { normalizeSearchOption } from "./utils.mjs";
|
|
7
7
|
import SearchItem from "./SearchItem.mjs";
|
|
8
8
|
import { StyledInputAdornment, StyledTextField } from "./styles.mjs";
|
|
9
9
|
import "../../index.mjs";
|
|
@@ -22,8 +22,6 @@ var Search = () => {
|
|
|
22
22
|
const { t } = useTranslation();
|
|
23
23
|
const navigate = useNavigate();
|
|
24
24
|
const { searchResults, isLoading, doSearch } = useSearch();
|
|
25
|
-
const { configOptions: { flags } } = useConfig();
|
|
26
|
-
const searchRemote = flags?.searchRemote ?? false;
|
|
27
25
|
const abortControllerRef = useRef(null);
|
|
28
26
|
const cancelAllSearchRequests = useCallback(() => {
|
|
29
27
|
if (abortControllerRef.current) {
|
|
@@ -38,10 +36,10 @@ var Search = () => {
|
|
|
38
36
|
const handleClickSearch = useCallback((event, value, reason) => {
|
|
39
37
|
event.stopPropagation();
|
|
40
38
|
if (reason === "selectOption") {
|
|
41
|
-
const
|
|
42
|
-
navigate(`${Route$1.DETAIL}${
|
|
39
|
+
const { name } = normalizeSearchOption(value);
|
|
40
|
+
if (name) navigate(`${Route$1.DETAIL}${name}`);
|
|
43
41
|
}
|
|
44
|
-
}, [navigate
|
|
42
|
+
}, [navigate]);
|
|
45
43
|
const doSearchRef = useRef(doSearch);
|
|
46
44
|
doSearchRef.current = doSearch;
|
|
47
45
|
/**
|
|
@@ -73,29 +71,16 @@ var Search = () => {
|
|
|
73
71
|
}, [debouncedFetch, cancelAllSearchRequests]);
|
|
74
72
|
const renderOption = (props, option) => {
|
|
75
73
|
const { key, ...otherProps } = props;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
isRemote,
|
|
87
|
-
name: item?.name,
|
|
88
|
-
version: item?.version
|
|
89
|
-
}, key);
|
|
90
|
-
} else {
|
|
91
|
-
const item = option.package;
|
|
92
|
-
return /* @__PURE__ */ jsx(SearchItem, {
|
|
93
|
-
...otherProps,
|
|
94
|
-
description: item?.description,
|
|
95
|
-
name: item?.name,
|
|
96
|
-
version: item?.version
|
|
97
|
-
}, key);
|
|
98
|
-
}
|
|
74
|
+
const { name, version, description, isPrivate, isCached, isRemote } = normalizeSearchOption(option);
|
|
75
|
+
return /* @__PURE__ */ jsx(SearchItem, {
|
|
76
|
+
...otherProps,
|
|
77
|
+
description,
|
|
78
|
+
isCached,
|
|
79
|
+
isPrivate,
|
|
80
|
+
isRemote,
|
|
81
|
+
name,
|
|
82
|
+
version
|
|
83
|
+
}, key);
|
|
99
84
|
};
|
|
100
85
|
const renderInput = (params) => {
|
|
101
86
|
return /* @__PURE__ */ jsx(StyledTextField, {
|
|
@@ -113,7 +98,7 @@ var Search = () => {
|
|
|
113
98
|
});
|
|
114
99
|
};
|
|
115
100
|
const getOptionLabel = (option) => {
|
|
116
|
-
return option
|
|
101
|
+
return normalizeSearchOption(option).name;
|
|
117
102
|
};
|
|
118
103
|
return /* @__PURE__ */ jsx(AutoComplete, {
|
|
119
104
|
getOptionLabel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Search.mjs","names":[],"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["import SearchMui from '@mui/icons-material/Search';\nimport { debounce } from 'lodash-es';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport
|
|
1
|
+
{"version":3,"file":"Search.mjs","names":[],"sources":["../../../src/components/Search/Search.tsx"],"sourcesContent":["import SearchMui from '@mui/icons-material/Search';\nimport { debounce } from 'lodash-es';\nimport React, { useCallback, useEffect, useMemo, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport { useSearch } from '../../';\nimport { Route } from '../../utils';\nimport AutoComplete from './AutoComplete';\nimport SearchItem from './SearchItem';\nimport { StyledInputAdornment, StyledTextField } from './styles';\nimport { normalizeSearchOption } from './utils';\n\nconst CONSTANTS = {\n API_DELAY: 300,\n ABORT_ERROR: 'AbortError',\n};\n\nconst Search: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { searchResults, isLoading, doSearch } = useSearch();\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const cancelAllSearchRequests = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const handleOnBlur = useCallback(\n (event: React.SyntheticEvent) => {\n event.stopPropagation();\n cancelAllSearchRequests();\n },\n [cancelAllSearchRequests]\n );\n\n const handleClickSearch = useCallback(\n (event: React.SyntheticEvent, value: any, reason: string): void => {\n event.stopPropagation();\n if (reason === 'selectOption') {\n const { name } = normalizeSearchOption(value);\n if (name) {\n navigate(`${Route.DETAIL}${name}`);\n }\n }\n },\n [navigate]\n );\n\n // Use a ref to always access the latest doSearch without re-creating the debounced function\n const doSearchRef = useRef(doSearch);\n doSearchRef.current = doSearch;\n\n /**\n * Stable fetch function that reads the latest doSearch from a ref,\n * avoiding dependency changes that would break the debounce.\n */\n const handleFetchPackages = useCallback(\n async ({ value }: { value: string }) => {\n if (value?.trim() !== '') {\n // Abort any previous pending request before starting a new one\n cancelAllSearchRequests();\n\n // Create a new controller for the current request\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n try {\n await doSearchRef.current?.({\n text: value,\n signal: controller.signal,\n });\n } catch (err: any) {\n if (err.name === CONSTANTS.ABORT_ERROR) {\n console.warn('Search request aborted');\n } else {\n console.error('Search error:', err);\n }\n }\n }\n },\n [cancelAllSearchRequests]\n );\n\n // Memoize the debounced function so a single instance is reused across renders,\n // ensuring the debounce timer works correctly instead of creating a new timer per render.\n const debouncedFetch = useMemo(\n () => debounce(handleFetchPackages, CONSTANTS.API_DELAY),\n [handleFetchPackages]\n );\n\n useEffect(() => {\n return () => {\n debouncedFetch.cancel?.();\n cancelAllSearchRequests();\n };\n }, [debouncedFetch, cancelAllSearchRequests]);\n\n const renderOption = (props, option) => {\n const { key, ...otherProps } = props;\n const { name, version, description, isPrivate, isCached, isRemote } =\n normalizeSearchOption(option);\n return (\n <SearchItem\n key={key}\n {...otherProps}\n description={description}\n isCached={isCached}\n isPrivate={isPrivate}\n isRemote={isRemote}\n name={name}\n version={version}\n />\n );\n };\n\n const renderInput = (params) => {\n return (\n <StyledTextField\n {...params}\n InputProps={{\n ...params.InputProps,\n startAdornment: (\n <StyledInputAdornment position=\"start\">\n <SearchMui />\n </StyledInputAdornment>\n ),\n }}\n label=\"\"\n placeholder={t('search.packages')}\n variant=\"standard\"\n />\n );\n };\n\n const getOptionLabel = (option) => {\n return normalizeSearchOption(option).name;\n };\n\n return (\n <AutoComplete\n getOptionLabel={getOptionLabel}\n onCleanSuggestions={handleOnBlur}\n onSelectItem={handleClickSearch}\n onSuggestionsFetch={debouncedFetch}\n placeholder={t('search.packages')}\n renderInput={renderInput}\n renderOption={renderOption}\n suggestions={searchResults}\n suggestionsLoading={isLoading}\n />\n );\n};\n\nexport default Search;\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,IAAM,YAAY;CAChB,WAAW;CACX,aAAa;CACd;AAED,IAAM,eAAyB;CAC7B,MAAM,EAAE,MAAM,gBAAgB;CAC9B,MAAM,WAAW,aAAa;CAC9B,MAAM,EAAE,eAAe,WAAW,aAAa,WAAW;CAE1D,MAAM,qBAAqB,OAA+B,KAAK;CAE/D,MAAM,0BAA0B,kBAAkB;AAChD,MAAI,mBAAmB,SAAS;AAC9B,sBAAmB,QAAQ,OAAO;AAClC,sBAAmB,UAAU;;IAE9B,EAAE,CAAC;CAEN,MAAM,eAAe,aAClB,UAAgC;AAC/B,QAAM,iBAAiB;AACvB,2BAAyB;IAE3B,CAAC,wBAAwB,CAC1B;CAED,MAAM,oBAAoB,aACvB,OAA6B,OAAY,WAAyB;AACjE,QAAM,iBAAiB;AACvB,MAAI,WAAW,gBAAgB;GAC7B,MAAM,EAAE,SAAS,sBAAsB,MAAM;AAC7C,OAAI,KACF,UAAS,GAAG,QAAM,SAAS,OAAO;;IAIxC,CAAC,SAAS,CACX;CAGD,MAAM,cAAc,OAAO,SAAS;AACpC,aAAY,UAAU;;;;;CAMtB,MAAM,sBAAsB,YAC1B,OAAO,EAAE,YAA+B;AACtC,MAAI,OAAO,MAAM,KAAK,IAAI;AAExB,4BAAyB;GAGzB,MAAM,aAAa,IAAI,iBAAiB;AACxC,sBAAmB,UAAU;AAE7B,OAAI;AACF,UAAM,YAAY,UAAU;KAC1B,MAAM;KACN,QAAQ,WAAW;KACpB,CAAC;YACK,KAAU;AACjB,QAAI,IAAI,SAAS,UAAU,YACzB,SAAQ,KAAK,yBAAyB;QAEtC,SAAQ,MAAM,iBAAiB,IAAI;;;IAK3C,CAAC,wBAAwB,CAC1B;CAID,MAAM,iBAAiB,cACf,SAAS,qBAAqB,UAAU,UAAU,EACxD,CAAC,oBAAoB,CACtB;AAED,iBAAgB;AACd,eAAa;AACX,kBAAe,UAAU;AACzB,4BAAyB;;IAE1B,CAAC,gBAAgB,wBAAwB,CAAC;CAE7C,MAAM,gBAAgB,OAAO,WAAW;EACtC,MAAM,EAAE,KAAK,GAAG,eAAe;EAC/B,MAAM,EAAE,MAAM,SAAS,aAAa,WAAW,UAAU,aACvD,sBAAsB,OAAO;AAC/B,SACE,oBAAC,YAAD;GAEE,GAAI;GACS;GACH;GACC;GACD;GACJ;GACG;GACT,EARK,IAQL;;CAIN,MAAM,eAAe,WAAW;AAC9B,SACE,oBAAC,iBAAD;GACE,GAAI;GACJ,YAAY;IACV,GAAG,OAAO;IACV,gBACE,oBAAC,sBAAD;KAAsB,UAAS;eAC7B,oBAAC,WAAD,EAAa,CAAA;KACQ,CAAA;IAE1B;GACD,OAAM;GACN,aAAa,EAAE,kBAAkB;GACjC,SAAQ;GACR,CAAA;;CAIN,MAAM,kBAAkB,WAAW;AACjC,SAAO,sBAAsB,OAAO,CAAC;;AAGvC,QACE,oBAAC,cAAD;EACkB;EAChB,oBAAoB;EACpB,cAAc;EACd,oBAAoB;EACpB,aAAa,EAAE,kBAAkB;EACpB;EACC;EACd,aAAa;EACb,oBAAoB;EACpB,CAAA"}
|
|
@@ -1 +1,22 @@
|
|
|
1
|
+
export type NormalizedSearchOption = {
|
|
2
|
+
name: string;
|
|
3
|
+
version?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
isPrivate: boolean;
|
|
6
|
+
isCached: boolean;
|
|
7
|
+
isRemote: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Normalize a raw search result into a unified shape the UI can render,
|
|
11
|
+
* regardless of which backend response format was returned:
|
|
12
|
+
*
|
|
13
|
+
* 1) npm-style "search objects" response where each entry is wrapped in
|
|
14
|
+
* `{ package: { name, version, description, ... }, verdaccioPrivate, verdaccioPkgCached }`.
|
|
15
|
+
* 2) Flat packument-style response where each entry exposes `name`, `version`,
|
|
16
|
+
* `description`, `dist`, etc. directly at the top level.
|
|
17
|
+
*
|
|
18
|
+
* The second shape carries no uplink metadata, so private/remote/cached flags
|
|
19
|
+
* default to `false` and the UI simply omits the corresponding badges.
|
|
20
|
+
*/
|
|
21
|
+
export declare function normalizeSearchOption(option: any): NormalizedSearchOption;
|
|
1
22
|
export declare function cleanDescription(description: string): string;
|
|
@@ -1,4 +1,40 @@
|
|
|
1
1
|
//#region src/components/Search/utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a raw search result into a unified shape the UI can render,
|
|
4
|
+
* regardless of which backend response format was returned:
|
|
5
|
+
*
|
|
6
|
+
* 1) npm-style "search objects" response where each entry is wrapped in
|
|
7
|
+
* `{ package: { name, version, description, ... }, verdaccioPrivate, verdaccioPkgCached }`.
|
|
8
|
+
* 2) Flat packument-style response where each entry exposes `name`, `version`,
|
|
9
|
+
* `description`, `dist`, etc. directly at the top level.
|
|
10
|
+
*
|
|
11
|
+
* The second shape carries no uplink metadata, so private/remote/cached flags
|
|
12
|
+
* default to `false` and the UI simply omits the corresponding badges.
|
|
13
|
+
*/
|
|
14
|
+
function normalizeSearchOption(option) {
|
|
15
|
+
if (option && typeof option === "object" && option.package) {
|
|
16
|
+
const pkg = option.package ?? {};
|
|
17
|
+
const isPrivate = Boolean(option.verdaccioPrivate);
|
|
18
|
+
const isCached = Boolean(option.verdaccioPkgCached);
|
|
19
|
+
return {
|
|
20
|
+
name: pkg.name,
|
|
21
|
+
version: pkg.version,
|
|
22
|
+
description: pkg.description,
|
|
23
|
+
isPrivate,
|
|
24
|
+
isCached,
|
|
25
|
+
isRemote: !isCached && !isPrivate
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const flat = option ?? {};
|
|
29
|
+
return {
|
|
30
|
+
name: flat.name,
|
|
31
|
+
version: flat.version,
|
|
32
|
+
description: flat.description,
|
|
33
|
+
isPrivate: false,
|
|
34
|
+
isCached: false,
|
|
35
|
+
isRemote: false
|
|
36
|
+
};
|
|
37
|
+
}
|
|
2
38
|
function removeHtmlTags(input) {
|
|
3
39
|
let previous;
|
|
4
40
|
do {
|
|
@@ -15,5 +51,6 @@ function cleanDescription(description) {
|
|
|
15
51
|
}
|
|
16
52
|
//#endregion
|
|
17
53
|
exports.cleanDescription = cleanDescription;
|
|
54
|
+
exports.normalizeSearchOption = normalizeSearchOption;
|
|
18
55
|
|
|
19
56
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/Search/utils.ts"],"sourcesContent":["function removeHtmlTags(input: string): string {\n let previous;\n do {\n previous = input;\n input = input.replace(/<[^>]*>?/gm, '');\n } while (input !== previous);\n return input;\n}\n\nexport function cleanDescription(description: string): string {\n let output = description;\n // remove html tags from description (e.g. <h1...>)\n output = removeHtmlTags(output);\n // remove markdown links from description (e.g. [link](url))\n output = output.replace(/\\(.*?\\)/gm, '').replace(/(\\[!?|\\])/gm, '');\n return output;\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/components/Search/utils.ts"],"sourcesContent":["export type NormalizedSearchOption = {\n name: string;\n version?: string;\n description?: string;\n isPrivate: boolean;\n isCached: boolean;\n isRemote: boolean;\n};\n\n/**\n * Normalize a raw search result into a unified shape the UI can render,\n * regardless of which backend response format was returned:\n *\n * 1) npm-style \"search objects\" response where each entry is wrapped in\n * `{ package: { name, version, description, ... }, verdaccioPrivate, verdaccioPkgCached }`.\n * 2) Flat packument-style response where each entry exposes `name`, `version`,\n * `description`, `dist`, etc. directly at the top level.\n *\n * The second shape carries no uplink metadata, so private/remote/cached flags\n * default to `false` and the UI simply omits the corresponding badges.\n */\nexport function normalizeSearchOption(option: any): NormalizedSearchOption {\n if (option && typeof option === 'object' && option.package) {\n const pkg = option.package ?? {};\n const isPrivate = Boolean(option.verdaccioPrivate);\n const isCached = Boolean(option.verdaccioPkgCached);\n return {\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n isPrivate,\n isCached,\n isRemote: !isCached && !isPrivate,\n };\n }\n\n const flat = option ?? {};\n return {\n name: flat.name,\n version: flat.version,\n description: flat.description,\n isPrivate: false,\n isCached: false,\n isRemote: false,\n };\n}\n\nfunction removeHtmlTags(input: string): string {\n let previous;\n do {\n previous = input;\n input = input.replace(/<[^>]*>?/gm, '');\n } while (input !== previous);\n return input;\n}\n\nexport function cleanDescription(description: string): string {\n let output = description;\n // remove html tags from description (e.g. <h1...>)\n output = removeHtmlTags(output);\n // remove markdown links from description (e.g. [link](url))\n output = output.replace(/\\(.*?\\)/gm, '').replace(/(\\[!?|\\])/gm, '');\n return output;\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAgB,sBAAsB,QAAqC;AACzE,KAAI,UAAU,OAAO,WAAW,YAAY,OAAO,SAAS;EAC1D,MAAM,MAAM,OAAO,WAAW,EAAE;EAChC,MAAM,YAAY,QAAQ,OAAO,iBAAiB;EAClD,MAAM,WAAW,QAAQ,OAAO,mBAAmB;AACnD,SAAO;GACL,MAAM,IAAI;GACV,SAAS,IAAI;GACb,aAAa,IAAI;GACjB;GACA;GACA,UAAU,CAAC,YAAY,CAAC;GACzB;;CAGH,MAAM,OAAO,UAAU,EAAE;AACzB,QAAO;EACL,MAAM,KAAK;EACX,SAAS,KAAK;EACd,aAAa,KAAK;EAClB,WAAW;EACX,UAAU;EACV,UAAU;EACX;;AAGH,SAAS,eAAe,OAAuB;CAC7C,IAAI;AACJ,IAAG;AACD,aAAW;AACX,UAAQ,MAAM,QAAQ,cAAc,GAAG;UAChC,UAAU;AACnB,QAAO;;AAGT,SAAgB,iBAAiB,aAA6B;CAC5D,IAAI,SAAS;AAEb,UAAS,eAAe,OAAO;AAE/B,UAAS,OAAO,QAAQ,aAAa,GAAG,CAAC,QAAQ,eAAe,GAAG;AACnE,QAAO"}
|
|
@@ -1,4 +1,40 @@
|
|
|
1
1
|
//#region src/components/Search/utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a raw search result into a unified shape the UI can render,
|
|
4
|
+
* regardless of which backend response format was returned:
|
|
5
|
+
*
|
|
6
|
+
* 1) npm-style "search objects" response where each entry is wrapped in
|
|
7
|
+
* `{ package: { name, version, description, ... }, verdaccioPrivate, verdaccioPkgCached }`.
|
|
8
|
+
* 2) Flat packument-style response where each entry exposes `name`, `version`,
|
|
9
|
+
* `description`, `dist`, etc. directly at the top level.
|
|
10
|
+
*
|
|
11
|
+
* The second shape carries no uplink metadata, so private/remote/cached flags
|
|
12
|
+
* default to `false` and the UI simply omits the corresponding badges.
|
|
13
|
+
*/
|
|
14
|
+
function normalizeSearchOption(option) {
|
|
15
|
+
if (option && typeof option === "object" && option.package) {
|
|
16
|
+
const pkg = option.package ?? {};
|
|
17
|
+
const isPrivate = Boolean(option.verdaccioPrivate);
|
|
18
|
+
const isCached = Boolean(option.verdaccioPkgCached);
|
|
19
|
+
return {
|
|
20
|
+
name: pkg.name,
|
|
21
|
+
version: pkg.version,
|
|
22
|
+
description: pkg.description,
|
|
23
|
+
isPrivate,
|
|
24
|
+
isCached,
|
|
25
|
+
isRemote: !isCached && !isPrivate
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const flat = option ?? {};
|
|
29
|
+
return {
|
|
30
|
+
name: flat.name,
|
|
31
|
+
version: flat.version,
|
|
32
|
+
description: flat.description,
|
|
33
|
+
isPrivate: false,
|
|
34
|
+
isCached: false,
|
|
35
|
+
isRemote: false
|
|
36
|
+
};
|
|
37
|
+
}
|
|
2
38
|
function removeHtmlTags(input) {
|
|
3
39
|
let previous;
|
|
4
40
|
do {
|
|
@@ -14,6 +50,6 @@ function cleanDescription(description) {
|
|
|
14
50
|
return output;
|
|
15
51
|
}
|
|
16
52
|
//#endregion
|
|
17
|
-
export { cleanDescription };
|
|
53
|
+
export { cleanDescription, normalizeSearchOption };
|
|
18
54
|
|
|
19
55
|
//# sourceMappingURL=utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/components/Search/utils.ts"],"sourcesContent":["function removeHtmlTags(input: string): string {\n let previous;\n do {\n previous = input;\n input = input.replace(/<[^>]*>?/gm, '');\n } while (input !== previous);\n return input;\n}\n\nexport function cleanDescription(description: string): string {\n let output = description;\n // remove html tags from description (e.g. <h1...>)\n output = removeHtmlTags(output);\n // remove markdown links from description (e.g. [link](url))\n output = output.replace(/\\(.*?\\)/gm, '').replace(/(\\[!?|\\])/gm, '');\n return output;\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/components/Search/utils.ts"],"sourcesContent":["export type NormalizedSearchOption = {\n name: string;\n version?: string;\n description?: string;\n isPrivate: boolean;\n isCached: boolean;\n isRemote: boolean;\n};\n\n/**\n * Normalize a raw search result into a unified shape the UI can render,\n * regardless of which backend response format was returned:\n *\n * 1) npm-style \"search objects\" response where each entry is wrapped in\n * `{ package: { name, version, description, ... }, verdaccioPrivate, verdaccioPkgCached }`.\n * 2) Flat packument-style response where each entry exposes `name`, `version`,\n * `description`, `dist`, etc. directly at the top level.\n *\n * The second shape carries no uplink metadata, so private/remote/cached flags\n * default to `false` and the UI simply omits the corresponding badges.\n */\nexport function normalizeSearchOption(option: any): NormalizedSearchOption {\n if (option && typeof option === 'object' && option.package) {\n const pkg = option.package ?? {};\n const isPrivate = Boolean(option.verdaccioPrivate);\n const isCached = Boolean(option.verdaccioPkgCached);\n return {\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n isPrivate,\n isCached,\n isRemote: !isCached && !isPrivate,\n };\n }\n\n const flat = option ?? {};\n return {\n name: flat.name,\n version: flat.version,\n description: flat.description,\n isPrivate: false,\n isCached: false,\n isRemote: false,\n };\n}\n\nfunction removeHtmlTags(input: string): string {\n let previous;\n do {\n previous = input;\n input = input.replace(/<[^>]*>?/gm, '');\n } while (input !== previous);\n return input;\n}\n\nexport function cleanDescription(description: string): string {\n let output = description;\n // remove html tags from description (e.g. <h1...>)\n output = removeHtmlTags(output);\n // remove markdown links from description (e.g. [link](url))\n output = output.replace(/\\(.*?\\)/gm, '').replace(/(\\[!?|\\])/gm, '');\n return output;\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAgB,sBAAsB,QAAqC;AACzE,KAAI,UAAU,OAAO,WAAW,YAAY,OAAO,SAAS;EAC1D,MAAM,MAAM,OAAO,WAAW,EAAE;EAChC,MAAM,YAAY,QAAQ,OAAO,iBAAiB;EAClD,MAAM,WAAW,QAAQ,OAAO,mBAAmB;AACnD,SAAO;GACL,MAAM,IAAI;GACV,SAAS,IAAI;GACb,aAAa,IAAI;GACjB;GACA;GACA,UAAU,CAAC,YAAY,CAAC;GACzB;;CAGH,MAAM,OAAO,UAAU,EAAE;AACzB,QAAO;EACL,MAAM,KAAK;EACX,SAAS,KAAK;EACd,aAAa,KAAK;EAClB,WAAW;EACX,UAAU;EACV,UAAU;EACX;;AAGH,SAAS,eAAe,OAAuB;CAC7C,IAAI;AACJ,IAAG;AACD,aAAW;AACX,UAAQ,MAAM,QAAQ,cAAc,GAAG;UAChC,UAAU;AACnB,QAAO;;AAGT,SAAgB,iBAAiB,aAA6B;CAC5D,IAAI,SAAS;AAEb,UAAS,eAAe,OAAO;AAE/B,UAAS,OAAO,QAAQ,aAAa,GAAG,CAAC,QAAQ,eAAe,GAAG;AACnE,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/ui-components",
|
|
3
|
-
"version": "5.0.0-next-9.
|
|
3
|
+
"version": "5.0.0-next-9.8",
|
|
4
4
|
"description": "Verdaccio UI Components",
|
|
5
5
|
"author": "Juan Picado <juanpicado19@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@testing-library/react": "16.3.2",
|
|
62
62
|
"@types/lodash-es": "4.17.12",
|
|
63
63
|
"@types/node": "24.10.13",
|
|
64
|
-
"@verdaccio/types": "14.0.0-next-9.
|
|
64
|
+
"@verdaccio/types": "14.0.0-next-9.5",
|
|
65
65
|
"@vitejs/plugin-react": "6.0.1",
|
|
66
66
|
"eslint-plugin-storybook": "10.2.17",
|
|
67
67
|
"eslint-plugin-verdaccio": "10.0.0",
|