Merge branch 'main' into fix/clean-test-warnings

This commit is contained in:
Simone Taeggi 2022-10-18 10:24:07 +02:00
commit 1039e207c0
16 changed files with 342 additions and 124 deletions

View File

@ -110,6 +110,7 @@ testApp
license.txt
exports
*.cache
dist
build
documentation
.strapi-updater.json

View File

@ -110,5 +110,6 @@ coverage
license.txt
exports
*.cache
dist
build
.strapi-updater.json

View File

@ -110,5 +110,6 @@ coverage
license.txt
exports
*.cache
dist
build
.strapi-updater.json

View File

@ -62,6 +62,15 @@ async function initProject(projectName, program) {
await checkInstallPath(resolve(projectName));
}
const programFlags = program.options
.reduce((acc, { short, long }) => [...acc, short, long], [])
.filter(Boolean);
if (program.template && programFlags.includes(program.template)) {
console.error(`${program.template} is not a valid template`);
process.exit(1);
}
const hasDatabaseOptions = databaseOptions.some((opt) => program[opt]);
if (program.quickstart && hasDatabaseOptions) {

View File

@ -110,5 +110,6 @@ coverage
license.txt
exports
*.cache
dist
build
.strapi-updater.json

View File

@ -0,0 +1,110 @@
import React from 'react';
import semver from 'semver';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { Tooltip } from '@strapi/design-system/Tooltip';
import { Button } from '@strapi/design-system/Button';
import { Box } from '@strapi/design-system/Box';
import Duplicate from '@strapi/icons/Duplicate';
const TooltipButton = ({ description, installMessage, disabled, handleCopy, pluginName }) => (
<Tooltip data-testid={`tooltip-${pluginName}`} description={description}>
<Box>
<Button
size="S"
startIcon={<Duplicate />}
variant="secondary"
disabled={disabled}
onClick={handleCopy}
>
{installMessage}
</Button>
</Box>
</Tooltip>
);
const CardButton = ({ strapiPeerDepVersion, strapiAppVersion, handleCopy, pluginName }) => {
const { formatMessage } = useIntl();
const versionRange = semver.validRange(strapiPeerDepVersion);
const isCompatible = semver.satisfies(strapiAppVersion, versionRange);
const installMessage = formatMessage({
id: 'admin.pages.MarketPlacePage.plugin.copy',
defaultMessage: 'Copy install command',
});
// Only plugins receive a strapiAppVersion
if (strapiAppVersion) {
if (!versionRange) {
return (
<TooltipButton
installMessage={installMessage}
pluginName={pluginName}
description={formatMessage(
{
id: 'admin.pages.MarketPlacePage.plugin.version.null',
defaultMessage:
'Unable to verify compatibility with your Strapi version: "{strapiAppVersion}"',
},
{ strapiAppVersion }
)}
handleCopy={handleCopy}
/>
);
}
if (!isCompatible) {
return (
<TooltipButton
installMessage={installMessage}
pluginName={pluginName}
description={formatMessage(
{
id: 'admin.pages.MarketPlacePage.plugin.version',
defaultMessage:
'Update your Strapi version: "{strapiAppVersion}" to: "{versionRange}"',
},
{
strapiAppVersion,
versionRange,
}
)}
disabled
/>
);
}
}
return (
<Button size="S" startIcon={<Duplicate />} variant="secondary" onClick={handleCopy}>
{installMessage}
</Button>
);
};
TooltipButton.defaultProps = {
disabled: false,
handleCopy: null,
};
TooltipButton.propTypes = {
description: PropTypes.string.isRequired,
installMessage: PropTypes.string.isRequired,
disabled: PropTypes.bool,
handleCopy: PropTypes.func,
pluginName: PropTypes.string.isRequired,
};
CardButton.defaultProps = {
strapiAppVersion: null,
strapiPeerDepVersion: null,
};
CardButton.propTypes = {
strapiAppVersion: PropTypes.string,
strapiPeerDepVersion: PropTypes.string,
handleCopy: PropTypes.func.isRequired,
pluginName: PropTypes.string.isRequired,
};
export default CardButton;

View File

@ -1,20 +1,34 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { useNotification, useTracking } from '@strapi/helper-plugin';
import { Box } from '@strapi/design-system/Box';
import { Icon } from '@strapi/design-system/Icon';
import { Typography } from '@strapi/design-system/Typography';
import Check from '@strapi/icons/Check';
import Duplicate from '@strapi/icons/Duplicate';
import { Button } from '@strapi/design-system/Button';
import CardButton from './CardButton';
const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }) => {
const InstallPluginButton = ({
isInstalled,
isInDevelopmentMode,
commandToCopy,
strapiAppVersion,
strapiPeerDepVersion,
pluginName,
}) => {
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const { trackUsage } = useTracking();
const handleCopy = () => {
navigator.clipboard.writeText(commandToCopy);
trackUsage('willInstallPlugin');
toggleNotification({
type: 'success',
message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
});
};
// Already installed
if (isInstalled) {
return (
@ -33,23 +47,12 @@ const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }
// In development, show install button
if (isInDevelopmentMode) {
return (
<CopyToClipboard
onCopy={() => {
trackUsage('willInstallPlugin');
toggleNotification({
type: 'success',
message: { id: 'admin.pages.MarketPlacePage.plugin.copy.success' },
});
}}
text={commandToCopy}
>
<Button size="S" startIcon={<Duplicate />} variant="secondary">
{formatMessage({
id: 'admin.pages.MarketPlacePage.plugin.copy',
defaultMessage: 'Copy install command',
})}
</Button>
</CopyToClipboard>
<CardButton
strapiAppVersion={strapiAppVersion}
strapiPeerDepVersion={strapiPeerDepVersion}
handleCopy={handleCopy}
pluginName={pluginName}
/>
);
}
@ -57,10 +60,18 @@ const InstallPluginButton = ({ isInstalled, isInDevelopmentMode, commandToCopy }
return null;
};
InstallPluginButton.defaultProps = {
strapiAppVersion: null,
strapiPeerDepVersion: null,
};
InstallPluginButton.propTypes = {
isInstalled: PropTypes.bool.isRequired,
isInDevelopmentMode: PropTypes.bool.isRequired,
commandToCopy: PropTypes.string.isRequired,
strapiAppVersion: PropTypes.string,
strapiPeerDepVersion: PropTypes.string,
pluginName: PropTypes.string.isRequired,
};
export default InstallPluginButton;

View File

@ -32,6 +32,7 @@ const NpmPackageCard = ({
useYarn,
isInDevelopmentMode,
npmPackageType,
strapiAppVersion,
}) => {
const { attributes } = npmPackage;
const { formatMessage } = useIntl();
@ -139,6 +140,9 @@ const NpmPackageCard = ({
isInstalled={isInstalled}
isInDevelopmentMode={isInDevelopmentMode}
commandToCopy={commandToCopy}
strapiAppVersion={strapiAppVersion}
strapiPeerDepVersion={attributes.strapiVersion}
pluginName={attributes.name}
/>
</Stack>
</Flex>
@ -147,6 +151,7 @@ const NpmPackageCard = ({
NpmPackageCard.defaultProps = {
isInDevelopmentMode: false,
strapiAppVersion: null,
};
NpmPackageCard.propTypes = {
@ -164,12 +169,14 @@ NpmPackageCard.propTypes = {
validated: PropTypes.bool.isRequired,
madeByStrapi: PropTypes.bool.isRequired,
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']),
strapiVersion: PropTypes.string,
}).isRequired,
}).isRequired,
isInstalled: PropTypes.bool.isRequired,
useYarn: PropTypes.bool.isRequired,
isInDevelopmentMode: PropTypes.bool,
npmPackageType: PropTypes.string.isRequired,
strapiAppVersion: PropTypes.string,
};
export default NpmPackageCard;

View File

@ -9,6 +9,7 @@ const NpmPackagesGrid = ({
useYarn,
isInDevelopmentMode,
npmPackageType,
strapiAppVersion,
}) => {
// Check if an individual package is in the dependencies
const isAlreadyInstalled = useCallback(
@ -26,6 +27,7 @@ const NpmPackagesGrid = ({
useYarn={useYarn}
isInDevelopmentMode={isInDevelopmentMode}
npmPackageType={npmPackageType}
strapiAppVersion={strapiAppVersion}
/>
</GridItem>
))}
@ -35,6 +37,7 @@ const NpmPackagesGrid = ({
NpmPackagesGrid.defaultProps = {
installedPackageNames: [],
strapiAppVersion: null,
};
NpmPackagesGrid.propTypes = {
@ -43,6 +46,7 @@ NpmPackagesGrid.propTypes = {
useYarn: PropTypes.bool.isRequired,
isInDevelopmentMode: PropTypes.bool.isRequired,
npmPackageType: PropTypes.string.isRequired,
strapiAppVersion: PropTypes.string,
};
export default NpmPackagesGrid;

View File

@ -50,7 +50,7 @@ const MarketPlacePage = () => {
const toggleNotification = useNotification();
const [searchQuery, setSearchQuery] = useState('');
const [npmPackageType, setNpmPackageType] = useState('plugin');
const { autoReload: isInDevelopmentMode, dependencies, useYarn } = useAppInfos();
const { autoReload: isInDevelopmentMode, dependencies, useYarn, strapiVersion } = useAppInfos();
const isOnline = useNavigatorOnLine();
useFocusWhenNavigate();
@ -247,6 +247,7 @@ const MarketPlacePage = () => {
useYarn={useYarn}
isInDevelopmentMode={isInDevelopmentMode}
npmPackageType="plugin"
strapiAppVersion={strapiVersion}
/>
)}
</TabPanel>

View File

@ -1223,38 +1223,46 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
</svg>
</div>
</a>
<button
aria-disabled="false"
class="c51 c52"
type="button"
>
<span>
<div
aria-hidden="true"
class="c53 c54 c55"
aria-describedby="tooltip-3"
class=""
tabindex="0"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<button
aria-disabled="false"
class="c51 c52"
type="button"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
<div
aria-hidden="true"
class="c53 c54 c55"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</span>
</div>
</div>
</div>
@ -1340,38 +1348,47 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
</svg>
</div>
</a>
<button
aria-disabled="false"
class="c51 c52"
type="button"
>
<span>
<div
aria-hidden="true"
class="c53 c54 c55"
aria-describedby="tooltip-5"
class=""
tabindex="0"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<button
aria-disabled="true"
class="c51 c52"
disabled=""
type="button"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
<div
aria-hidden="true"
class="c53 c54 c55"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</span>
</div>
</div>
</div>
@ -1410,7 +1427,7 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
Documentation
<span>
<div
aria-describedby="tooltip-3"
aria-describedby="tooltip-7"
class="c43"
tabindex="0"
>
@ -1579,38 +1596,47 @@ exports[`Marketplace page renders and matches the plugin tab snapshot 1`] = `
</svg>
</div>
</a>
<button
aria-disabled="false"
class="c51 c52"
type="button"
>
<span>
<div
aria-hidden="true"
class="c53 c54 c55"
aria-describedby="tooltip-9"
class=""
tabindex="0"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
<button
aria-disabled="true"
class="c51 c52"
disabled=""
type="button"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
<div
aria-hidden="true"
class="c53 c54 c55"
>
<svg
fill="none"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.056 24h15.906c.583 0 1.056-.473 1.056-1.056V7.028c0-.583-.473-1.056-1.056-1.056H1.056C.473 5.972 0 6.445 0 7.028v15.916C0 23.527.473 24 1.056 24z"
fill="#212134"
/>
<path
d="M8.094 2.111h13.795v13.795h-1.127v2.112h2.182A1.056 1.056 0 0024 16.962V1.056A1.056 1.056 0 0022.944 0H7.038a1.056 1.056 0 00-1.056 1.056v2.252h2.112V2.11z"
fill="#212134"
/>
</svg>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</div>
<span
class="c56 c57"
>
Copy install command
</span>
</button>
</span>
</div>
</div>
</div>
@ -2724,7 +2750,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Amazon Ses
<span>
<div
aria-describedby="tooltip-9"
aria-describedby="tooltip-21"
class="c43"
tabindex="0"
>
@ -2856,7 +2882,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
AWS S3
<span>
<div
aria-describedby="tooltip-11"
aria-describedby="tooltip-23"
class="c43"
tabindex="0"
>
@ -2988,7 +3014,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Cloudinary
<span>
<div
aria-describedby="tooltip-13"
aria-describedby="tooltip-25"
class="c43"
tabindex="0"
>
@ -3110,7 +3136,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Local Upload
<span>
<div
aria-describedby="tooltip-15"
aria-describedby="tooltip-27"
class="c43"
tabindex="0"
>
@ -3242,7 +3268,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Mailgun
<span>
<div
aria-describedby="tooltip-17"
aria-describedby="tooltip-29"
class="c43"
tabindex="0"
>
@ -3374,7 +3400,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Nodemailer
<span>
<div
aria-describedby="tooltip-19"
aria-describedby="tooltip-31"
class="c43"
tabindex="0"
>
@ -3506,7 +3532,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Rackspace
<span>
<div
aria-describedby="tooltip-21"
aria-describedby="tooltip-33"
class="c43"
tabindex="0"
>
@ -3638,7 +3664,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
SendGrid
<span>
<div
aria-describedby="tooltip-23"
aria-describedby="tooltip-35"
class="c43"
tabindex="0"
>
@ -3770,7 +3796,7 @@ exports[`Marketplace page renders and matches the provider tab snapshot 1`] = `
Sendmail
<span>
<div
aria-describedby="tooltip-25"
aria-describedby="tooltip-37"
class="c43"
tabindex="0"
>

View File

@ -8,6 +8,7 @@ import {
screen,
getByText,
queryByText,
getByRole,
} from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import { QueryClient, QueryClientProvider } from 'react-query';
@ -35,6 +36,7 @@ jest.mock('@strapi/helper-plugin', () => ({
'@strapi/plugin-documentation': '4.2.0',
'@strapi/provider-upload-cloudinary': '4.2.0',
},
strapiVersion: '4.1.0',
useYarn: true,
})),
}));
@ -215,7 +217,7 @@ describe('Marketplace page', () => {
expect(pluginCardText).toEqual(null);
});
it('shows the installed text for installed plugins', async () => {
it('shows the installed text for installed plugins', () => {
render(App);
const pluginsTab = screen.getByRole('tab', { name: /plugins/i });
fireEvent.click(pluginsTab);
@ -235,7 +237,7 @@ describe('Marketplace page', () => {
expect(notInstalledText).toBeVisible();
});
it('shows the installed text for installed providers', async () => {
it('shows the installed text for installed providers', () => {
// Open providers tab
render(App);
const providersTab = screen.getByRole('tab', { name: /providers/i });
@ -255,4 +257,38 @@ describe('Marketplace page', () => {
const notInstalledText = queryByText(notInstalledCard, /copy install command/i);
expect(notInstalledText).toBeVisible();
});
it('disables the button and shows compatibility tooltip message when version provided', async () => {
const { getByTestId } = render(App);
const alreadyInstalledCard = screen
.getAllByTestId('npm-package-card')
.find((div) => div.innerHTML.includes('Transformer'));
const button = getByRole(alreadyInstalledCard, 'button', { name: /copy install command/i });
const tooltip = getByTestId(`tooltip-Transformer`);
fireEvent.mouseOver(button);
await waitFor(() => {
expect(tooltip).toBeVisible();
});
expect(button).toBeDisabled();
expect(tooltip).toBeInTheDocument();
expect(tooltip).toHaveTextContent('Update your Strapi version: "4.1.0" to: "4.0.7"');
});
it('shows compatibility tooltip message when no version provided', async () => {
const { getByTestId } = render(App);
const alreadyInstalledCard = screen
.getAllByTestId('npm-package-card')
.find((div) => div.innerHTML.includes('Config Sync'));
const button = getByRole(alreadyInstalledCard, 'button', { name: /copy install command/i });
const tooltip = getByTestId(`tooltip-Config Sync`);
fireEvent.mouseOver(button);
await waitFor(() => {
expect(tooltip).toBeVisible();
});
expect(button).not.toBeDisabled();
expect(tooltip).toBeInTheDocument();
expect(tooltip).toHaveTextContent(
'Unable to verify compatibility with your Strapi version: "4.1.0"'
);
});
});

View File

@ -48,6 +48,7 @@ const handlers = [
validated: false,
madeByStrapi: false,
strapiCompatibility: 'v3',
strapiVersion: '^4.0.0',
},
},
{
@ -221,6 +222,7 @@ const handlers = [
validated: false,
madeByStrapi: false,
strapiCompatibility: 'v4',
strapiVersion: '4.x.x',
},
},
{
@ -291,6 +293,7 @@ const handlers = [
validated: true,
madeByStrapi: false,
strapiCompatibility: 'v4',
strapiVersion: 'Contact developer',
},
},
{
@ -362,6 +365,7 @@ const handlers = [
validated: false,
madeByStrapi: false,
strapiCompatibility: 'v4',
strapiVersion: '^3.4.2',
},
},
{
@ -404,6 +408,7 @@ const handlers = [
validated: true,
madeByStrapi: true,
strapiCompatibility: 'v4',
strapiVersion: '^4.0.7',
},
},
{
@ -446,6 +451,7 @@ const handlers = [
validated: true,
madeByStrapi: false,
strapiCompatibility: 'v3',
strapiVersion: '^4.3.0',
},
},
{
@ -488,6 +494,7 @@ const handlers = [
validated: false,
madeByStrapi: false,
strapiCompatibility: 'v4',
strapiVersion: '4.0.7',
},
},
],

View File

@ -100,11 +100,11 @@
"Settings.apiTokens.duration.30-days": "30 days",
"Settings.apiTokens.duration.90-days": "90 days",
"Settings.apiTokens.duration.unlimited": "Unlimited",
"Settings.apiTokens.form.duration":"Token duration",
"Settings.apiTokens.form.type":"Token type",
"Settings.apiTokens.duration.expiration-date":"Expiration date",
"Settings.apiTokens.createPage.permissions.title":"Permissions",
"Settings.apiTokens.createPage.permissions.description":"Only actions bound by a route are listed below.",
"Settings.apiTokens.form.duration": "Token duration",
"Settings.apiTokens.form.type": "Token type",
"Settings.apiTokens.duration.expiration-date": "Expiration date",
"Settings.apiTokens.createPage.permissions.title": "Permissions",
"Settings.apiTokens.createPage.permissions.description": "Only actions bound by a route are listed below.",
"Settings.apiTokens.RegenerateDialog.title": "Regenerate token",
"Settings.apiTokens.popUpWarning.message": "Are you sure you want to regenerate this token?",
"Settings.apiTokens.Button.cancel": "Cancel",
@ -270,6 +270,8 @@
"admin.pages.MarketPlacePage.plugin.installed": "Installed",
"admin.pages.MarketPlacePage.plugin.tooltip.madeByStrapi": "Made by Strapi",
"admin.pages.MarketPlacePage.plugin.tooltip.verified": "Plugin verified by Strapi",
"admin.pages.MarketPlacePage.plugin.version": "Update your Strapi version: \"{strapiAppVersion}\" to: \"{versionRange}\"",
"admin.pages.MarketPlacePage.plugin.version.null": "Unable to verify compatibility with your Strapi version: \"{strapiAppVersion}\"",
"admin.pages.MarketPlacePage.providers": "Providers",
"admin.pages.MarketPlacePage.search.clear": "Clear the search",
"admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",

View File

@ -164,4 +164,4 @@
}
}
}
}
}

View File

@ -110,5 +110,6 @@ coverage
license.txt
exports
*.cache
dist
build
.strapi-updater.json