Merge branch 'master' into rbac/decorrelate-crud

This commit is contained in:
HichamELBSI 2020-12-14 11:17:41 +01:00
commit f67b519f2f
52 changed files with 904 additions and 773 deletions

View File

@ -26,6 +26,16 @@ Before contributing, you will probably have to create a RFC on this [strapi/rfcs
This project and everyone participating in it are governed by the [Strapi Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please read the [full text](CODE_OF_CONDUCT.md) so that you can read which actions may or may not be tolerated.
## Contributor License Agreement (CLA)
### Individual
In order to accept your pull request, we need you to submit a CLA. You only need to do this once. If you are submitting a pull request for the first time, you can complete your CLA [here](https://cla.strapi.io/strapi/strapi) or just submit a Pull Request and our CLA Bot will ask you to sign the CLA before merging your Pull Request.
### Company
If you are making contributions to our repositories on behalf of your company, then we will need a Corporate Contributor License Agreement (CLA) signed. In order to do that, please contact us at [contributions@strapi.io](mailto:contributions@strapi.io).
## Documentation
Pull requests relating to fixing documentation for the latest release should be directed towards the [documentation branch](https://github.com/strapi/strapi/tree/documentation) **not** towards the master branch. Any PRs made towards the master branch will not be released until the next Strapi version release.

View File

@ -136,6 +136,7 @@ For general help using Strapi, please refer to [the official Strapi documentatio
- [Slack](http://slack.strapi.io) (For live discussion with the Community and Strapi team)
- [GitHub](https://github.com/strapi/strapi) (Bug reports, Contributions)
- [Community Forum](https://forum.strapi.io) (Questions and Discussions)
- [Academy](https://academy.strapi.io) (Learn the fundamentals of Strapi)
- [ProductBoard](https://portal.productboard.com/strapi/tabs/2-under-consideration) (Roadmap, Feature requests)
- [Twitter](https://twitter.com/strapijs) (Get the news fast)
- [Facebook](https://www.facebook.com/Strapi-616063331867161)

View File

@ -25,7 +25,7 @@ You can use a template when creating a project with `create-strapi-app`.
::: tab yarn
```bash
yarn create strapi-app my-project --template <template-github-url>
yarn create strapi-app my-project --template <template-github-name>
```
:::
@ -33,13 +33,36 @@ yarn create strapi-app my-project --template <template-github-url>
::: tab npx
```bash
npx create-strapi-app my-project --template <template-github-url>
npx create-strapi-app my-project --template <template-github-name>
```
:::
::::
In these examples, the `template-github-name` argument can have different forms:
- A shorthand. If a Github user named `paul` has a repository called `strapi-template-restaurant`, then the shorthand would be `paul/restaurant`. It only works if the repository's name starts with `strapi-template-`.
- A URL. Just paste the URL of your GitHub repository. It works even if the repository is not prefixed by `strapi-template-`.
::: tip
When using a shorthand, if the username is omitted, the CLI assumes it's `strapi`.
So the following commands are equivalent:
```bash
# Shorthand
yarn create strapi-app my-project --template strapi/blog
# Shorthand with username omitted since it defaults to strapi
yarn create strapi-app my-project --template blog
# Full GitHub URL
yarn create strapi-app my-project --template https://github.com/strapi/strapi-template-blog
```
:::
You can use the `--template` option in combination with all other `create-strapi-app` options, like `--quickstart` or `--no-run`.
## Creating a template
@ -52,7 +75,7 @@ Second, a template must follow the following file structure.
### File structure
You can add as many files as you want to the root of your template repository. But it must at least have a `template.json` file and a `template` directory.
You can add as many files as you want to the root of your template repository. But it must at least have `template` directory, and either a `template.json` or a `template.js` file.
The `template.json` is used to extend the Strapi app's default `package.json`. You can put all the properties that should overwrite the default `package.json` in a root `package` property. For example, a `template.json` might look like this:
@ -69,6 +92,20 @@ The `template.json` is used to extend the Strapi app's default `package.json`. Y
}
```
You can also use a `template.js` file instead of the `template.json` file. It should export a function that returns an object with the same properties. It's useful when our properties need to have dynamic values. For example, we can use it to make sure that a template requires the latest version of a Strapi plugin:
```js
module.exports = function(scope) {
return {
package: {
dependencies: {
"strapi-plugin-graphql": scope.strapiVersion,
}
}
}
}
```
The `template` directory is where you can extend the file contents of a Strapi project. All the children are optional, you should only include the files that will overwrite the default Strapi app.
Only the following contents are allowed inside the `template` directory:

View File

@ -1,7 +1,7 @@
{
"name": "getstarted",
"private": true,
"version": "3.3.3",
"version": "3.3.4",
"description": "A Strapi application.",
"scripts": {
"develop": "strapi develop",
@ -17,22 +17,22 @@
"mysql": "^2.17.1",
"pg": "8.4.0",
"sqlite3": "^5.0.0",
"strapi": "3.3.3",
"strapi-admin": "3.3.3",
"strapi-connector-bookshelf": "3.3.3",
"strapi-connector-mongoose": "3.3.3",
"strapi-middleware-views": "3.3.3",
"strapi-plugin-content-manager": "3.3.3",
"strapi-plugin-content-type-builder": "3.3.3",
"strapi-plugin-documentation": "3.3.3",
"strapi-plugin-email": "3.3.3",
"strapi-plugin-graphql": "3.3.3",
"strapi-plugin-upload": "3.3.3",
"strapi-plugin-users-permissions": "3.3.3",
"strapi-provider-email-mailgun": "3.3.3",
"strapi-provider-upload-aws-s3": "3.3.3",
"strapi-provider-upload-cloudinary": "3.3.3",
"strapi-utils": "3.3.3"
"strapi": "3.3.4",
"strapi-admin": "3.3.4",
"strapi-connector-bookshelf": "3.3.4",
"strapi-connector-mongoose": "3.3.4",
"strapi-middleware-views": "3.3.4",
"strapi-plugin-content-manager": "3.3.4",
"strapi-plugin-content-type-builder": "3.3.4",
"strapi-plugin-documentation": "3.3.4",
"strapi-plugin-email": "3.3.4",
"strapi-plugin-graphql": "3.3.4",
"strapi-plugin-upload": "3.3.4",
"strapi-plugin-users-permissions": "3.3.4",
"strapi-provider-email-mailgun": "3.3.4",
"strapi-provider-upload-aws-s3": "3.3.4",
"strapi-provider-upload-cloudinary": "3.3.4",
"strapi-utils": "3.3.4"
},
"strapi": {
"uuid": "getstarted"

View File

@ -1,5 +1,5 @@
{
"version": "3.3.3",
"version": "3.3.4",
"packages": [
"packages/*",
"examples/*"

View File

@ -4,38 +4,38 @@
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
"@swc-node/jest": "^0.3.4",
"@testing-library/jest-dom": "^5.8.0",
"@testing-library/react": "^11.0.2",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"@testing-library/react-hooks": "^3.4.2",
"axios-mock-adapter": "^1.18.2",
"axios-mock-adapter": "^1.19.0",
"babel-eslint": "^10.0.0",
"chokidar": "3.3.1",
"cross-env": "^5.2.0",
"cross-env": "^7.0.3",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.12.1",
"eslint": "^6.3.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.2.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.1.2",
"eslint-plugin-redux-saga": "^1.1.0",
"eslint-plugin-redux-saga": "^1.2.1",
"execa": "^1.0.0",
"fs-extra": "9.0.1",
"glob": "7.1.6",
"husky": "^3.0.0",
"istanbul": "~0.4.2",
"jest": "^26.0.1",
"jest": "^26.6.3",
"jest-cli": "^26.0.1",
"jest-styled-components": "^7.0.2",
"lerna": "^3.13.1",
"lint-staged": "^10.4.0",
"npm-run-all": "^4.1.5",
"prettier": "^1.18.2",
"react-test-renderer": "^16.9.0",
"react-test-renderer": "^17.0.1",
"request": "^2.87.0",
"request-promise-native": "^1.0.9",
"rimraf": "3.0.2",

View File

@ -1,6 +1,6 @@
{
"name": "create-strapi-app",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a new Strapi application.",
"license": "SEE LICENSE IN LICENSE",
"homepage": "http://strapi.io",
@ -21,7 +21,7 @@
],
"dependencies": {
"commander": "6.1.0",
"strapi-generate-new": "3.3.3"
"strapi-generate-new": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -4,6 +4,7 @@
"Auth.form.button.login": "Se connecter",
"Auth.form.button.register": "Prêt à commencer",
"Auth.form.button.reset-password": "Changez votre mot de passe",
"Auth.form.confirmPassword.label": "Confirmation du mot de passe",
"Auth.form.email.label": "Email",
"Auth.form.email.placeholder": "johndoe@gmail.com",
"Auth.form.error.blocked": "Votre compte a été bloqué par l'administrateur.",
@ -21,8 +22,12 @@
"Auth.form.error.ratelimit": "Trop de tentatives, veuillez réessayer dans une minute.",
"Auth.form.error.user.not-exist": "Cette e-mail n'existe pas.",
"Auth.form.error.username.taken": "Ce nom est déjà utilisé",
"Auth.form.firstname.label": "Prénom",
"Auth.form.firstname.placeholder": "John",
"Auth.form.forgot-password.email.label": "Entrez votre e-mail",
"Auth.form.forgot-password.email.label.success": "E-mail envoyé avec succès à l'adresse suivante",
"Auth.form.lastname.label": "Nom",
"Auth.form.lastname.placeholder": "Doe",
"Auth.form.password.label": "Mot de Passe",
"Auth.form.register.news.label": "Me tenir au courant des nouvelles fonctionnalités et améliorations à venir (en faisant cela vous acceptez les {terms} et {policy}).",
"Auth.form.rememberMe.label": "Se souvenir de moi",
@ -30,6 +35,8 @@
"Auth.form.username.placeholder": "John Doe",
"Auth.link.forgot-password": "Mot de passe oublié ?",
"Auth.link.ready": "Prêt à vous connecter ?",
"Auth.link.signin": "Connexion",
"Auth.link.signin.account": "Vous avez déjà un compte ?",
"Auth.privacy-policy-agreement.policy": "la politique de confidentialité",
"Auth.privacy-policy-agreement.terms": "termes",
"Content Manager": "Content Manager",
@ -48,6 +55,16 @@
"Provider": "Provider",
"ResetPasswordToken": "ResetPasswordToken",
"Role": "Rôle",
"Settings.permissions.menu.link.roles.label": "Rôles",
"Settings.permissions.menu.link.users.label": "Utilisateurs",
"Settings.permissions.users.add-new": "Ajouter un nouvel utilisateur",
"Settings.permissions.users.create": "Créer un nouvel Utilisateur",
"Settings.permissions.users.form.email": "Email",
"Settings.permissions.users.form.firstname": "Prénom",
"Settings.permissions.users.form.lastname": "Nom",
"Settings.permissions.users.listview.header.description.plural": "{number} utilisateurs trouvés",
"Settings.permissions.users.listview.header.description.singular": "{number} utilisateur trouvé",
"Settings.permissions.users.listview.header.title": "Utilisateurs",
"Username": "Nom d'utilisateur",
"Users": "Utilisateurs",
"Users & Permissions": "Utilisateurs et autorisations",
@ -56,6 +73,7 @@
"app.components.BlockLink.documentation": "Voir la documentation",
"app.components.BlockLink.documentation.content": "Découvrez les concepts, guides et tutoriaux.",
"app.components.Button.cancel": "Annuler",
"app.components.Button.reset": "Annuler",
"app.components.Button.save": "Sauvegarder",
"app.components.ComingSoonPage.comingSoon": "Bientôt disponible",
"app.components.DownloadInfo.download": "Téléchargement en cours...",
@ -93,6 +111,18 @@
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "Aucun plugin installé",
"app.components.LeftMenuLinkContainer.plugins": "Plugins",
"app.components.LeftMenuLinkContainer.settings": "Paramètres",
"app.components.Users.MagicLink.connect": "Envoyez ce lien à l'utilisateur pour qu'il se connecte.",
"app.components.Users.ModalCreateBody.block-title.details": "Détails",
"app.components.Users.ModalCreateBody.block-title.roles": "Rôles de l'utilisateur",
"app.components.Users.SortPicker.button-label": "Trier par",
"app.components.Users.SortPicker.sortby.email_asc": "Email (A à Z)",
"app.components.Users.SortPicker.sortby.email_desc": "Email (Z à A)",
"app.components.Users.SortPicker.sortby.firstname_asc": "Prénom (A à Z)",
"app.components.Users.SortPicker.sortby.firstname_desc": "Prénom (Z à A)",
"app.components.Users.SortPicker.sortby.lastname_asc": "Nom (A à Z)",
"app.components.Users.SortPicker.sortby.lastname_desc": "Nom (Z à A)",
"app.components.Users.SortPicker.sortby.username_asc": "Nom d'utilisateur (A à Z)",
"app.components.Users.SortPicker.sortby.username_desc": "Nom d'utilisateur (Z à A)",
"app.components.ListPluginsPage.description": "Liste des plugins installés dans le projet.",
"app.components.ListPluginsPage.helmet.title": "List plugins",
"app.components.ListPluginsPage.title": "Plugins",
@ -118,11 +148,25 @@
"app.components.listPlugins.title.singular": "{number} est disponible",
"app.components.listPluginsPage.deletePlugin.error": "Une erreur est survenue pendant la désintallation",
"app.containers.App.notification.error.init": "Une erreur est survenue en requêtant l'API",
"app.containers.AuthPage.ForgotPasswordSuccess.text.contact-admin": "Si vous ne recevez pas ce lien, veuillez contacter votre administrateur.",
"app.containers.AuthPage.ForgotPasswordSuccess.text.email": "La réception de votre lien de récupération de mot de passe peut prendre quelques minutes.",
"app.containers.AuthPage.ForgotPasswordSuccess.title": "Email envoyé",
"app.containers.Users.EditPage.form.active.label": "Actif",
"app.containers.Users.EditPage.header.label": "Modifier {name}",
"app.containers.Users.EditPage.header.label-loading": "Modifier l'utilisateur",
"app.containers.Users.EditPage.roles-bloc-title": "Rôles attribués",
"app.containers.Users.ModalForm.footer.button-success": "Créer l'utilisateur",
"app.links.configure-view": "Configurez la vue",
"app.utils.SelectOption.defaultMessage": " ",
"app.utils.add-filter": "Ajouter un filtre",
"app.utils.defaultMessage": " ",
"app.utils.delete": "Supprimer",
"app.utils.errors.file-too-big.message": "Le fichier est trop lourd",
"app.utils.filters": "Filtres",
"app.utils.placeholder.defaultMessage": " ",
"app.utils.publish": "Publier",
"app.utils.select-all": "Tout sélectionner",
"app.utils.unpublish": "Annuler la publication",
"components.AutoReloadBlocker.description": "Démarrez Strapi avec l'une des commandes suivantes:",
"components.AutoReloadBlocker.header": "L'autoReload doit être activé pour ce plugin.",
"components.ErrorBoundary.title": "Une erreur est survenue...",
@ -174,9 +218,13 @@
"components.WysiwygBottomControls.fullscreen": "Plein écran",
"components.WysiwygBottomControls.uploadFiles": "Ajouter des fichiers en les 'glissant-déposant', {browse}, ou en les collant depuis le presse-papier",
"components.WysiwygBottomControls.uploadFiles.browse": "en les selectionnant",
"components.popUpWarning.button.cancel": "Non, annuler",
"components.popUpWarning.button.confirm": "Oui, confirmer",
"components.popUpWarning.message": "Etes-vous sure de vouloir le supprimer ?",
"components.popUpWarning.title": "Merci de confirmer",
"form.button.done": "Terminer",
"form.button.finish": "Terminer",
"global.prompt.unsaved": "Êtes-vous sûr de vouloir quitter cette page? Toutes vos modifications seront perdues",
"notification.error": "Une erreur est survenue",
"notification.error.layout": "Impossible de récupérer le layout de l'admin",
"notification.form.error.fields": "Le formulaire contient des erreurs",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-admin",
"version": "3.3.3",
"version": "3.3.4",
"description": "Strapi Admin",
"repository": {
"type": "git",
@ -36,14 +36,14 @@
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.12",
"autoprefixer": "^9.8.6",
"axios": "^0.20.0",
"axios": "^0.21.0",
"babel-loader": "^8.1.0",
"bcryptjs": "^2.4.3",
"bootstrap": "^4.5.3",
"chalk": "^2.4.2",
"chokidar": "^3.2.1",
"classnames": "^2.2.6",
"cross-env": "^5.0.5",
"cross-env": "^7.0.3",
"css-loader": "^2.1.1",
"duplicate-package-checker-webpack-plugin": "^3.0.0",
"execa": "^1.0.0",
@ -66,7 +66,7 @@
"lodash": "4.17.19",
"match-sorter": "^4.0.2",
"mini-css-extract-plugin": "^0.6.0",
"moment": "^2.24.0",
"moment": "^2.29.1",
"p-map": "4.0.0",
"passport-local": "1.0.0",
"prop-types": "^15.7.2",
@ -93,8 +93,8 @@
"reselect": "^4.0.0",
"sanitize.css": "^4.1.0",
"sift": "13.1.10",
"strapi-helper-plugin": "3.3.3",
"strapi-utils": "3.3.3",
"strapi-helper-plugin": "3.3.4",
"strapi-utils": "3.3.4",
"style-loader": "^0.23.1",
"styled-components": "^5.0.0",
"terser-webpack-plugin": "^1.2.3",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-connector-bookshelf",
"version": "3.3.3",
"version": "3.3.4",
"description": "Bookshelf hook for the Strapi framework",
"homepage": "http://strapi.io",
"keywords": [
@ -23,7 +23,7 @@
"p-map": "4.0.0",
"pluralize": "^8.0.0",
"rimraf": "3.0.2",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"peerDependencies": {
"knex": "^0.20.0"

View File

@ -1,6 +1,6 @@
{
"name": "strapi-connector-mongoose",
"version": "3.3.3",
"version": "3.3.4",
"description": "Mongoose hook for the Strapi framework",
"homepage": "http://strapi.io",
"keywords": [
@ -20,8 +20,8 @@
"mongoose-float": "^1.0.4",
"mongoose-long": "^0.3.2",
"pluralize": "^8.0.0",
"semver": "^7.3.2",
"strapi-utils": "3.3.3"
"semver": "^7.3.4",
"strapi-utils": "3.3.4"
},
"author": {
"email": "hi@strapi.io",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-database",
"version": "3.3.3",
"version": "3.3.4",
"description": "Strapi's database layer",
"homepage": "http://strapi.io",
"main": "./lib/index.js",
@ -30,7 +30,7 @@
"dependencies": {
"lodash": "4.17.19",
"p-map": "4.0.0",
"strapi-utils": "3.3.3",
"strapi-utils": "3.3.4",
"verror": "^1.10.0"
},
"gitHead": "231263a3535658bab1e9492c6aaaed8692d62a53"

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-api",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate an API for a Strapi application.",
"homepage": "http://strapi.io",
"keywords": [
@ -15,7 +15,7 @@
"dependencies": {
"lodash": "4.17.19",
"pluralize": "^8.0.0",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-controller",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a controller for a Strapi API.",
"homepage": "http://strapi.io",
"keywords": [
@ -15,7 +15,7 @@
},
"dependencies": {
"lodash": "4.17.19",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-model",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a model for a Strapi API.",
"homepage": "http://strapi.io",
"keywords": [
@ -16,7 +16,7 @@
"dependencies": {
"lodash": "4.17.19",
"pluralize": "^8.0.0",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -72,7 +72,7 @@ module.exports = async function createProject(scope, { client, connection, depen
const hasTemplate = Boolean(scope.template);
if (hasTemplate) {
try {
await mergeTemplate(scope.template, rootPath);
await mergeTemplate(scope, rootPath);
} catch (error) {
throw new Error(`⛔️ Template installation failed: ${error.message}`);
}

View File

@ -1,191 +0,0 @@
'use strict';
const path = require('path');
const fse = require('fs-extra');
const fetch = require('node-fetch');
const tar = require('tar');
const _ = require('lodash');
const chalk = require('chalk');
const gitInfo = require('hosted-git-info');
// Specify all the files and directories a template can have
const allowChildren = '*';
const allowedTemplateContents = {
'README.md': true,
'.env.example': true,
api: allowChildren,
components: allowChildren,
config: {
functions: allowChildren,
},
data: allowChildren,
plugins: allowChildren,
public: allowChildren,
scripts: allowChildren,
};
// Make sure the template has the required top-level structure
async function checkTemplateRootStructure(templatePath) {
// Make sure the root of the repo has a template.json and a template/ folder
const templateJsonPath = path.resolve(templatePath, 'template.json');
try {
const hasTemplateJson = !fse.statSync(templateJsonPath).isDirectory();
if (!hasTemplateJson) {
throw Error();
}
} catch (error) {
throw Error(`A template must have a root ${chalk.green('template.json')} file`);
}
// Make sure the root of the repo has a template.json and a template/ folder
const templateDirPath = path.resolve(templatePath, 'template');
try {
const hasTemplateDir = fse.statSync(templateDirPath).isDirectory();
if (!hasTemplateDir) {
throw Error();
}
} catch (error) {
throw Error(`A template must have a root ${chalk.green('template/')} directory`);
}
}
// Traverse template tree to make sure each file and folder is allowed
async function checkTemplateContentsStructure(templateContentsPath) {
// Recursively check if each item in a directory is allowed
const checkPathContents = (pathToCheck, parents) => {
const contents = fse.readdirSync(pathToCheck);
contents.forEach(item => {
const nextParents = [...parents, item];
const matchingTreeValue = _.get(allowedTemplateContents, nextParents);
// Treat files and directories separately
const itemPath = path.resolve(pathToCheck, item);
const isDirectory = fse.statSync(itemPath).isDirectory();
if (matchingTreeValue === undefined) {
// Unknown paths are forbidden
throw Error(
`Illegal template structure, unknown path ${chalk.green(nextParents.join('/'))}`
);
}
if (matchingTreeValue === true) {
if (!isDirectory) {
// All good, the file is allowed
return;
}
throw Error(
`Illegal template structure, expected a file and got a directory at ${chalk.green(
nextParents.join('/')
)}`
);
}
if (isDirectory) {
if (matchingTreeValue === allowChildren) {
// All children are allowed
return;
}
// Check if the contents of the directory are allowed
checkPathContents(itemPath, nextParents);
} else {
throw Error(
`Illegal template structure, unknow file ${chalk.green(nextParents.join('/'))}`
);
}
});
};
checkPathContents(templateContentsPath, []);
}
function getRepoInfo(githubURL) {
const info = gitInfo.fromUrl(githubURL);
// Make sure it's a github url
if (info == null || info.type !== 'github') {
throw Error('A Strapi template can only be a GitHub URL');
}
return { user: info.user, project: info.project };
}
async function downloadGithubRepo(repoInfo, templatePath) {
// Download from GitHub
const { user, project } = repoInfo;
const codeload = `https://codeload.github.com/${user}/${project}/tar.gz/master`;
const response = await fetch(codeload);
// Store locally
fse.mkdirSync(templatePath);
await new Promise(resolve => {
response.body.pipe(tar.extract({ strip: 1, cwd: templatePath })).on('close', resolve);
});
}
// Merge the template's template.json into the Strapi project's package.json
async function mergePackageJSON(rootPath, templatePath, templateUrl) {
// Import the package.json and template.json objects
const packageJSON = require(path.resolve(rootPath, 'package.json'));
const templateJSON = require(path.resolve(templatePath, 'template.json'));
if (!templateJSON.package) {
// Nothing to overwrite
return;
}
// Make sure the template.json doesn't overwrite the UUID
if (templateJSON.package.strapi && templateJSON.package.strapi.uuid) {
throw Error('A template cannot overwrite the Strapi UUID');
}
// Use lodash to deeply merge them
const mergedConfig = _.merge(packageJSON, templateJSON.package);
// Add starter info to package.json
(mergedConfig.strapi.template = templateUrl),
// Save the merged config as the new package.json
await fse.writeJSON(path.resolve(rootPath, 'package.json'), mergedConfig, {
spaces: 2,
});
}
// Merge all allowed files and directories
async function mergeFilesAndDirectories(rootPath, templatePath) {
const copyPromises = fse
.readdirSync(path.resolve(templatePath, 'template'))
.map(async fileOrDir => {
// Copy the template contents from the downloaded template to the Strapi project
await fse.copy(
path.resolve(templatePath, 'template', fileOrDir),
path.resolve(rootPath, fileOrDir),
{ overwrite: true, recursive: true }
);
});
await Promise.all(copyPromises);
}
module.exports = async function mergeTemplate(templateUrl, rootPath) {
// Parse template info
const repoInfo = getRepoInfo(templateUrl);
const { user, project } = repoInfo;
console.log(`Installing ${chalk.yellow(`${user}/${project}`)} template.`);
// Download template repository to a temporary directory
const templatePath = path.resolve(rootPath, '.tmp-template');
try {
await downloadGithubRepo(repoInfo, templatePath);
} catch (error) {
throw Error(`Could not download ${chalk.yellow(`${user}/${project}`)} repository`);
}
// Make sure the downloaded template matches the required format
await checkTemplateRootStructure(templatePath);
await checkTemplateContentsStructure(path.resolve(templatePath, 'template'));
// Merge contents of the template in the project
await mergePackageJSON(rootPath, templatePath, templateUrl);
await mergeFilesAndDirectories(rootPath, templatePath);
// Delete the downloaded template repo
await fse.remove(templatePath);
};

View File

@ -27,12 +27,12 @@ const allowedTemplateContents = {
/**
* merge template with new project being created
* @param {string} templateUrl tempalte github url
* @param {string} scope project creation params
* @param {string} rootPath project path
*/
module.exports = async function mergeTemplate(templateUrl, rootPath) {
module.exports = async function mergeTemplate(scope, rootPath) {
// Parse template info
const repoInfo = getRepoInfo(templateUrl);
const repoInfo = getRepoInfo(scope.template);
const { user, project } = repoInfo;
console.log(`Installing ${chalk.yellow(`${user}/${project}`)} template.`);
@ -46,11 +46,12 @@ module.exports = async function mergeTemplate(templateUrl, rootPath) {
}
// Make sure the downloaded template matches the required format
await checkTemplateRootStructure(templatePath);
const { templateConfig } = await checkTemplateRootStructure(templatePath, scope);
await checkTemplateContentsStructure(path.resolve(templatePath, 'template'));
// Merge contents of the template in the project
await mergePackageJSON(rootPath, templatePath, templateUrl);
const fullTemplateUrl = `https://github.com/${user}/${project}`;
await mergePackageJSON(rootPath, templateConfig, fullTemplateUrl);
await mergeFilesAndDirectories(rootPath, templatePath);
// Delete the downloaded template repo
@ -58,23 +59,49 @@ module.exports = async function mergeTemplate(templateUrl, rootPath) {
};
// Make sure the template has the required top-level structure
async function checkTemplateRootStructure(templatePath) {
// Make sure the root of the repo has a template.json and a template/ folder
async function checkTemplateRootStructure(templatePath, scope) {
// Make sure the root of the repo has a template.json or a template.js file
const templateJsonPath = path.join(templatePath, 'template.json');
try {
const stat = await fse.stat(templateJsonPath);
if (!stat.isFile()) {
throw Error(`A template must have a root ${chalk.green('template.json')} file`);
}
} catch (error) {
if (error.code === 'ENOENT') {
throw Error(`A template must have a root ${chalk.green('template.json')} file`);
}
const templateFunctionPath = path.join(templatePath, 'template.js');
throw error;
// Store the template config, whether it comes from a JSON or a function
let templateConfig = {};
const hasJsonConfig = fse.existsSync(templateJsonPath);
if (hasJsonConfig) {
const jsonStat = await fse.stat(templateJsonPath);
if (!jsonStat.isFile()) {
throw new Error(`A template's ${chalk.green('template.json')} must be a file`);
}
templateConfig = require(templateJsonPath);
}
// Make sure the root of the repo has a template.json and a template/ folder
const hasFunctionConfig = fse.existsSync(templateFunctionPath);
if (hasFunctionConfig) {
const functionStat = await fse.stat(templateFunctionPath);
if (!functionStat.isFile()) {
throw new Error(`A template's ${chalk.green('template.js')} must be a file`);
}
// Get the config by passing the scope to the function
templateConfig = require(templateFunctionPath)(scope);
}
// Make sure there's exactly one template config file
if (!hasJsonConfig && !hasFunctionConfig) {
throw new Error(
`A template must have either a ${chalk.green('template.json')} or a ${chalk.green(
'template.js'
)} root file`
);
} else if (hasJsonConfig && hasFunctionConfig) {
throw new Error(
`A template cannot have both ${chalk.green('template.json')} and ${chalk.green(
'template.js'
)} root files`
);
}
// Make sure the root of the repo has a template folder
const templateDirPath = path.join(templatePath, 'template');
try {
const stat = await fse.stat(templateDirPath);
@ -88,6 +115,8 @@ async function checkTemplateRootStructure(templatePath) {
throw error;
}
return { templateConfig };
}
// Traverse template tree to make sure each file and folder is allowed
@ -140,14 +169,27 @@ async function checkTemplateContentsStructure(templateContentsPath) {
checkPathContents(templateContentsPath, []);
}
function getRepoInfo(githubURL) {
const { type, user, project } = gitInfo.fromUrl(githubURL);
// Make sure it's a github url
if (type !== 'github') {
throw Error('A Strapi template can only be a GitHub URL');
function getRepoInfo(template) {
try {
const { user, project, default: urlStrategy } = gitInfo.fromUrl(template);
if (urlStrategy === 'https' || urlStrategy === 'http') {
// A full GitHub URL was provided, return username and project directly
return { user, project };
}
if (urlStrategy === 'shortcut') {
// A shorthand was provided, so prefix the project name with "strapi-template-"
return {
user,
project: `strapi-template-${project}`,
};
}
} catch (error) {
// If it's not a GitHub URL, then assume it's a shorthand for an official template
return {
user: 'strapi',
project: `strapi-template-${template}`,
};
}
return { user, project };
}
async function downloadGithubRepo(repoInfo, templatePath) {
@ -165,23 +207,22 @@ async function downloadGithubRepo(repoInfo, templatePath) {
}
// Merge the template's template.json into the Strapi project's package.json
async function mergePackageJSON(rootPath, templatePath, templateUrl) {
// Import the package.json and template.json objects
async function mergePackageJSON(rootPath, templateConfig, templateUrl) {
// Import the package.json as an object
const packageJSON = require(path.resolve(rootPath, 'package.json'));
const templateJSON = require(path.resolve(templatePath, 'template.json'));
if (!templateJSON.package) {
if (!templateConfig.package) {
// Nothing to overwrite
return;
}
// Make sure the template.json doesn't overwrite the UUID
if (templateJSON.package.strapi && templateJSON.package.strapi.uuid) {
if (templateConfig.package.strapi && templateConfig.package.strapi.uuid) {
throw Error('A template cannot overwrite the Strapi UUID');
}
// Use lodash to deeply merge them
const mergedConfig = _.merge(packageJSON, templateJSON.package);
const mergedConfig = _.merge(packageJSON, templateConfig.package);
// Add starter info to package.json
_.set(mergedConfig, 'strapi.template', templateUrl);

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-new",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a new Strapi application.",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-plugin",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate an plugin for a Strapi application.",
"homepage": "http://strapi.io",
"keywords": [
@ -15,7 +15,7 @@
"dependencies": {
"fs-extra": "^9.0.1",
"lodash": "4.17.19",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-policy",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a policy for a Strapi API.",
"homepage": "http://strapi.io",
"keywords": [
@ -15,7 +15,7 @@
},
"dependencies": {
"lodash": "4.17.19",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate-service",
"version": "3.3.3",
"version": "3.3.4",
"description": "Generate a service for a Strapi API.",
"homepage": "http://strapi.io",
"keywords": [
@ -15,7 +15,7 @@
},
"dependencies": {
"lodash": "4.17.19",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"scripts": {
"test": "echo \"no tests yet\""

View File

@ -1,6 +1,6 @@
{
"name": "strapi-generate",
"version": "3.3.3",
"version": "3.3.4",
"description": "Master of ceremonies for the Strapi generators.",
"homepage": "http://strapi.io",
"keywords": [
@ -20,7 +20,7 @@
"fs-extra": "^9.0.1",
"lodash": "4.17.19",
"reportback": "^2.0.2",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"author": {
"name": "Strapi team",

View File

@ -1,6 +1,6 @@
import React, { isValidElement, useState } from 'react';
import PropTypes from 'prop-types';
import { get, isEmpty, isObject } from 'lodash';
import { get, isEmpty, isObject, toLower } from 'lodash';
import { useGlobalContext } from '../../contexts/GlobalContext';
import matchSorter from 'match-sorter';
import LeftMenuLink from '../LeftMenuLink';
@ -54,12 +54,13 @@ function LeftMenuList({ customLink, links, title, searchable }) {
return links.map(link => {
return {
...link,
links: matchSorter(link.links, search, { keys: ['title'] }),
links: matchSorter(link.links, toLower(search), {
keys: [item => toLower(item.title)],
}),
};
});
}
return matchSorter(links, search, { keys: ['title'] });
return matchSorter(links, toLower(search), { keys: [item => toLower(item.title)] });
};
const renderCompo = (link, i) => {

View File

@ -1,6 +1,6 @@
{
"name": "strapi-helper-plugin",
"version": "3.3.3",
"version": "3.3.4",
"description": "Helper for Strapi plugins development",
"files": [
"dist"
@ -61,7 +61,7 @@
"immutable": "^3.8.2",
"invariant": "^2.2.1",
"lodash": "4.17.19",
"moment": "^2.16.0",
"moment": "^2.29.1",
"react": "^16.13.1",
"react-dom": "^16.9.0",
"react-helmet": "^6.1.0",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-hook-ejs",
"version": "3.3.3",
"version": "3.3.4",
"description": "EJS hook for the Strapi framework",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-hook-redis",
"version": "3.3.3",
"version": "3.3.4",
"description": "Redis hook for the Strapi framework",
"homepage": "http://strapi.io",
"keywords": [
@ -19,7 +19,7 @@
"lodash": "4.17.19",
"rimraf": "3.0.2",
"stack-trace": "0.0.10",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"author": {
"email": "hi@strapi.io",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-middleware-views",
"version": "3.3.3",
"version": "3.3.4",
"description": "Views middleware to enable server-side rendering for the Strapi framework",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -18,6 +18,8 @@
"components.FiltersPickWrapper.hide": "Fermer",
"components.LimitSelect.itemsPerPage": "Éléments par page",
"components.Search.placeholder": "Rechercher une entrée...",
"components.Select.draft-info-title": "Statut: Brouillon",
"components.Select.publish-info-title": "Statut: Publié",
"components.SettingsViewWrapper.pluginHeader.description.edit-settings": "Définissez l'apparence de la vue edit.",
"components.SettingsViewWrapper.pluginHeader.description.list-settings": "Définir les paramètres de la vue liste.",
"components.SettingsViewWrapper.pluginHeader.title": "Configurer la vue - {name}",
@ -43,7 +45,13 @@
"containers.Edit.addAnItem": "Ajouter un élément...",
"containers.Edit.clickToJump": "Cliquer pour voir l'entrée",
"containers.Edit.delete": "Supprimer",
"containers.Edit.delete-entry": "Supprimer cette entrée",
"containers.Edit.editing": "Édition en cours...",
"containers.Edit.information.by": "Par",
"containers.Edit.information.draftVersion": "version brouillon",
"containers.Edit.information.editing": "Édition :",
"containers.Edit.information.lastUpdate": "Dernière modification",
"containers.Edit.information.publishedVersion": "version publiée",
"containers.Edit.pluginHeader.title.new": "Créer un document",
"containers.Edit.reset": "Annuler",
"containers.Edit.returnList": "Retourner à la liste",
@ -58,16 +66,21 @@
"containers.Home.pluginHeaderDescription": "Créer et modifier votre type de contenu",
"containers.Home.pluginHeaderTitle": "Type de contenu",
"containers.List.addAnEntry": "Ajouter {entity}",
"containers.List.draft": "Brouillon",
"containers.List.errorFetchRecords": "Erreur",
"containers.List.pluginHeaderDescription": "{label} entrées trouvées",
"containers.List.pluginHeaderDescription.singular": "{label} entrée trouvée",
"containers.List.published": "Publié",
"containers.ListPage.displayedFields": "Champs affichés",
"containers.ListPage.table-headers.published_at": "Statut",
"containers.ListSettingsView.modal-form.edit-label": "Editer le label",
"containers.SettingPage.add.field": "Insérer un autre champ",
"containers.SettingPage.add.relational-field": "Insérer un autre champ relationnel",
"containers.SettingPage.attributes": "Attributs",
"containers.SettingPage.attributes.description": "Organisez les attributs du modèle",
"containers.SettingPage.editSettings.description": "Glissez & déposez les champs pour construire le layout",
"containers.SettingPage.editSettings.entry.title": "Nom de l'entrée",
"containers.SettingPage.editSettings.entry.title.description": "Définissez quelle champ sera affiché",
"containers.SettingPage.editSettings.entry.title.description": "Définissez quel champ sera affiché",
"containers.SettingPage.editSettings.title": "Vue edit (paramètres)",
"containers.SettingPage.layout": "Layout",
"containers.SettingPage.listSettings.description": "Configurez les options de ce modèle",
@ -139,6 +152,11 @@
"popUpWarning.bodyMessage.contentType.delete.all": "Êtes-vous sûr de vouloir supprimer ces entrées ?",
"popUpWarning.warning.cancelAllSettings": "Êtes-vous sûr de vouloir abandonner vos modifications ?",
"popUpWarning.warning.updateAllSettings": "Cela modifiera tous vos précédents paramètres.",
"popUpWarning.warning.publish-question": "Êtes-vous sûr de vouloir le publier ?",
"popUpWarning.warning.unpublish": "Si vous annulez la publication de ce contenu, il deviendra automatiquement un brouillon.",
"popUpWarning.warning.unpublish-question": "Êtes-vous sûr de vouloir annuler sa publication ?",
"success.record.delete": "Supprimé",
"success.record.save": "Sauvegardé"
"success.record.publish": "Publié",
"success.record.save": "Sauvegardé",
"success.record.unpublish": "Publication annulée"
}

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-content-manager",
"version": "3.3.3",
"version": "3.3.4",
"description": "A powerful UI to easily manage your data.",
"strapi": {
"name": "Content Manager",
@ -45,8 +45,8 @@
"redux-immutable": "^4.0.0",
"reselect": "^4.0.0",
"sanitize-html": "2.1.1",
"strapi-helper-plugin": "3.3.3",
"strapi-utils": "3.3.3",
"strapi-helper-plugin": "3.3.4",
"strapi-utils": "3.3.4",
"yup": "^0.27.0"
},
"author": {

View File

@ -14,6 +14,8 @@
"button.model.create": "Créer un type de collection",
"button.single-types.create": "Créer un single type",
"contentType.kind.change.warning": "Vous venez de changer le type de ce modèle: L'API va redémarrer (Les routes, controllers, et les services seront écrasés).",
"contentType.draftAndPublish.description": "Rédigez une version brouillon de chaque entrée avant de la publier",
"contentType.draftAndPublish.label": "Système brouillon/publier",
"form.attribute.item.customColumnName": "Nom de colonne personalisée",
"form.attribute.item.customColumnName.description": "Pratique pour renommer la colonne de la db dans un format plus comprehensible pour les responses de l'API",
"form.attribute.item.defineRelation.fieldName": "Nom du Champ",
@ -45,6 +47,7 @@
"form.button.delete": "Supprimer",
"form.button.finish": "Terminer",
"form.button.save": "Sauvegarder",
"form.contentType.divider.draft-publish": "BROUILLON/PUBLIER",
"from": "de",
"injected-components.content-manager.edit-settings-view.link.components": "Modifier le composant",
"injected-components.content-manager.edit-settings-view.link.content-types": "Modifier le content type",
@ -69,6 +72,9 @@
"popUpForm.navContainer.advanced": "Réglages avancés",
"popUpForm.navContainer.base": "Réglages de base",
"popUpWarning.bodyMessage.contentType.delete": "Êtes-vous sûr de vouloir supprimer cette Collection ? Cela le supprimera aussi de vos types de contenu.",
"popUpWarning.draft-publish.button.confirm": "Oui, désactiver",
"popUpWarning.draft-publish.message": "Si vous désactivez le système Brouillon/Publier, vos brouillons seront supprimés.",
"popUpWarning.draft-publish.second-message": "Êtes-vous sûr de vouloir le désactiver ?",
"relation.attributeName.placeholder": "Ex : auteur, catégorie, tag",
"relation.manyToMany": "a plusieurs",
"relation.manyToOne": "a plusieurs",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-content-type-builder",
"version": "3.3.3",
"version": "3.3.4",
"description": "Strapi plugin to create content type (API).",
"strapi": {
"name": "Content Type Builder",
@ -29,10 +29,10 @@
"redux": "^4.0.1",
"redux-immutable": "^4.0.0",
"reselect": "^4.0.0",
"strapi-generate": "3.3.3",
"strapi-generate-api": "3.3.3",
"strapi-helper-plugin": "3.3.3",
"strapi-utils": "3.3.3",
"strapi-generate": "3.3.4",
"strapi-generate-api": "3.3.4",
"strapi-helper-plugin": "3.3.4",
"strapi-utils": "3.3.4",
"yup": "^0.27.0"
},
"author": {

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-documentation",
"version": "3.3.3",
"version": "3.3.4",
"description": "This is the description of the plugin.",
"strapi": {
"name": "Documentation",
@ -22,7 +22,7 @@
"immutable": "^3.8.2",
"koa-static": "^5.0.0",
"lodash": "4.17.19",
"moment": "^2.24.0",
"moment": "^2.29.1",
"path-to-regexp": "^3.1.0",
"react": "^16.13.1",
"react-copy-to-clipboard": "^5.0.1",
@ -35,7 +35,7 @@
"redux": "^4.0.1",
"redux-immutable": "^4.0.0",
"reselect": "^4.0.0",
"strapi-helper-plugin": "3.3.3",
"strapi-helper-plugin": "3.3.4",
"swagger-ui-dist": "3.35.0"
},
"author": {

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-email",
"version": "3.3.3",
"version": "3.3.4",
"description": "This is the description of the plugin.",
"strapi": {
"name": "Email",
@ -13,12 +13,12 @@
},
"dependencies": {
"lodash": "4.17.19",
"strapi-provider-email-sendmail": "3.3.3",
"strapi-utils": "3.3.3"
"strapi-provider-email-sendmail": "3.3.4",
"strapi-utils": "3.3.4"
},
"devDependencies": {
"rimraf": "3.0.2",
"strapi-helper-plugin": "3.3.3"
"strapi-helper-plugin": "3.3.4"
},
"author": {
"name": "Strapi team",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-graphql",
"version": "3.3.3",
"version": "3.3.4",
"description": "This is the description of the plugin.",
"strapi": {
"name": "graphql",
@ -26,10 +26,10 @@
"koa-compose": "^4.1.0",
"lodash": "4.17.20",
"pluralize": "^8.0.0",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"devDependencies": {
"cross-env": "^5.2.1",
"cross-env": "^7.0.3",
"koa": "^2.13.0",
"rimraf": "3.0.2"
},

View File

@ -0,0 +1,81 @@
{
"button.next": "Suivant",
"checkControl.crop-duplicate": "Dupliquer & recadrer le média",
"checkControl.crop-original": "Recadrer le média d'origine",
"control-card.add": "Ajouter",
"control-card.cancel": "Annuler",
"control-card.copy-link": "Copier le lien",
"control-card.crop": "Recadrer",
"control-card.delete": "Supprimer",
"control-card.download": "Télécharger",
"control-card.edit": "Éditer",
"control-card.replace-media": "Remplacer le média",
"control-card.save": "Sauvegarder",
"filter.add": "Ajouter un filtre",
"form.button.replace-media": "Remplacer le média",
"form.input.decription.file-alt": "Ce texte sera affiché si le média ne peut pas être affiché.",
"form.input.label.file-alt": "Texte alternatif",
"form.input.label.file-caption": "Légende",
"form.input.label.file-name": "Nom du fichier",
"form.upload-url.error.url.invalid": "Une URL n'est pas valide",
"form.upload-url.error.url.invalids": "{number} URLs ne sont pas valides",
"header.actions.upload-assets": "Importer des médias",
"header.content.assets-empty": "Aucun média",
"header.content.assets-multiple": "{number} médias",
"header.content.assets-single": "1 média",
"input.button.label": "Parcourir les fichiers",
"input.label-bold": "Glissez & déposez",
"input.label-normal": "pour importer ou",
"input.placeholder": "Cliquez pour sélectionner un média ou glissez & déposez un fichier dans cette zone",
"input.url.description": "Séparez vos URLs par un retour à la ligne.",
"input.url.label": "URL",
"list.assets-empty.subtitle": "Ajoutez-en un à la liste.",
"list.assets-empty.title": "Il n'y a pas encore de média",
"list.assets-empty.title-withSearch": "Il n'y a aucun média avec les filtres appliqués",
"list.assets.selected.plural": "{number} médias sélectionnés",
"list.assets.selected.singular": "{number} média sélectionné",
"list.assets.type-not-allowed": "Ce type de fichier n'est pas autorisé.",
"modal.file-details.date": "Date",
"modal.file-details.dimensions": "Dimensions",
"modal.file-details.extension": "Extension",
"modal.file-details.size": "Taille",
"modal.header.browse": "Importer des médias",
"modal.header.file-detail": "Détails",
"modal.header.pending-assets": "Médias en attente",
"modal.header.select-files": "Fichiers sélectionnés",
"modal.nav.browse": "parcourir",
"modal.nav.computer": "depuis l'ordinateur",
"modal.nav.selected": "sélectionné(s)",
"modal.nav.url": "depuis une url",
"modal.selected-list.sub-header-subtitle": "Glissez-déposez pour réorganiser les médias dans le champ",
"modal.upload-list.footer.button.plural": "Importer {number} médias dans la médiathèque",
"modal.upload-list.footer.button.singular": "Importer {number} média dans la médiathèque",
"modal.upload-list.sub-header-subtitle": "Gérez les médias avant de les ajouter à la médiathèque",
"modal.upload-list.sub-header-title.plural": "{number} médias sélectionnés",
"modal.upload-list.sub-header-title.singular": "{number} média sélectionné",
"modal.upload-list.sub-header.button": "Ajouter plus de médias",
"plugin.description.long": "Gestion des fichiers multimédias.",
"plugin.description.short": "Gestion des fichiers multimédias.",
"plugin.name": "Médiathèque",
"search.placeholder": "Rechercher un média...",
"settings.form.autoOrientation.description": "Faire pivoter automatiquement l'image selon les EXIF d'orientation",
"settings.form.autoOrientation.label": "Activer l'orientation automatique",
"settings.form.responsiveDimensions.description": "Génère automatiquement plusieurs formats (grand, moyen, petit) du média importé",
"settings.form.responsiveDimensions.label": "Activer le téléchargement \"responsive friendly\"",
"settings.form.sizeOptimization.label": "Activer l'optimisation de la taille (sans perte de qualité)",
"settings.form.videoPreview.description": "Génère un aperçu de six secondes de la vidéo (GIF)",
"settings.form.videoPreview.label": "Aperçu",
"settings.header.label": "Médiathèque - Réglages",
"settings.section.image.label": "IMAGE",
"settings.section.video.label": "VIDÉO",
"settings.sub-header.label": "Configurer les paramètres de la médiathèque",
"sort.created_at_asc": "Importations les plus anciennes",
"sort.created_at_desc": "Importations les plus récentes",
"sort.label": "Trier par",
"sort.name_asc": "Ordre alphabétique (A à Z)",
"sort.name_desc": "Ordre alphabétique inversé (Z à A)",
"sort.updated_at_asc": "Modifications les plus anciennes",
"sort.updated_at_desc": "Modifications les plus récentes",
"window.confirm.close-modal.file": "Êtes-vous sûr ? Vos modifications seront perdues.",
"window.confirm.close-modal.files": "Êtes-vous sûr ? Certains fichiers n'ont pas encore été téléchargés."
}

View File

@ -1,5 +1,6 @@
import en from './en.json';
import es from './es.json';
import fr from './fr.json';
import he from './he.json';
import ja from './ja.json';
import ms from './ms.json';
@ -13,6 +14,7 @@ import zh from './zh.json';
const trads = {
en,
es,
fr,
he,
ja,
ms,

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-upload",
"version": "3.3.3",
"version": "3.3.4",
"description": "This is the description of the plugin.",
"strapi": {
"name": "Media Library",
@ -18,7 +18,7 @@
"@buffetjs/icons": "3.3.1",
"@buffetjs/styles": "3.3.1",
"@buffetjs/utils": "3.3.1",
"byte-size": "^6.2.0",
"byte-size": "^7.0.0",
"cropperjs": "^1.5.6",
"immer": "^7.0.14",
"immutable": "^3.8.2",
@ -36,9 +36,9 @@
"react-router-dom": "^5.0.0",
"reactstrap": "8.4.1",
"sharp": "0.26.2",
"strapi-helper-plugin": "3.3.3",
"strapi-provider-upload-local": "3.3.3",
"strapi-utils": "3.3.3",
"strapi-helper-plugin": "3.3.4",
"strapi-provider-upload-local": "3.3.4",
"strapi-utils": "3.3.4",
"stream-to-array": "^2.3.0",
"uuid": "^3.2.1"
},

View File

@ -1,6 +1,6 @@
{
"name": "strapi-plugin-users-permissions",
"version": "3.3.3",
"version": "3.3.4",
"description": "Protect your API with a full-authentication process based on JWT",
"strapi": {
"name": "Roles & Permissions",
@ -18,9 +18,9 @@
"@buffetjs/icons": "3.3.1",
"@buffetjs/styles": "3.3.1",
"@buffetjs/utils": "3.3.1",
"@purest/providers": "^1.0.1",
"@purest/providers": "^1.0.2",
"bcryptjs": "^2.4.3",
"grant-koa": "5.2.0",
"grant-koa": "5.4.8",
"immutable": "^3.8.2",
"jsonwebtoken": "^8.1.0",
"koa2-ratelimit": "^0.9.0",
@ -35,8 +35,8 @@
"reactstrap": "8.4.1",
"redux-saga": "^0.16.0",
"request": "^2.83.0",
"strapi-helper-plugin": "3.3.3",
"strapi-utils": "3.3.3",
"strapi-helper-plugin": "3.3.4",
"strapi-utils": "3.3.4",
"uuid": "^3.1.0"
},
"devDependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-email-amazon-ses",
"version": "3.3.3",
"version": "3.3.4",
"description": "Amazon SES provider for strapi email",
"homepage": "http://strapi.io",
"keywords": [
@ -14,8 +14,8 @@
},
"main": "./lib",
"dependencies": {
"node-ses": "^3.0.0",
"strapi-utils": "3.3.3"
"node-ses": "^3.0.3",
"strapi-utils": "3.3.4"
},
"author": {
"email": "nikolay@tsenkov.net",

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-email-mailgun",
"version": "3.3.3",
"version": "3.3.4",
"description": "Mailgun provider for strapi email plugin",
"homepage": "http://strapi.io",
"keywords": [
@ -14,7 +14,7 @@
"main": "./lib",
"dependencies": {
"mailgun-js": "0.22.0",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"strapi": {
"isProvider": true

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-email-nodemailer",
"version": "3.3.3",
"version": "3.3.4",
"description": "Nodemailer provider for Strapi 3",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-email-sendgrid",
"version": "3.3.3",
"version": "3.3.4",
"description": "Sendgrid provider for strapi email",
"homepage": "http://strapi.io",
"keywords": [
@ -14,7 +14,7 @@
"main": "./lib",
"dependencies": {
"@sendgrid/mail": "6.4.0",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"strapi": {
"isProvider": true

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-email-sendmail",
"version": "3.3.3",
"version": "3.3.4",
"description": "Sendmail provider for strapi email",
"homepage": "http://strapi.io",
"keywords": [
@ -13,7 +13,7 @@
"main": "./lib",
"dependencies": {
"sendmail": "^1.6.1",
"strapi-utils": "3.3.3"
"strapi-utils": "3.3.4"
},
"strapi": {
"isProvider": true

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-upload-aws-s3",
"version": "3.3.3",
"version": "3.3.4",
"description": "AWS S3 provider for strapi upload",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-upload-cloudinary",
"version": "3.3.3",
"version": "3.3.4",
"description": "Cloudinary provider for strapi upload",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-upload-local",
"version": "3.3.3",
"version": "3.3.4",
"description": "Local provider for strapi upload",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -1,6 +1,6 @@
{
"name": "strapi-provider-upload-rackspace",
"version": "3.3.3",
"version": "3.3.4",
"description": "Rackspace provider for strapi upload",
"main": "./lib",
"keywords": [],

View File

@ -1,6 +1,6 @@
{
"name": "strapi-utils",
"version": "3.3.3",
"version": "3.3.4",
"description": "Shared utilities for the Strapi packages",
"homepage": "http://strapi.io",
"keywords": [

View File

@ -64,7 +64,7 @@ program.helpOption('-h, --help', 'Display help for command');
program.addHelpCommand('help [command]', 'Display help for command');
// `$ strapi version` (--version synonym)
program.option('-v, --version', 'Output the version number');
program.version(packageJSON.version, '-v, --version', 'Output the version number');
program
.command('version')
.description('Output your version of Strapi')

View File

@ -1,6 +1,6 @@
{
"name": "strapi",
"version": "3.3.3",
"version": "3.3.4",
"description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MongoDB, MySQL, MariaDB, PostgreSQL, SQLite",
"homepage": "http://strapi.io",
"directories": {
@ -22,7 +22,7 @@
"cli-table3": "^0.6.0",
"commander": "6.1.0",
"configstore": "5.0.1",
"cross-spawn": "^6.0.5",
"cross-spawn": "^7.0.3",
"debug": "^4.1.1",
"delegates": "^1.0.0",
"dotenv": "8.2.0",
@ -35,7 +35,7 @@
"koa-body": "^4.2.0",
"koa-compose": "^4.1.0",
"koa-compress": "^5.0.1",
"koa-convert": "^1.2.0",
"koa-convert": "^2.0.0",
"koa-favicon": "^2.0.0",
"koa-i18n": "^2.1.0",
"koa-ip": "^2.0.0",
@ -54,17 +54,17 @@
"qs": "^6.9.3",
"resolve-cwd": "^3.0.0",
"rimraf": "^3.0.2",
"semver": "7.3.2",
"strapi-database": "3.3.3",
"strapi-generate": "3.3.3",
"strapi-generate-api": "3.3.3",
"strapi-generate-controller": "3.3.3",
"strapi-generate-model": "3.3.3",
"strapi-generate-new": "3.3.3",
"strapi-generate-plugin": "3.3.3",
"strapi-generate-policy": "3.3.3",
"strapi-generate-service": "3.3.3",
"strapi-utils": "3.3.3"
"semver": "7.3.4",
"strapi-database": "3.3.4",
"strapi-generate": "3.3.4",
"strapi-generate-api": "3.3.4",
"strapi-generate-controller": "3.3.4",
"strapi-generate-model": "3.3.4",
"strapi-generate-new": "3.3.4",
"strapi-generate-plugin": "3.3.4",
"strapi-generate-policy": "3.3.4",
"strapi-generate-service": "3.3.4",
"strapi-utils": "3.3.4"
},
"scripts": {
"postinstall": "node lib/utils/success.js"

919
yarn.lock

File diff suppressed because it is too large Load Diff