Merge branch 'main' into feature/relations-main-view

This commit is contained in:
Gustav Hansen 2022-08-22 09:28:39 +02:00
commit a024a40d1a
98 changed files with 2130 additions and 1369 deletions

View File

@ -28,7 +28,7 @@ module.exports = {
'no-use-before-define': 'warn',
'no-param-reassign': 'warn',
'no-continue': 'warn',
'no-process-exit': 'warn',
'no-process-exit': 'off',
'no-plusplus': 'warn',
'no-loop-func': 'warn',
'guard-for-in': 'warn',

View File

@ -13,7 +13,7 @@ https://guides.github.com/features/mastering-markdown/
Please ensure you have also read and understand the contributing guide.
https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md#reporting-an-issue
https://github.com/strapi/strapi/blob/main/CONTRIBUTING.md#reporting-an-issue
-->
## Bug report

View File

@ -8,7 +8,7 @@ To help us merge your PR, make sure to follow the instructions below:
- Refer to the issue you are closing in the PR description: Fix #issue
- Specify if the PR is ready to be merged or work in progress (by opening a draft PR)
Please ensure you read the Contributing Guide: https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md
Please ensure you read the Contributing Guide: https://github.com/strapi/strapi/blob/main/CONTRIBUTING.md
-->
### What does it do?

View File

@ -1,6 +1,6 @@
# PR checker for status
This action checks a PR labels, milestone and status to validate it is ready for merging into master.
This action checks a PR labels, milestone and status to validate it is ready for merging into main.
> ❗️ When making changes to this code, make sure to run the build before committing. See [Development](#development) to know more.

View File

@ -9,7 +9,7 @@
"watch": "NODE_ENV=production ncc build index.js -w -o dist --minify"
},
"devDependencies": {
"@actions/core": "1.9.0",
"@actions/core": "1.9.1",
"@actions/github": "5.0.0",
"@vercel/ncc": "0.34.0"
}

View File

@ -9,7 +9,7 @@ on:
- labeled
- unlabeled
branches:
- master
- main
jobs:
check-pr-status:

23
.github/workflows/nightly.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: 'Nightly Releases'
on:
schedule:
- cron: '0 0 * * 2-6'
workflow_dispatch:
jobs:
publish:
name: 'Publish'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup npmrc
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
- uses: actions/setup-node@v3
with:
node-version: 16
- run: yarn
- run: ./scripts/pre-publish.sh --yes
env:
VERSION: '0.0.0-${{ github.sha }}'
DIST_TAG: experimental

44
.github/workflows/pages.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Deploy static content to Pages
on:
push:
branches:
- 'main'
workflow_dispatch:
concurrency:
group: 'pages'
cancel-in-progress: true
defaults:
run:
working-directory: docs
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/build
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

View File

@ -3,7 +3,7 @@ name: 'Tests'
on:
push:
branches:
- master
- main
pull_request:
jobs:

View File

@ -1,10 +0,0 @@
trigger_deploy:
stage: deploy
script:
- curl -X POST
--form "token=$TRIGGER_TOKEN"
--form "ref=master"
--form "variables[UPSTREAM_COMMIT_SHA]=$CI_COMMIT_SHA"
https://gitlab.com/api/v4/projects/12825884/trigger/pipeline
only:
- develop

View File

@ -1,6 +1,6 @@
# Contribute to Strapi
Strapi is an open-source project administered by [the Strapi team](https://strapi.io/about-us). We appreciate your interest and efforts to contribute to Strapi. See the [LICENSE](https://github.com/strapi/strapi/blob/master/LICENSE) licensing information. All work done is available on GitHub.
Strapi is an open-source project administered by [the Strapi team](https://strapi.io/about-us). We appreciate your interest and efforts to contribute to Strapi. See the [LICENSE](https://github.com/strapi/strapi/blob/main/LICENSE) licensing information. All work done is available on GitHub.
We highly appreciate your effort to contribute, but we recommend you talk to a maintainer before spending a lot of time making a pull request that may not align with the project roadmap. Whether it is from Strapi or contributors, every pull request goes through the same process.
@ -51,7 +51,7 @@ The Strapi core team will review your pull request and either merge it, request
**Before submitting your pull request** make sure the following requirements are fulfilled:
- Fork the repository and create your new branch from `master`.
- Fork the repository and create your new branch from `main`.
- Run `yarn setup` in the root of the repository.
- If you've fixed a bug or added code that should be tested, please make sure to add tests
- Ensure the following test suites are passing:

View File

@ -17,11 +17,14 @@
<img src="https://img.shields.io/npm/v/@strapi/strapi/latest.svg" alt="NPM Version" />
</a>
<a href="https://github.com/strapi/strapi/actions/workflows/tests.yml">
<img src="https://github.com/strapi/strapi/actions/workflows/tests.yml/badge.svg?branch=master" alt="Tests" />
<img src="https://github.com/strapi/strapi/actions/workflows/tests.yml/badge.svg?branch=main" alt="Tests" />
</a>
<a href="https://discord.strapi.io">
<img src="https://img.shields.io/discord/811989166782021633?label=Discord" alt="Strapi on Discord" />
</a>
<a href="https://github.com/strapi/strapi/actions/workflows/nightly.yml">
<img src="https://github.com/strapi/strapi/actions/workflows/nightly.yml/badge.svg" alt="Strapi Nightly Release Build Status" />
</a>
</p>
<br>

View File

@ -1,7 +1,6 @@
comment:
branches:
- master
- develop
- main
github_checks:
annotations: false

View File

@ -9,12 +9,13 @@ const config = {
title: 'Doc',
tagline: 'Dinosaurs are cool',
url: 'https://your-docusaurus-test-site.com',
baseUrl: '/',
baseUrl: '/strapi/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'strapi',
projectName: 'strapi',
trailingSlash: false,
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
@ -32,7 +33,7 @@ const config = {
docs: {
routeBasePath: '/',
sidebarPath: require.resolve('./sidebars.js'),
// editUrl: 'https://github.com/strapi/strapi/tree/master/docs//docs',
// editUrl: 'https://github.com/strapi/strapi/tree/main/docs//docs',
},
blog: false,
},

View File

@ -14,8 +14,8 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.0.0-beta.21",
"@docusaurus/preset-classic": "2.0.0-beta.21",
"@docusaurus/core": "2.0.1",
"@docusaurus/preset-classic": "2.0.1",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.3.3",

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
'use strict';
/**
* `test-middleware` middleware.
* `test-middleware` middleware
*/
module.exports = (config, { strapi }) => {

View File

@ -1,7 +1,7 @@
'use strict';
/**
* `test-policy` policy.
* `test-policy` policy
*/
module.exports = (policyCtx, config, { strapi }) => {

View File

@ -67,9 +67,6 @@
"eslint --fix"
]
},
"dependencies": {
"@babel/polyfill": "7.12.1"
},
"devDependencies": {
"@babel/core": "7.18.10",
"@babel/eslint-parser": "7.18.9",
@ -77,10 +74,6 @@
"@strapi/eslint-config": "0.1.1",
"@swc/core": "1.2.224",
"@swc/jest": "0.2.22",
"@testing-library/react": "11.2.7",
"@testing-library/react-hooks": "3.7.0",
"@testing-library/user-event": "13.5.0",
"axios-mock-adapter": "1.20.0",
"babel-eslint": "10.1.0",
"chalk": "4.1.2",
"chokidar": "3.5.3",
@ -98,16 +91,14 @@
"jest-circus": "26.6.3",
"jest-cli": "26.6.3",
"jest-watch-typeahead": "0.6.5",
"lerna": "5.1.6",
"lerna": "5.4.3",
"lint-staged": "10.5.4",
"lodash": "4.17.21",
"msw": "0.42.3",
"npm-run-all": "4.1.5",
"nx": "14.4.2",
"plop": "2.7.6",
"prettier": "2.7.1",
"qs": "6.11.0",
"react-test-renderer": "17.0.2",
"request": "2.88.2",
"request-promise-native": "1.0.9",
"rimraf": "3.0.2",

View File

@ -1,8 +1,5 @@
'use strict';
// needed for regenerator-runtime
require('@babel/polyfill');
const noop = () => {};
// eslint-disable-next-line no-undef
Object.defineProperty(window, 'scrollTo', { value: noop, writable: true });

View File

@ -17,12 +17,14 @@
}
],
"main": "lib/index.js",
"dependencies": {
"@babel/polyfill": "7.12.1"
},
"devDependencies": {
"@testing-library/jest-dom": "5.16.5",
"jest-styled-components": "7.0.2"
"jest-styled-components": "7.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-is": "^17.0.2",
"styled-components": "5.3.3",
"redux": "^4.0.1"
},
"peerDependencies": {
"redux": "^4.0.1"

View File

@ -1,5 +1,5 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useIntl } from 'react-intl';
import useLocalesProvider from '../../LocalesProvider/useLocalesProvider';
@ -29,7 +29,7 @@ describe('LanguageProvider', () => {
`);
});
it('should change the locale and set the strapi-admin-language item in the localStorage', () => {
it('should change the locale and set the strapi-admin-language item in the localStorage', async () => {
const Test = () => {
const { locale } = useIntl();
const { changeLocale } = useLocalesProvider();
@ -54,7 +54,9 @@ describe('LanguageProvider', () => {
expect(screen.getByText('English')).toBeInTheDocument();
userEvent.click(screen.getByText('CHANGE'));
act(() => {
userEvent.click(screen.getByText('CHANGE'));
});
expect(screen.getByText('Français')).toBeInTheDocument();
expect(localStorage.getItem('strapi-admin-language')).toEqual('fr');

View File

@ -1,4 +1,8 @@
import React from 'react';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { Typography } from '@strapi/design-system/Typography';
import { Tbody, Tr, Td } from '@strapi/design-system/Table';
import { Flex } from '@strapi/design-system/Flex';
@ -9,9 +13,7 @@ import {
pxToRem,
useTracking,
} from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import DeleteButton from './DeleteButton';
import UpdateButton from './UpdateButton';

View File

@ -1,5 +1,9 @@
import React, { useEffect, useRef } from 'react';
import { useIntl } from 'react-intl';
import { useQuery, useMutation, useQueryClient } from 'react-query';
import { useHistory } from 'react-router-dom';
import qs from 'qs';
import {
SettingsPageTitle,
useFocusWhenNavigate,
@ -16,9 +20,7 @@ import { HeaderLayout, ContentLayout } from '@strapi/design-system/Layout';
import { Main } from '@strapi/design-system/Main';
import { Button } from '@strapi/design-system/Button';
import Plus from '@strapi/icons/Plus';
import { useQuery, useMutation, useQueryClient } from 'react-query';
import { useHistory } from 'react-router-dom';
import qs from 'qs';
import { axiosInstance } from '../../../../../core/utils';
import adminPermissions from '../../../../../permissions';
import tableHeaders from './utils/tableHeaders';

View File

@ -1,9 +1,11 @@
import React from 'react';
import { IntlProvider } from 'react-intl';
import { render as renderTL, fireEvent, screen, waitFor } from '@testing-library/react';
import { render as renderTL, fireEvent, screen, waitFor, configure } from '@testing-library/react';
import { ThemeProvider, lightTheme } from '@strapi/design-system';
import LogoInput from '../index';
configure({ asyncUtilTimeout: 8000 });
const getFakeSize = jest.fn(() => ({
width: 500,
height: 500,
@ -28,7 +30,7 @@ const render = (props) =>
<LogoInput
{...props}
defaultLogo="/admin/defaultLogo.png"
onChangeLogo={() => jest.fn()}
onChangeLogo={jest.fn()}
onResetMenuLogo={jest.fn()}
/>
</IntlProvider>
@ -172,7 +174,7 @@ describe('ApplicationsInfosPage || LogoInput', () => {
it('should show error message when uploading wrong file format', async () => {
render();
const changeLogoButton = document.querySelector('button');
const changeLogoButton = screen.getByRole('button');
fireEvent.click(changeLogoButton);
fireEvent.click(screen.getByText('From url'));
@ -247,8 +249,11 @@ describe('ApplicationsInfosPage || LogoInput', () => {
it('should accept upload and lead user to next modal', async () => {
render();
const changeLogoButton = document.querySelector('button');
fireEvent.click(changeLogoButton);
fireEvent.click(screen.getByText('From url'));
const textInput = document.querySelector('input[name="logo-url"]');

View File

@ -47,11 +47,11 @@ describe('SSO', () => {
});
describe('Get Strategy Callback URL', () => {
const BASE_URL = '/admin/connect/{{provider}}';
const BASE_URL = '/admin/connect/{{ provider }}';
test.each(['foo', 'bar', 'foobar'])('Get a correct callback url for %s', (providerName) => {
expect(getStrategyCallbackURL(providerName)).toBe(
BASE_URL.replace('{{provider}}', providerName)
BASE_URL.replace('{{ provider }}', providerName)
);
});
});

View File

@ -39,14 +39,13 @@
"dependencies": {
"@babel/core": "7.18.10",
"@babel/plugin-transform-runtime": "7.18.10",
"@babel/polyfill": "7.12.1",
"@babel/preset-env": "7.18.10",
"@babel/preset-react": "7.18.6",
"@babel/runtime": "7.18.9",
"@casl/ability": "^5.4.3",
"@fingerprintjs/fingerprintjs": "3.3.3",
"@fortawesome/fontawesome-free": "^5.15.3",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/fontawesome-svg-core": "6.1.2",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.2.0",
@ -57,7 +56,7 @@
"@strapi/icons": "1.2.1",
"@strapi/typescript-utils": "4.3.4",
"@strapi/utils": "4.3.4",
"axios": "0.24.0",
"axios": "0.27.2",
"babel-loader": "8.2.5",
"babel-plugin-styled-components": "2.0.2",
"bcryptjs": "2.4.3",
@ -66,7 +65,7 @@
"codemirror": "^5.65.6",
"cross-env": "^7.0.3",
"css-loader": "6.7.1",
"date-fns": "2.28.0",
"date-fns": "2.29.2",
"dotenv": "8.5.1",
"esbuild-loader": "^2.19.0",
"execa": "^1.0.0",
@ -100,7 +99,7 @@
"markdown-it-sup": "1.0.0",
"match-sorter": "^4.0.2",
"mini-css-extract-plugin": "2.4.4",
"node-polyfill-webpack-plugin": "1.1.4",
"node-polyfill-webpack-plugin": "2.0.1",
"p-map": "4.0.0",
"passport-local": "1.0.0",
"prop-types": "^15.7.2",
@ -114,6 +113,7 @@
"react-fast-compare": "^3.2.0",
"react-helmet": "^6.1.0",
"react-intl": "5.20.2",
"react-is": "^17.0.2",
"react-query": "3.24.3",
"react-redux": "7.2.8",
"react-refresh": "0.11.0",
@ -123,11 +123,12 @@
"redux": "^4.0.1",
"reselect": "^4.0.0",
"rimraf": "3.0.2",
"sanitize-html": "2.7.0",
"sanitize-html": "2.7.1",
"semver": "7.3.7",
"sift": "13.5.4",
"style-loader": "3.3.1",
"styled-components": "5.3.3",
"typescript": "4.6.2",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.3",
@ -135,13 +136,18 @@
"yup": "^0.32.9"
},
"devDependencies": {
"@testing-library/dom": "8.17.1",
"@testing-library/react": "11.2.7",
"@testing-library/react-hooks": "3.7.0",
"@testing-library/user-event": "13.5.0",
"react-test-renderer": "^17.0.2",
"duplicate-dependencies-webpack-plugin": "^1.0.2",
"glob": "8.0.3",
"speed-measure-webpack-plugin": "1.5.0",
"webpack-bundle-analyzer": "^4.5.0"
},
"peerDependencies": {
"@strapi/strapi": "4.3.2"
"@strapi/strapi": "^4.3.4"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",

View File

@ -49,11 +49,6 @@ module.exports = ({
]
: [];
// Directly inject a polyfill in the webpack entry point before the entry point
// FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
// The only I could fix it was to inject the babel polyfill
const babelPolyfill = '@babel/polyfill/dist/polyfill.min.js';
return {
mode: isProduction ? 'production' : 'development',
bail: !!isProduction,
@ -61,7 +56,7 @@ module.exports = ({
experiments: {
topLevelAwait: true,
},
entry: [babelPolyfill, entry],
entry: [entry],
output: {
path: dest,
publicPath: options.adminPath,

View File

@ -12,7 +12,7 @@ async function validateCustomConfig(schema) {
}).validate(schema.config);
} catch (error) {
throw new Error(
`Invalid Model configuration for model ${schema.uid}. Verify your {{modelName}}.config.js(on) file:\n - ${error.message}\n`
`Invalid Model configuration for model ${schema.uid}. Verify your {{ modelName }}.config.js(on) file:\n - ${error.message}\n`
);
}
}

View File

@ -44,6 +44,9 @@
"reselect": "^4.0.0",
"yup": "^0.32.9"
},
"devDependencies": {
"@testing-library/react": "12.1.4"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",
"npm": ">=6.0.0"

View File

@ -31,7 +31,7 @@
"test:unit": "jest --verbose"
},
"dependencies": {
"date-fns": "2.28.0",
"date-fns": "2.29.2",
"debug": "4.3.1",
"fs-extra": "10.0.0",
"knex": "1.0.7",

View File

@ -31,7 +31,8 @@
"lodash": "4.17.21"
},
"devDependencies": {
"@strapi/helper-plugin": "4.3.4"
"@strapi/helper-plugin": "4.3.4",
"@testing-library/react": "12.1.4"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",

View File

@ -40,15 +40,18 @@
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.2",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/fontawesome-svg-core": "6.1.2",
"@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.2.0",
"axios": "0.25.0",
"formik": "2.2.9",
"axios": "0.27.2",
"date-fns": "2.29.2",
"formik": "^2.2.6",
"immer": "9.0.6",
"invariant": "^2.2.1",
"lodash": "4.17.21",
"match-sorter": "^4.0.2",
"qs": "6.10.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
@ -68,6 +71,8 @@
"@babel/preset-env": "7.18.10",
"@babel/preset-react": "7.18.6",
"@babel/runtime": "7.18.9",
"@testing-library/react": "11.2.7",
"@testing-library/react-hooks": "3.7.0",
"@storybook/addon-actions": "6.5.10",
"@storybook/addon-essentials": "6.5.9",
"@storybook/addon-links": "6.5.9",
@ -78,14 +83,10 @@
"@strapi/icons": "1.2.1",
"babel-loader": "^8.2.5",
"cross-env": "^7.0.3",
"date-fns": "2.28.0",
"rimraf": "3.0.2"
},
"peerDependencies": {
"formik": "^2.2.6",
"immer": "9.0.6",
"qs": "6.10.1",
"react-select": "^4.0.2"
"react-test-renderer": "^17.0.2",
"require-from-string": "2.0.2",
"rimraf": "3.0.2",
"typescript": "4.6.2"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",

View File

@ -4,9 +4,9 @@ const packageJson = require('./package.json');
const nodeModules = [];
[
...Object.keys(packageJson.dependencies),
...Object.keys(packageJson.peerDependencies),
...Object.keys(packageJson.devDependencies),
...Object.keys(packageJson.dependencies || {}),
...Object.keys(packageJson.peerDependencies || {}),
...Object.keys(packageJson.devDependencies || {}),
].forEach((module) => {
nodeModules.push(new RegExp(`^${module}(/.+)?$`));
});

View File

@ -13,7 +13,7 @@
<img src="https://img.shields.io/npm/v/@strapi/strapi/latest.svg" alt="NPM Version" />
</a>
<a href="https://github.com/strapi/strapi/actions/workflows/tests.yml">
<img src="https://github.com/strapi/strapi/actions/workflows/tests.yml/badge.svg?branch=master" alt="Tests" />
<img src="https://github.com/strapi/strapi/actions/workflows/tests.yml/badge.svg?branch=main" alt="Tests" />
</a>
<a href="https://discord.strapi.io">
<img src="https://img.shields.io/discord/811989166782021633?label=Discord" alt="Strapi on Discord" />

View File

@ -23,12 +23,16 @@ function getFiles(ctx) {
/**
* @type {import('./').MiddlewareFactory}
*/
module.exports = (config) => {
module.exports = (config, { strapi }) => {
const bodyConfig = defaultsDeep(defaults, config);
const { config: gqlConfig } = strapi.plugin('graphql');
const gqlEndpoint = gqlConfig('endpoint');
return async (ctx, next) => {
// TODO: find a better way later
if (ctx.url === '/graphql') {
if (ctx.url === gqlEndpoint) {
await next();
} else {
try {

View File

@ -30,22 +30,27 @@ const defaults = {
/**
* @type {import('./').MiddlewareFactory}
*/
module.exports = (config) => (ctx, next) => {
let helmetConfig = defaultsDeep(defaults, config);
if (
ctx.method === 'GET' &&
['/graphql', '/documentation'].some((str) => ctx.path.startsWith(str))
) {
helmetConfig = merge(helmetConfig, {
contentSecurityPolicy: {
directives: {
'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
'img-src': ["'self'", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],
module.exports =
(config, { strapi }) =>
(ctx, next) => {
let helmetConfig = defaultsDeep(defaults, config);
const { config: gqlConfig } = strapi.plugin('graphql');
const gqlEndpoint = gqlConfig('endpoint');
if (
ctx.method === 'GET' &&
[gqlEndpoint, '/documentation'].some((str) => ctx.path.startsWith(str))
) {
helmetConfig = merge(helmetConfig, {
contentSecurityPolicy: {
directives: {
'script-src': ["'self'", "'unsafe-inline'", 'cdn.jsdelivr.net'],
'img-src': ["'self'", 'data:', 'cdn.jsdelivr.net', 'strapi.io'],
},
},
},
});
}
});
}
return helmet(helmetConfig)(ctx, next);
};
return helmet(helmetConfig)(ctx, next);
};

View File

@ -114,7 +114,7 @@
"koa-compress": "5.1.0",
"koa-favicon": "2.1.0",
"koa-helmet": "6.1.0",
"koa-ip": "2.1.0",
"koa-ip": "^2.1.2",
"koa-session": "6.2.0",
"koa-static": "5.0.0",
"lodash": "4.17.21",

View File

@ -161,7 +161,7 @@ describe('UploadAssetDialog', () => {
const assets = [
{
name: 'http://localhost:5000/an-image.png',
name: 'an-image.png',
ext: 'png',
mime: 'image/png',
source: 'url',
@ -170,7 +170,7 @@ describe('UploadAssetDialog', () => {
rawFile: new File([''], 'image/png'),
},
{
name: 'http://localhost:5000/a-pdf.pdf',
name: 'a-pdf.pdf',
ext: 'pdf',
mime: 'application/pdf',
source: 'url',
@ -179,7 +179,7 @@ describe('UploadAssetDialog', () => {
rawFile: new File([''], 'application/pdf'),
},
{
name: 'http://localhost:5000/a-video.mp4',
name: 'a-video.mp4',
ext: 'mp4',
mime: 'video/mp4',
source: 'url',
@ -188,7 +188,7 @@ describe('UploadAssetDialog', () => {
rawFile: new File([''], 'video/mp4'),
},
{
name: 'http://localhost:5000/not-working-like-cors.lutin',
name: 'not-working-like-cors.lutin',
ext: 'lutin',
mime: 'application/json',
source: 'url',

View File

@ -2,6 +2,10 @@ import axios from 'axios';
import { AssetSource } from '../constants';
import { typeFromMime } from './typeFromMime';
function getFilenameFromURL(url) {
return new URL(url).pathname.split('/').pop();
}
export const urlsToAssets = async (urls) => {
const assetPromises = urls.map((url) =>
axios
@ -10,7 +14,7 @@ export const urlsToAssets = async (urls) => {
timeout: 60000,
})
.then((res) => {
const loadedFile = new File([res.data], res.config.url, {
const loadedFile = new File([res.data], getFilenameFromURL(res.config.url), {
type: res.headers['content-type'],
});

View File

@ -28,7 +28,7 @@
"@strapi/utils": "4.3.4",
"byte-size": "7.0.1",
"cropperjs": "1.5.12",
"date-fns": "2.28.0",
"date-fns": "2.29.2",
"fs-extra": "10.0.0",
"immer": "9.0.15",
"koa-range": "0.3.0",
@ -44,6 +44,14 @@
"react-router-dom": "5.2.0",
"sharp": "0.30.7"
},
"devDependencies": {
"@testing-library/dom": "8.17.1",
"@testing-library/react": "11.2.7",
"@testing-library/react-hooks": "3.7.0",
"@testing-library/user-event": "13.5.0",
"msw": "0.42.3",
"react-test-renderer": "^17.0.2"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",
"npm": ">=6.0.0"

View File

@ -12,6 +12,7 @@ const crypto = require('crypto');
const fs = require('fs');
const fse = require('fs-extra');
const _ = require('lodash');
const { extension } = require('mime-types');
const {
sanitize,
nameToSlug,
@ -72,7 +73,10 @@ module.exports = ({ strapi }) => ({
async formatFileInfo({ filename, type, size }, fileInfo = {}, metas = {}) {
const fileService = getService('file');
const ext = path.extname(filename);
let ext = path.extname(filename);
if (!ext) {
ext = `.${extension(type)}`;
}
const basename = path.basename(fileInfo.name || filename, ext);
const usedName = fileInfo.name || filename;
@ -190,37 +194,47 @@ module.exports = ({ strapi }) => ({
// Store width and height of the original image
const { width, height } = await getDimensions(fileData);
// Make sure this is assigned before calling upload
// Make sure this is assigned before calling any upload
// That way it can mutate the width and height
_.assign(fileData, {
width,
height,
});
// Upload image
await getService('provider').upload(fileData);
// For performance reasons, all uploads are wrapped in a single Promise.all
const uploadThumbnail = async (thumbnailFile) => {
await getService('provider').upload(thumbnailFile);
_.set(fileData, 'formats.thumbnail', thumbnailFile);
};
// Generate thumbnail and responsive formats
const uploadResponsiveFormat = async (format) => {
const { key, file } = format;
await getService('provider').upload(file);
_.set(fileData, ['formats', key], file);
};
const uploadPromises = [];
// Upload image
uploadPromises.push(getService('provider').upload(fileData));
// Generate & Upload thumbnail and responsive formats
if (await isOptimizableImage(fileData)) {
const thumbnailFile = await generateThumbnail(fileData);
if (thumbnailFile) {
await getService('provider').upload(thumbnailFile);
_.set(fileData, 'formats.thumbnail', thumbnailFile);
uploadPromises.push(uploadThumbnail(thumbnailFile));
}
const formats = await generateResponsiveFormats(fileData);
if (Array.isArray(formats) && formats.length > 0) {
for (const format of formats) {
if (!format) continue;
const { key, file } = format;
await getService('provider').upload(file);
_.set(fileData, ['formats', key], file);
uploadPromises.push(uploadResponsiveFormat(format));
}
}
}
// Wait for all uploads to finish
await Promise.all(uploadPromises);
},
/**

View File

@ -1,10 +1,7 @@
# strapi-utils
[![npm version](https://img.shields.io/npm/v/strapi-utils.svg)](https://www.npmjs.org/package/strapi-utils)
[![npm downloads](https://img.shields.io/npm/dm/strapi-utils.svg)](https://www.npmjs.org/package/strapi-utils)
[![npm dependencies](https://david-dm.org/strapi/strapi-utils.svg)](https://david-dm.org/strapi/strapi-utils)
[![Build status](https://travis-ci.org/strapi/strapi-utils.svg?branch=master)](https://travis-ci.org/strapi/strapi-utils)
[![Slack status](https://slack.strapi.io/badge.svg)](https://slack.strapi.io)
[![npm version](https://img.shields.io/npm/v/@strapi/utils.svg)](https://www.npmjs.org/package/@strapi/utils)
[![npm downloads](https://img.shields.io/npm/dm/@strapi/utils.svg)](https://www.npmjs.org/package/@strapi/utils)
Shared utilities between Strapi packages.

View File

@ -36,7 +36,7 @@
},
"dependencies": {
"@sindresorhus/slugify": "1.1.0",
"date-fns": "2.28.0",
"date-fns": "2.29.2",
"http-errors": "1.8.1",
"lodash": "4.17.21",
"yup": "0.32.9"

View File

@ -63,7 +63,7 @@ const actions = (answers) => {
answers.plugin = plugin;
const templatesFolder = 'component/templates';
const pattern = useRedux ? '**/**.hbs' : '**/index.*.hbs';
const path = join(packagesFolder, pluginFolder, '{{plugin}}/admin/src/components/{{name}}');
const path = join(packagesFolder, pluginFolder, '{{ plugin }}/admin/src/components/{{ name }}');
return [
{
type: 'addMany',

View File

@ -1,6 +1,6 @@
/**
*
* {{name}} actions
* {{ name }} actions
*
*/

View File

@ -1,8 +1,8 @@
/**
*
* {{name}} constants
* {{ name }} constants
*
*/
// eslint-disable-next-line import/prefer-default-export
export const DEFAULT_ACTION = '{{plugin}}/{{name}}/DEFAULT_ACTION';
export const DEFAULT_ACTION = '{{ plugin }}/{{ name }}/DEFAULT_ACTION';

View File

@ -3,7 +3,7 @@
{{else}}
/**
*
* {{name}}
* {{ name }}
*
*/
@ -17,22 +17,22 @@
{{/if}}
{{#if useRedux}}
import { useDispatch, useSelector } from 'react-redux';
import { select{{name}}Domain } from './selectors';
import { select{{ name }}Domain } from './selectors';
import { defaultAction } from './actions';
{{/if}}
{{/if}}
{{#if styled}}
const {{name}} = styled.{{ htmlTag }}``;
const {{ name }} = styled.{{ htmlTag }}``;
{{else}}
const {{name}} = () => {
const {{ name }} = () => {
{{#if useI18n}}
const { formatMessage } = useIntl();
{{/if}}
{{#if useRedux}}
const dispatch = useDispatch();
// eslint-disable-next-line no-unused-vars
const state = useSelector(select{{name}}Domain);
const state = useSelector(select{{ name }}Domain);
const handleClick = () => dispatch(defaultAction())
{{/if}}
@ -55,7 +55,7 @@
);
};
{{name}}.propTypes = {};
{{ name }}.propTypes = {};
{{/if}}
export default {{name}};
export default {{ name }};

View File

@ -1,6 +1,6 @@
/*
*
* {{name}} reducer
* {{ name }} reducer
*
*/
@ -9,7 +9,7 @@ import { DEFAULT_ACTION } from './constants';
export const initialState = {};
const {{camelCase name}}Reducer = (state = initialState, action) =>
const {{ camelCase name }}Reducer = (state = initialState, action) =>
// eslint-disable-next-line consistent-return
produce(state, draftState => {
switch (action.type) {
@ -21,4 +21,4 @@ const {{camelCase name}}Reducer = (state = initialState, action) =>
}
});
export default {{camelCase name}}Reducer;
export default {{ camelCase name }}Reducer;

View File

@ -4,14 +4,14 @@ import { initialState } from './reducer';
{{/unless}}
/**
* Direct selector to the {{name}} state domain
* Direct selector to the {{ name }} state domain
*/
// eslint-disable-next-line import/prefer-default-export
export const select{{name}}Domain = state => state[`
export const select{{ name }}Domain = state => state[`
{{~#if plugin "===" "admin"~}}
{{plugin}}
{{ plugin }}
{{~else~}}
${pluginId}
{{~/if~}}
_{{camelCase name}}`] || initialState;
_{{ camelCase name }}`] || initialState;

View File

@ -1,7 +1,7 @@
import { defaultAction } from '../actions';
import { DEFAULT_ACTION } from '../constants';
describe('{{plugin}} | components | {{name}} actions', () => {
describe('{{ plugin }} | components | {{ name }} actions', () => {
describe('Default Action', () => {
it('has a type of DEFAULT_ACTION', () => {
const expected = {

View File

@ -1,6 +1,6 @@
/**
*
* Tests for {{name}}
* Tests for {{ name }}
*
*/
@ -16,7 +16,7 @@ import { ThemeProvider, lightTheme } from '@strapi/design-system';
{{#if useI18n}}
import { IntlProvider } from 'react-intl';
{{/if}}
import {{name}} from '../index';
import {{ name }} from '../index';
{{#if useRedux}}
const rootReducer = combineReducers(reducers);
@ -25,7 +25,7 @@ import {{name}} from '../index';
ui,
{
preloadedState = initialState,
store = createStore(rootReducer, { '{{plugin}}_{{camelCase name}}': preloadedState }),
store = createStore(rootReducer, { '{{ plugin }}_{{ camelCase name }}': preloadedState }),
...renderOptions
} = {},
) => {
@ -40,11 +40,11 @@ import {{name}} from '../index';
{{/if}}
{{#if useI18n}}
const messages = {
'{{plugin}}.component.name': '{{titleCase name}}',
'{{ plugin }}.component.name': '{{titleCase name}}',
};
{{/if}}
describe('<{{name}} />', () => {
describe('<{{ name }} />', () => {
it('renders and matches the snapshot', () => {
const {
container: { firstChild },
@ -52,12 +52,12 @@ describe('<{{name}} />', () => {
{{#if useI18n}}
<ThemeProvider theme={lightTheme}>
<IntlProvider locale="en" messages={messages} defaultLocale="en">
<{{name}} />
<{{ name }} />
</IntlProvider>
</ThemeProvider>
{{else}}
<ThemeProvider theme={lightTheme}>
<{{name}} />
<{{ name }} />
</ThemeProvider>
{{/if}}
);

View File

@ -1,21 +1,21 @@
// import produce from 'immer';
import {{camelCase name}}Reducer, { initialState } from '../reducer';
import {{ camelCase name }}Reducer, { initialState } from '../reducer';
import { fixtures } from '../../../../../../../admin-test-utils';
// import { someAction } from '../actions';
/* eslint-disable default-case, no-param-reassign */
describe('{{camelCase name}}Reducer', () => {
describe('{{ camelCase name }}Reducer', () => {
let state;
beforeEach(() => {
state = {
...fixtures.store.state,
'{{plugin}}_{{camelCase name}}': initialState,
'{{ plugin }}_{{ camelCase name }}': initialState,
};
});
it('returns the initial state', () => {
const expectedResult = state['{{plugin}}_{{camelCase name}}'];
const expectedResult = state['{{ plugin }}_{{ camelCase name }}'];
expect({{camelCase name}}Reducer(undefined, {})).toEqual(expectedResult);
expect({{ camelCase name }}Reducer(undefined, {})).toEqual(expectedResult);
});
});

View File

@ -1,17 +1,17 @@
import { fixtures } from '../../../../../../../admin-test-utils';
import { select{{name}}Domain } from '../selectors';
import { select{{ name }}Domain } from '../selectors';
describe('select{{name}}Domain', () => {
describe('select{{ name }}Domain', () => {
let store;
beforeEach(() => {
store = { ...fixtures.store.state, '{{plugin}}_{{camelCase name}}': {} };
store = { ...fixtures.store.state, '{{ plugin }}_{{ camelCase name }}': {} };
});
it('expects to have unit tests specified', () => {
const actual = select{{name}}Domain(store);
const actual = select{{ name }}Domain(store);
// TBC
expect(actual).toEqual(store['{{plugin}}_{{camelCase name}}']);
expect(actual).toEqual(store['{{ plugin }}_{{ camelCase name }}']);
});
});

View File

@ -43,7 +43,7 @@ module.exports = (opts) => {
...packageJsonStrapi,
},
engines: {
node: '>=12.x.x <=16.x.x',
node: '>=14.19.1 <=16.x.x',
npm: '>=6.0.0',
},
license: 'MIT',

View File

@ -9,8 +9,12 @@ module.exports = () => ({
},
include: [
// Include the root directory
// Include root files
'./',
// Include all ts files
'./**/*.ts',
// Include all js files
'./**/*.js',
// Force the JSON files in the src folder to be included
'src/**/*.json',
],
@ -25,7 +29,7 @@ module.exports = () => ({
// Do not include admin files in the server compilation
'src/admin/',
// Do not include test files
'**/*.test.ts',
'**/*.test.*',
// Do not include plugins in the server compilation
'src/plugins/**',
],

View File

@ -1,14 +1,28 @@
'use strict';
const { red, green, bold, yellow } = require('chalk');
const semver = require('semver');
const packageJSON = require('../resources/json/common/package.json');
module.exports = function checkBeforeInstall() {
const currentNodeVersion = process.versions.node;
const semver = currentNodeVersion.split('.');
const major = semver[0];
const { engines } = packageJSON({ strapiDependencies: [] });
if (major < 12) {
console.error(`You are running Node ${currentNodeVersion}`);
console.error('Strapi requires Node 12 and higher.');
// error if the node version isn't supported
if (!semver.satisfies(currentNodeVersion, engines.node)) {
console.error(red(`You are running ${bold(`Node.js ${currentNodeVersion}`)}`));
console.error(`Strapi requires ${bold(green(`Node.js ${engines.node}`))}`);
console.error('Please make sure to use the right version of Node.');
process.exit(1);
}
// warn if not using a LTS version
else if (semver.satisfies(currentNodeVersion, '15.x.x || 17.x.x || 19.x.x')) {
console.warn(yellow(`You are running ${bold(`Node.js ${currentNodeVersion}`)}`));
console.warn(
`Strapi only supports ${bold(
green('LTS versions of Node.js')
)}, other versions may not be compatible.`
);
}
};

View File

@ -46,6 +46,7 @@
"node-machine-id": "^1.1.10",
"ora": "^5.4.1",
"tar": "6.1.11",
"semver": "^7.3.4",
"uuid": "^8.3.2"
},
"engines": {

View File

@ -1,4 +1,4 @@
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// bootstrap phase

View File

@ -1,4 +1,4 @@
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => ({
index(ctx) {

View File

@ -1,4 +1,4 @@
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// destroy phase

View File

@ -1,4 +1,4 @@
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => {
// registeration phase

View File

@ -1,4 +1,4 @@
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default ({ strapi }: { strapi: Strapi }) => ({
getWelcomeMessage() {

View File

@ -47,19 +47,20 @@ module.exports = (plop) => {
},
],
actions(answers) {
const filePath = answers.isPluginApi && answers.plugin ? 'plugins/{{plugin}}' : 'api/{{id}}';
const filePath =
answers.isPluginApi && answers.plugin ? 'plugins/{{ plugin }}' : 'api/{{ id }}';
const currentDir = process.cwd();
const language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
const baseActions = [
{
type: 'add',
path: `${filePath}/controllers/{{id}}.${language}`,
path: `${filePath}/controllers/{{ id }}.${language}`,
templateFile: `templates/${language}/controller.${language}.hbs`,
},
{
type: 'add',
path: `${filePath}/services/{{id}}.${language}`,
path: `${filePath}/services/{{ id }}.${language}`,
templateFile: `templates/${language}/service.${language}.hbs`,
},
];
@ -71,7 +72,7 @@ module.exports = (plop) => {
return [
{
type: 'add',
path: `${filePath}/routes/{{id}}.${language}`,
path: `${filePath}/routes/{{ id }}.${language}`,
templateFile: `templates/${language}/single-route.${language}.hbs`,
},
...baseActions,

View File

@ -123,19 +123,19 @@ module.exports = (plop) => {
baseActions.push(
{
type: 'add',
path: `${filePath}/controllers/{{singularName}}.${language}`,
path: `${filePath}/controllers/{{ singularName }}.${language}`,
templateFile: `templates/${language}/core-controller.${language}.hbs`,
data: { uid },
},
{
type: 'add',
path: `${filePath}/services/{{singularName}}.${language}`,
path: `${filePath}/services/{{ singularName }}.${language}`,
templateFile: `templates/${language}/core-service.${language}.hbs`,
data: { uid },
},
{
type: 'add',
path: `${filePath}/routes/{{singularName}}.${language}`,
path: `${filePath}/routes/{{ singularName }}.${language}`,
templateFile: `templates/${language}/core-router.${language}.hbs`,
data: { uid },
}

View File

@ -27,7 +27,7 @@ module.exports = (plop) => {
return [
{
type: 'add',
path: `${filePath}/policies/{{id}}.${language}`,
path: `${filePath}/policies/{{ id }}.${language}`,
templateFile: `templates/${language}/policy.${language}.hbs`,
},
];

View File

@ -2,8 +2,8 @@ module.exports = {
routes: [
{
method: 'GET',
path: '/{{pluralize id}}',
handler: '{{id}}.find',
path: '/{{ pluralize id }}',
handler: '{{ id }}.find',
config: {
policies: [],
middlewares: [],
@ -11,8 +11,8 @@ module.exports = {
},
{
method: 'GET',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.findOne',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.findOne',
config: {
policies: [],
middlewares: [],
@ -20,8 +20,8 @@ module.exports = {
},
{
method: 'POST',
path: '/{{pluralize id}}',
handler: '{{id}}.create',
path: '/{{ pluralize id }}',
handler: '{{ id }}.create',
config: {
policies: [],
middlewares: [],
@ -29,8 +29,8 @@ module.exports = {
},
{
method: 'PUT',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.update',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.update',
config: {
policies: [],
middlewares: [],
@ -38,8 +38,8 @@ module.exports = {
},
{
method: 'DELETE',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.delete',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.delete',
config: {
policies: [],
middlewares: [],

View File

@ -1,7 +1,7 @@
'use strict';
/**
* A set of functions called "actions" for `{{id}}`
* A set of functions called "actions" for `{{ id }}`
*/
module.exports = {

View File

@ -1,7 +1,7 @@
'use strict';
/**
* {{ id }} controller
* {{ id }} controller
*/
const { createCoreController } = require('@strapi/strapi').factories;

View File

@ -1,7 +1,7 @@
'use strict';
/**
* {{ id }} router.
* {{ id }} router
*/
const { createCoreRouter } = require('@strapi/strapi').factories;

View File

@ -1,7 +1,7 @@
'use strict';
/**
* {{ id }} service.
* {{ id }} service
*/
const { createCoreService } = require('@strapi/strapi').factories;

View File

@ -1,7 +1,7 @@
'use strict';
/**
* `{{ name }}` middleware.
* `{{ name }}` middleware
*/
module.exports = (config, { strapi }) => {

View File

@ -1,12 +1,12 @@
'use strict';
/**
* `{{id}}` policy.
* `{{ id }}` policy
*/
module.exports = (policyContext, config, { strapi }) => {
// Add your own logic here.
strapi.log.info('In {{id}} policy.');
strapi.log.info('In {{ id }} policy.');
const canDoSomething = true;

View File

@ -1,7 +1,7 @@
'use strict';
/**
* {{id}} service.
* {{ id }} service
*/
module.exports = () => ({});

View File

@ -2,8 +2,8 @@ module.exports = {
routes: [
// {
// method: 'GET',
// path: '/{{id}}',
// handler: '{{id}}.exampleAction',
// path: '/{{ id }}',
// handler: '{{ id }}.exampleAction',
// config: {
// policies: [],
// middlewares: [],

View File

@ -4,8 +4,8 @@ module.exports = {
routes: [
{
method: 'GET',
path: '/{{id}}',
handler: '{{id}}.find',
path: '/{{ id }}',
handler: '{{ id }}.find',
config: {
policies: [],
middlewares: [],
@ -13,8 +13,8 @@ module.exports = {
},
{
method: 'PUT',
path: '/{{id}}',
handler: '{{id}}.update',
path: '/{{ id }}',
handler: '{{ id }}.update',
config: {
policies: [],
middlewares: [],
@ -22,8 +22,8 @@ module.exports = {
},
{
method: 'DELETE',
path: '/{{id}}',
handler: '{{id}}.delete',
path: '/{{ id }}',
handler: '{{ id }}.delete',
config: {
policies: [],
middlewares: [],

View File

@ -2,8 +2,8 @@ export default {
routes: [
{
method: 'GET',
path: '/{{pluralize id}}',
handler: '{{id}}.find',
path: '/{{ pluralize id }}',
handler: '{{ id }}.find',
config: {
policies: [],
middlewares: [],
@ -11,8 +11,8 @@ export default {
},
{
method: 'GET',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.findOne',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.findOne',
config: {
policies: [],
middlewares: [],
@ -20,8 +20,8 @@ export default {
},
{
method: 'POST',
path: '/{{pluralize id}}',
handler: '{{id}}.create',
path: '/{{ pluralize id }}',
handler: '{{ id }}.create',
config: {
policies: [],
middlewares: [],
@ -29,8 +29,8 @@ export default {
},
{
method: 'PUT',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.update',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.update',
config: {
policies: [],
middlewares: [],
@ -38,8 +38,8 @@ export default {
},
{
method: 'DELETE',
path: '/{{pluralize id}}/:id',
handler: '{{id}}.delete',
path: '/{{ pluralize id }}/:id',
handler: '{{ id }}.delete',
config: {
policies: [],
middlewares: [],

View File

@ -1,5 +1,5 @@
/**
* A set of functions called "actions" for `{{id}}`
* A set of functions called "actions" for `{{ id }}`
*/
export default {

View File

@ -1,5 +1,5 @@
/**
* {{ id }} controller
* {{ id }} controller
*/
import { factories } from '@strapi/strapi'

View File

@ -1,5 +1,5 @@
/**
* {{ id }} router.
* {{ id }} router
*/
import { factories } from '@strapi/strapi';

View File

@ -1,5 +1,5 @@
/**
* {{ id }} service.
* {{ id }} service
*/
import { factories } from '@strapi/strapi';

View File

@ -1,8 +1,8 @@
/**
* `{{ name }}` middleware.
* `{{ name }}` middleware
*/
import '@strapi/strapi';
import { Strapi } from '@strapi/strapi';
export default (config, { strapi }: { strapi: Strapi }) => {
// Add your own logic here.

View File

@ -9,8 +9,7 @@
},
"dependencies": {},
"devDependencies": {
"typescript": "4.6.3",
"@strapi/strapi": "4.1.8"
"typescript": "4.6.3"
},
"author": {
"name": "A Strapi developer"
@ -21,7 +20,7 @@
}
],
"engines": {
"node": ">=12.x.x <=16.x.x",
"node": ">=14.19.1 <=16.x.x",
"npm": ">=6.0.0"
},
"scripts": {

View File

@ -1,10 +1,10 @@
/**
* `{{id}}` policy.
* {{ id }} policy
*/
export default (policyContext, config, { strapi }) => {
// Add your own logic here.
strapi.log.info('In {{id}} policy.');
strapi.log.info('In {{ id }} policy.');
const canDoSomething = true;

View File

@ -1,5 +1,5 @@
/**
* {{id}} service.
* {{ id }} service
*/
export default () => ({});

View File

@ -2,8 +2,8 @@ export default {
routes: [
// {
// method: 'GET',
// path: '/{{id}}',
// handler: '{{id}}.exampleAction',
// path: '/{{ id }}',
// handler: '{{ id }}.exampleAction',
// config: {
// policies: [],
// middlewares: [],

View File

@ -2,8 +2,8 @@ export default {
routes: [
{
method: 'GET',
path: '/{{id}}',
handler: '{{id}}.find',
path: '/{{ id }}',
handler: '{{ id }}.find',
config: {
policies: [],
middlewares: [],
@ -11,8 +11,8 @@ export default {
},
{
method: 'PUT',
path: '/{{id}}',
handler: '{{id}}.update',
path: '/{{ id }}',
handler: '{{ id }}.update',
config: {
policies: [],
middlewares: [],
@ -20,8 +20,8 @@ export default {
},
{
method: 'DELETE',
path: '/{{id}}',
handler: '{{id}}.delete',
path: '/{{ id }}',
handler: '{{ id }}.delete',
config: {
policies: [],
middlewares: [],

View File

@ -48,6 +48,10 @@
"peerDependencies": {
"@strapi/strapi": "^4.0.0"
},
"devDependencies": {
"@testing-library/react": "11.2.7",
"msw": "0.42.3"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",
"npm": ">=6.0.0"

View File

@ -28,7 +28,7 @@
},
"dependencies": {
"@graphql-tools/schema": "8.1.2",
"@graphql-tools/utils": "^8.9.0",
"@graphql-tools/utils": "^8.10.0",
"@strapi/utils": "4.3.4",
"apollo-server-core": "3.1.2",
"apollo-server-koa": "3.10.0",

View File

@ -1,7 +1,65 @@
{
"CMEditViewCopyLocale.copy-failure": "Échec de la copie de la locale",
"CMEditViewCopyLocale.copy-success": "Locale copiée",
"CMEditViewCopyLocale.copy-text": "Remplir à partir d'une autre locale",
"CMEditViewCopyLocale.submit-text": "Oui, remplir",
"CMListView.popover.display-locales.label": "Afficher les locales traduites",
"CheckboxConfirmation.Modal.body": "Voulez-vous le désactiver ?",
"CheckboxConfirmation.Modal.button-confirm": "Oui, désactiver",
"CheckboxConfirmation.Modal.content": "La désactivation de la localisation entraînera la suppression de tout votre contenu, à l'exception de celui associé à votre locale par défaut (si elle existe).",
"Field.localized": "Cette valeur est unique pour la locale sélectionnée",
"Field.not-localized": "Cette valeur est commune à toutes les locales",
"Settings.list.actions.add": "Ajouter une locale",
"Settings.list.actions.delete": "Supprimer une locale",
"Settings.list.actions.deleteAdditionalInfos": "Cela supprimera les versions locales actives <em>(d'Internationalisation)</em>.",
"Settings.list.actions.edit": "Modifier une locale",
"Settings.list.description": "Configurer les paramètres du plugin d'internationalisation",
"Settings.list.empty.description": "Ce n'est pas un comportement habituel, ce qui signifie que vous avez peut-être modifié la base de données manuellement. Assurez-vous d'avoir au moins une locale enregistrée dans votre base de données afin de pouvoir utiliser Strapi correctement.",
"Settings.list.empty.title": "Il n'y a pas de locale",
"Settings.locales.default": "Par défaut",
"Settings.locales.list.sort.default": "Trier par la locale par défaut",
"Settings.locales.list.sort.displayName": "Trier par nom d'affichage",
"Settings.locales.list.sort.id": "Trier par ID",
"Settings.locales.modal.advanced": "Paramètres avancés",
"Settings.locales.modal.advanced.setAsDefault": "Définir comme locale par défaut",
"Settings.locales.modal.advanced.setAsDefault.hint": "Une locale par défaut est requise, changez-la en en sélectionnant une autre",
"Settings.locales.modal.advanced.settings": "Paramètres",
"Settings.locales.modal.base": "Paramètres de base",
"Settings.locales.modal.create.alreadyExist": "Cette locale existe déjà",
"Settings.locales.modal.create.defaultLocales.loading": "Chargement des locales disponibles...",
"Settings.locales.modal.create.success": "Locale ajoutée avec succès",
"Settings.locales.modal.create.tab.label": "Navigation entre les paramètres de base et les paramètres avancés de l'I18N",
"Settings.locales.modal.delete.confirm": "Oui, supprimer",
"Settings.locales.modal.delete.message": "La suppression de cette locale entraîne la suppression de tout le contenu associé. Si vous souhaitez conserver du contenu, veillez à le réaffecter à une autre locale au préalable.",
"Settings.locales.modal.delete.secondMessage": "Voulez-vous supprimer cette locale ?",
"Settings.locales.modal.delete.success": "Locale supprimée avec succès",
"Settings.locales.modal.edit.confirmation": "Terminer",
"Settings.locales.modal.edit.locales.label": "Locales",
"Settings.locales.modal.edit.success": "Locale modifiée avec succès",
"Settings.locales.modal.edit.tab.label": "Navigation entre les paramètres de base et les paramètres avancés de l'I18N",
"Settings.locales.modal.locales.displayName": "Nom d'affichage de la locale",
"Settings.locales.modal.locales.displayName.description": "La locale sera affichée sous ce nom dans le panneau d'administration.",
"Settings.locales.modal.locales.displayName.error": "Le nom d'affichage de la locale doit avoir moins de 50 caractères.",
"Settings.locales.modal.locales.label": "Locales",
"Settings.locales.modal.locales.loaded": "Les locales ont été chargées avec succès.",
"Settings.locales.modal.title": "Configurations",
"Settings.locales.row.default-locale": "Locale par défaut",
"Settings.locales.row.displayName": "Nom d'affichage",
"Settings.locales.row.id": "ID",
"Settings.permissions.loading": "Chargement des autorisations",
"Settings.permissions.read.denied.description": "Afin de pouvoir lire ceci, assurez de contacter l'administrateur de votre système.",
"Settings.permissions.read.denied.title": "Vous n'avez pas les autorisations nécessaires pour accéder à ce contenu.",
"actions.select-locale": "Sélectionnez une locale",
"components.Select.locales.not-available": "Aucun contenu disponible",
"plugin.description.long": "Créez, lisez et modifiez votre contenu en différentes langues depuis le panel d'administration et votre API.",
"plugin.description.short": "Créez, lisez et modifiez votre contenu en différentes langues depuis le panel d'administration et votre API.",
"plugin.name": "Internationalisation"
}
"plugin.name": "Internationalisation",
"plugin.schema.i18n.ensure-unique-localization": "Les champs uniques doivent avoir une locale",
"plugin.schema.i18n.localized.description": "Donne la possibilité d'avoir du contenu dans différentes locales",
"plugin.schema.i18n.localized.description-content-type": "Donne la possibilité d'avoir du contenu dans différentes locales",
"plugin.schema.i18n.localized.description-field": "Le champ peut avoir des valeurs différentes dans chaque locale",
"plugin.schema.i18n.localized.label": "Activer la localisation pour ce type de contenu",
"plugin.schema.i18n.localized.label-content-type": "Activer la localisation pour ce type de contenu",
"plugin.schema.i18n.localized.label-field": "Activer la localisation pour ce champ"
}

View File

@ -27,6 +27,10 @@
"@strapi/utils": "4.3.4",
"lodash": "4.17.21"
},
"devDependencies": {
"@testing-library/react": "12.1.4",
"msw": "0.42.3"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",
"npm": ">=6.0.0"

View File

@ -42,10 +42,16 @@
"react-router": "^5.2.0",
"react-router-dom": "5.2.0",
"request": "^2.83.0",
"url-join": "4.0.1"
"url-join": "4.0.1",
"koa": "^2.13.4"
},
"devDependencies": {
"koa": "^2.13.4"
"@testing-library/dom": "8.17.1",
"@testing-library/react": "12.1.4",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/user-event": "14.4.2",
"msw": "0.42.3",
"react-test-renderer": "^17.0.2"
},
"engines": {
"node": ">=14.19.1 <=16.x.x",

View File

@ -1,7 +1,7 @@
'use strict';
/**
* Module dependencies.
* Module dependencies
*/
// Public node modules.

View File

@ -36,7 +36,7 @@
"test": "echo \"no tests yet\""
},
"dependencies": {
"@sendgrid/mail": "7.4.7",
"@sendgrid/mail": "7.7.0",
"@strapi/utils": "4.3.4"
},
"engines": {

View File

@ -14,7 +14,7 @@ module.exports = {
cloudinary.config(config);
const upload = (file, customConfig = {}) =>
new Promise((resolve) => {
new Promise((resolve, reject) => {
const config = {
resource_type: 'auto',
public_id: file.hash,
@ -29,9 +29,11 @@ module.exports = {
(err, image) => {
if (err) {
if (err.message.includes('File size too large')) {
throw new PayloadTooLargeError();
reject(new PayloadTooLargeError());
} else {
reject(new Error(`Error uploading to cloudinary: ${err.message}`));
}
throw new Error(`Error uploading to cloudinary: ${err.message}`);
return;
}
if (image.resource_type === 'video') {

View File

@ -5,15 +5,18 @@ cd "$(dirname "$0")/.."
set -e
version=""
distTag=""
version=$VERSION
distTag=$DIST_TAG
echo "Please enter the version you want to publish"
read -r version
if [[ -z "$version" ]]; then
echo "Please enter the version you want to publish"
read -r version
fi
echo "Please enter the dist-tag you want to publish with"
read -r distTag
if [[ -z "$distTag" ]]; then
echo "Please enter the dist-tag you want to publish with"
read -r distTag
fi
# publish packages
./node_modules/.bin/lerna publish --no-push --no-git-tag-version --force-publish --exact "$version" --dist-tag "$distTag"
./node_modules/.bin/lerna publish --no-push --no-git-tag-version --force-publish --exact "$version" --dist-tag "$distTag" $@

View File

@ -13,8 +13,8 @@ read -r version
# publish packages
./node_modules/.bin/lerna publish --no-push --force-publish --dist-tag latest --exact "$version"
# push master branch
git push origin master
# push main branch
git push origin main
# push tag
git push origin v"$version"

1665
yarn.lock

File diff suppressed because it is too large Load Diff