mirror of
https://github.com/strapi/strapi.git
synced 2025-12-03 02:23:44 +00:00
Merge branch 'master' into chore/routing-x-forwarded
This commit is contained in:
commit
7a94d9dad9
@ -42,6 +42,7 @@ module.exports = {
|
||||
rules: {
|
||||
'generator-star-spacing': 0,
|
||||
'no-console': 0,
|
||||
'require-atomic-updates': 0,
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
},
|
||||
|
||||
@ -71,6 +71,8 @@ jobs:
|
||||
- <<: *e2e_tests
|
||||
name: 'E2E Mysql'
|
||||
before_install:
|
||||
- sudo cp $TRAVIS_BUILD_DIR/_travis/mysql.cnf /etc/mysql/conf.d/
|
||||
- sudo service mysql restart
|
||||
- mysql -e 'CREATE DATABASE strapi_test;'
|
||||
env:
|
||||
- DB_STRING='--dbclient=mysql --dbhost=localhost --dbport=3306 --dbname=strapi_test --dbusername=travis --dbpassword='
|
||||
|
||||
3
_travis/mysql.cnf
Normal file
3
_travis/mysql.cnf
Normal file
@ -0,0 +1,3 @@
|
||||
[mysqld]
|
||||
collation-server=utf8_unicode_ci
|
||||
character-set-server=utf8
|
||||
@ -23,6 +23,9 @@
|
||||
"group": "dish",
|
||||
"type": "group",
|
||||
"repeatable": true
|
||||
},
|
||||
"menu": {
|
||||
"model": "menu"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,12 @@
|
||||
},
|
||||
"price": {
|
||||
"type": "float"
|
||||
},
|
||||
"picture": {
|
||||
"model": "file",
|
||||
"via": "related",
|
||||
"plugin": "upload",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "getstarted",
|
||||
"private": true,
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "A Strapi application.",
|
||||
"scripts": {
|
||||
"develop": "strapi develop",
|
||||
@ -15,23 +15,23 @@
|
||||
"mysql": "^2.17.1",
|
||||
"pg": "^7.10.0",
|
||||
"sqlite3": "^4.0.6",
|
||||
"strapi": "3.0.0-beta.16.3",
|
||||
"strapi-admin": "3.0.0-beta.16.3",
|
||||
"strapi-hook-bookshelf": "3.0.0-beta.16.3",
|
||||
"strapi-hook-knex": "3.0.0-beta.16.3",
|
||||
"strapi-hook-mongoose": "3.0.0-beta.16.3",
|
||||
"strapi-middleware-views": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-content-manager": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-content-type-builder": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-documentation": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-email": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-graphql": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-settings-manager": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-upload": "3.0.0-beta.16.3",
|
||||
"strapi-plugin-users-permissions": "3.0.0-beta.16.3",
|
||||
"strapi-provider-email-mailgun": "3.0.0-beta.16.3",
|
||||
"strapi-provider-upload-aws-s3": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi": "3.0.0-beta.16.4",
|
||||
"strapi-admin": "3.0.0-beta.16.4",
|
||||
"strapi-hook-bookshelf": "3.0.0-beta.16.4",
|
||||
"strapi-hook-knex": "3.0.0-beta.16.4",
|
||||
"strapi-hook-mongoose": "3.0.0-beta.16.4",
|
||||
"strapi-middleware-views": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-content-manager": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-content-type-builder": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-documentation": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-email": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-graphql": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-settings-manager": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-upload": "3.0.0-beta.16.4",
|
||||
"strapi-plugin-users-permissions": "3.0.0-beta.16.4",
|
||||
"strapi-provider-email-mailgun": "3.0.0-beta.16.4",
|
||||
"strapi-provider-upload-aws-s3": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"strapi": {
|
||||
"uuid": "getstarted"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"packages": [
|
||||
"packages/*",
|
||||
"examples/*"
|
||||
|
||||
16
package.json
16
package.json
@ -3,25 +3,25 @@
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^4.0.0",
|
||||
"@testing-library/react": "^9.1.1",
|
||||
"@testing-library/react-hooks": "^2.0.1",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"@testing-library/react": "^9.1.0",
|
||||
"@testing-library/react-hooks": "^2.0.0",
|
||||
"babel-eslint": "^10.0.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"cypress": "3.1.2",
|
||||
"enzyme": "^3.9.0",
|
||||
"enzyme-adapter-react-16": "^1.12.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-prettier": "^6.0.0",
|
||||
"eslint": "^6.3.0",
|
||||
"eslint-config-prettier": "^6.2.0",
|
||||
"eslint-plugin-react": "^7.14.0",
|
||||
"eslint-plugin-react-hooks": "^1.6.1",
|
||||
"eslint-plugin-redux-saga": "^1.0.0",
|
||||
"eslint-plugin-react-hooks": "^2.0.0",
|
||||
"eslint-plugin-redux-saga": "^1.1.0",
|
||||
"execa": "^1.0.0",
|
||||
"husky": "^3.0.0",
|
||||
"istanbul": "~0.4.2",
|
||||
"jest": "^24.5.0",
|
||||
"jest-cli": "^24.5.0",
|
||||
"lerna": "^3.13.1",
|
||||
"lint-staged": "^9.1.0",
|
||||
"lint-staged": "^9.2.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^1.18.2",
|
||||
"react-test-renderer": "^16.9.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-strapi-app",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a new Strapi application.",
|
||||
"license": "MIT",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -21,7 +21,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.20.0",
|
||||
"strapi-generate-new": "3.0.0-beta.16.3"
|
||||
"strapi-generate-new": "3.0.0-beta.16.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"no tests yet\""
|
||||
|
||||
@ -177,7 +177,7 @@ if (NODE_ENV !== 'test') {
|
||||
import('intl/locale-data/jsonp/en.js'),
|
||||
import('intl/locale-data/jsonp/de.js'),
|
||||
])
|
||||
) // eslint-disable-line prettier/prettier
|
||||
)
|
||||
.then(() => render(translationMessages))
|
||||
.catch(err => {
|
||||
throw err;
|
||||
|
||||
@ -15,7 +15,6 @@ import Reddit from '../../assets/images/social_reddit.png';
|
||||
|
||||
import { SocialLinkWrapper } from './components';
|
||||
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
function getSrc(name) {
|
||||
switch (name) {
|
||||
case 'GitHub':
|
||||
|
||||
@ -92,7 +92,6 @@ export class Onboarding extends React.Component {
|
||||
this.props.setVideoEnd(index, true);
|
||||
};
|
||||
|
||||
// eslint-disable-line jsx-handler-names
|
||||
render() {
|
||||
const { videos, onClick, setVideoDuration } = this.props;
|
||||
const { showVideos } = this.state;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-admin",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Strapi Admin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -72,8 +72,8 @@
|
||||
"sanitize.css": "^4.1.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"shelljs": "^0.7.8",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4",
|
||||
"style-loader": "^0.23.1",
|
||||
"styled-components": "^4.2.0",
|
||||
"terser-webpack-plugin": "^1.2.3",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-api",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate an API for a Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-controller",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a controller for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-model",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a model for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -29,8 +29,8 @@ module.exports = opts => {
|
||||
},
|
||||
devDependencies: {
|
||||
'babel-eslint': '^10.0.0',
|
||||
eslint: '^6.0.0',
|
||||
'eslint-config-airbnb': '^17.1.0',
|
||||
eslint: '^6.3.0',
|
||||
'eslint-config-airbnb': '^18.0.0',
|
||||
'eslint-plugin-import': '^2.18.0',
|
||||
'eslint-plugin-react': '^7.14.0',
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-new",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a new Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-plugin",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate an plugin for a Strapi application.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-policy",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a policy for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate-service",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Generate a service for a Strapi API.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-generate",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Master of ceremonies for the Strapi generators.",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -20,7 +20,7 @@
|
||||
"fs-extra": "^8.0.1",
|
||||
"lodash": "^4.17.11",
|
||||
"reportback": "^2.0.2",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Strapi team",
|
||||
|
||||
@ -30,7 +30,7 @@ import App from 'containers/App';
|
||||
|
||||
const layout = (() => {
|
||||
try {
|
||||
return require('../../../../config/layout.js'); // eslint-disable-line import/no-unresolved
|
||||
return require('../../../../config/layout.js');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
@ -38,7 +38,7 @@ const layout = (() => {
|
||||
|
||||
const injectedComponents = (() => {
|
||||
try {
|
||||
return require('injectedComponents').default; // eslint-disable-line import/no-unresolved
|
||||
return require('injectedComponents').default;
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
@ -80,7 +80,7 @@ if (module.hot) {
|
||||
// Require the Initializer component
|
||||
const initializer = (() => {
|
||||
try {
|
||||
return require('../../../../admin/src/initializer.js'); // eslint-disable-line import/no-unresolved
|
||||
return require('../../../../admin/src/initializer.js');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
@ -89,7 +89,7 @@ const initializer = (() => {
|
||||
// Require the plugin's lifecycle
|
||||
const lifecycles = (() => {
|
||||
try {
|
||||
return require('../../../../admin/src/lifecycles.js'); // eslint-disable-line import/no-unresolved
|
||||
return require('../../../../admin/src/lifecycles.js');
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/anchor-is-valid */
|
||||
class GlobalPagination extends React.Component {
|
||||
getLastPageNumber = () => Math.ceil(this.props.count / this.props.params._limit) || 1;
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputAddon extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
|
||||
@ -12,8 +12,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
class InputCheckbox extends React.Component {
|
||||
handleChange = () => {
|
||||
const target = {
|
||||
|
||||
@ -11,7 +11,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputEmail extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
|
||||
@ -17,7 +17,6 @@ import InputFileDetails from '../InputFileDetails';
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable react/jsx-handler-names */
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
class InputFile extends React.Component {
|
||||
state = {
|
||||
didDeleteFile: false,
|
||||
@ -60,7 +59,7 @@ class InputFile extends React.Component {
|
||||
type: 'file',
|
||||
value,
|
||||
};
|
||||
|
||||
|
||||
this.inputFile.value = '';
|
||||
this.setState({ isUploading: !this.state.isUploading });
|
||||
this.props.onChange({ target });
|
||||
@ -105,7 +104,7 @@ class InputFile extends React.Component {
|
||||
const {value} = this.props;
|
||||
|
||||
if (!value ||
|
||||
(isArray(value) && value.length === 0) ||
|
||||
(isArray(value) && value.length === 0) ||
|
||||
(isObject(value) && Object.keys(value).length === 0)
|
||||
) {
|
||||
return false;
|
||||
|
||||
@ -6,10 +6,9 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
function InputNumber(props) {
|
||||
const formattedPlaceholder = props.placeholder === '' ? 'app.utils.placeholder.defaultMessage' : props.placeholder;
|
||||
|
||||
|
||||
return (
|
||||
<FormattedMessage id={formattedPlaceholder} defaultMessage={formattedPlaceholder}>
|
||||
{(message) => (
|
||||
|
||||
@ -12,7 +12,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputPassword extends React.Component {
|
||||
state = { showPassword: false };
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputSearch extends React.Component {
|
||||
state = { isFocused: false };
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@ import SelectOption from '../SelectOption';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
function InputSelect(props) {
|
||||
return (
|
||||
<select
|
||||
|
||||
@ -4,7 +4,6 @@ import { isEmpty } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import cn from 'classnames';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
import styles from './styles.scss';
|
||||
|
||||
function InputText(props) {
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
@ -15,7 +15,6 @@ import InputSpacer from '../InputSpacer';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputTextWithErrors extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
state = { errors: [], hasInitialValue: false };
|
||||
|
||||
@ -9,7 +9,6 @@ import { isEmpty } from 'lodash';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-autofocus */
|
||||
class InputToggle extends React.Component {
|
||||
handleClick = (e) => {
|
||||
const target = {
|
||||
|
||||
@ -6,7 +6,6 @@ import cn from 'classnames';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
function Label(props) {
|
||||
let content = props.children;
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ import GlobalPagination from '../GlobalPagination';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
function PageFooter(props) {
|
||||
return (
|
||||
<div className={cn('row', styles.pageFooter)} style={props.style}>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-helper-plugin",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Helper for Strapi plugins development",
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@ -161,9 +161,9 @@ module.exports = ({ models, target, plugin = false }, ctx) => {
|
||||
|
||||
const FK = _.findKey(target.attributes, details => {
|
||||
if (
|
||||
details.hasOwnProperty('model') &&
|
||||
_.has(details, 'model') &&
|
||||
details.model === model &&
|
||||
details.hasOwnProperty('via') &&
|
||||
_.has(details, 'via') &&
|
||||
details.via === name
|
||||
) {
|
||||
return details;
|
||||
@ -841,7 +841,7 @@ module.exports = ({ models, target, plugin = false }, ctx) => {
|
||||
_.keyBy(
|
||||
_.filter(definition.attributes, (value, key) => {
|
||||
if (
|
||||
value.hasOwnProperty('columnName') &&
|
||||
_.has(value, 'columnName') &&
|
||||
!_.isEmpty(value.columnName) &&
|
||||
value.columnName !== key
|
||||
) {
|
||||
|
||||
@ -490,7 +490,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
|
||||
* @param {*} params
|
||||
*/
|
||||
const buildSearchQuery = (qb, model, params) => {
|
||||
const query = (params._q || '').replace(/[^a-zA-Z0-9.-\s]+/g, '');
|
||||
const query = params._q;
|
||||
|
||||
const associations = model.associations.map(x => x.alias);
|
||||
|
||||
@ -550,7 +550,7 @@ const buildSearchQuery = (qb, model, params) => {
|
||||
: `to_tsvector('${attribute}')`
|
||||
);
|
||||
|
||||
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ to_tsquery(?)`, query);
|
||||
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ plainto_tsquery(?)`, query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-bookshelf",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Bookshelf hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -22,8 +22,8 @@
|
||||
"lodash": "^4.17.11",
|
||||
"pluralize": "^7.0.0",
|
||||
"rimraf": "^2.6.3",
|
||||
"strapi-hook-knex": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-hook-knex": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"strapi": {
|
||||
"dependencies": [
|
||||
|
||||
@ -9,7 +9,7 @@ const path = require('path');
|
||||
|
||||
// Externals
|
||||
const co = require('co');
|
||||
const render = require('koa-ejs'); // eslint-disable-line import/no-unresolved
|
||||
const render = require('koa-ejs');
|
||||
|
||||
/**
|
||||
* EJS hook
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-ejs",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "EJS hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-knex",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Knex hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -356,14 +356,56 @@ const createOnFetchPopulateFn = ({
|
||||
});
|
||||
|
||||
groupAttributes.forEach(name => {
|
||||
const attr = definition.attributes[name];
|
||||
|
||||
const group = strapi.groups[attr.group];
|
||||
|
||||
const assocs = (group.associations || []).filter(
|
||||
assoc => assoc.autoPopulate === true
|
||||
);
|
||||
|
||||
let subpopulates = [];
|
||||
|
||||
assocs.forEach(assoc => {
|
||||
if (isPolymorphic({ assoc })) {
|
||||
if (
|
||||
assoc.nature === 'oneToManyMorph' ||
|
||||
assoc.nature === 'manyToManyMorph'
|
||||
) {
|
||||
subpopulates.push({
|
||||
path: assoc.alias,
|
||||
match: {
|
||||
[`${assoc.via}.${assoc.filter}`]: assoc.alias,
|
||||
[`${assoc.via}.kind`]: definition.globalId,
|
||||
},
|
||||
options: {
|
||||
sort: '-createdAt',
|
||||
},
|
||||
select: undefined,
|
||||
model: undefined,
|
||||
_docs: {},
|
||||
});
|
||||
} else {
|
||||
subpopulates.push({ path: `${assoc.alias}.ref`, _docs: {} });
|
||||
}
|
||||
} else {
|
||||
subpopulates.push({
|
||||
path: assoc.alias,
|
||||
_docs: {},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (
|
||||
this._mongooseOptions.populate &&
|
||||
this._mongooseOptions.populate[name]
|
||||
) {
|
||||
this._mongooseOptions.populate[name].path = `${name}.ref`;
|
||||
this._mongooseOptions.populate[name].populate = subpopulates;
|
||||
} else {
|
||||
_.set(this._mongooseOptions, ['populate', name], {
|
||||
path: `${name}.ref`,
|
||||
populate: subpopulates,
|
||||
_docs: {},
|
||||
});
|
||||
}
|
||||
@ -373,6 +415,10 @@ const createOnFetchPopulateFn = ({
|
||||
};
|
||||
};
|
||||
|
||||
const isPolymorphic = ({ assoc }) => {
|
||||
return assoc.nature.toLowerCase().indexOf('morph') !== -1;
|
||||
};
|
||||
|
||||
const buildRelation = ({ definition, model, instance, attribute, name }) => {
|
||||
const { nature, verbose } =
|
||||
utilsModels.getNature(attribute, name, undefined, model.toLowerCase()) ||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-mongoose",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Mongoose hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -20,7 +20,7 @@
|
||||
"mongoose-float": "^1.0.4",
|
||||
"mongoose-long": "^0.2.1",
|
||||
"pluralize": "^7.0.0",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
// Core
|
||||
const util = require('util');
|
||||
/* eslint-disable prefer-template */
|
||||
/* eslint-disable import/no-unresolved */
|
||||
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-hook-redis",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Redis hook for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
@ -19,7 +19,7 @@
|
||||
"lodash": "^4.17.11",
|
||||
"rimraf": "^2.6.3",
|
||||
"stack-trace": "0.0.10",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"author": {
|
||||
"email": "hi@strapi.io",
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = strapi => {
|
||||
if (_.isPlainObject(views) && !_.isEmpty(views)) {
|
||||
const opts = _.clone(views);
|
||||
|
||||
if (opts.hasOwnProperty('default')) {
|
||||
if (_.has(opts, 'default')) {
|
||||
opts.extension = opts.default;
|
||||
delete opts.default;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-middleware-views",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Views middleware to enable server-side rendering for the Strapi framework",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -30,6 +30,7 @@ const Form = ({
|
||||
<SelectWrapper
|
||||
{...currentFieldMeta}
|
||||
name={keys}
|
||||
plugin={currentField.plugin}
|
||||
relationType={currentField.relationType}
|
||||
targetModel={currentField.targetModel}
|
||||
value={get(modifiedData, keys)}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/* eslint-disable jsx-a11y/media-has-caption */
|
||||
const Video = props => {
|
||||
const { height, src, width } = props.contentState.getEntity(props.entityKey).getData();
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import styles from './styles.scss';
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
|
||||
const WysiwygBottomControls = ({ isPreviewMode, onChange, onClick }) => {
|
||||
const browse = (
|
||||
<FormattedMessage id="components.WysiwygBottomControls.uploadFiles.browse">
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
import React from 'react';
|
||||
import styles from './styles.scss';
|
||||
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
const WysiwygDropUpload = (props) => {
|
||||
return (
|
||||
<label
|
||||
|
||||
@ -134,6 +134,9 @@ function EditView({
|
||||
}
|
||||
};
|
||||
|
||||
// Force state to be cleared when navigation from one entry to another
|
||||
dispatch({ type: 'RESET_PROPS' });
|
||||
|
||||
if (!isCreatingEntry) {
|
||||
fetchData();
|
||||
} else {
|
||||
|
||||
@ -175,6 +175,8 @@ function reducer(state, action) {
|
||||
.update('errors', () => fromJS({}))
|
||||
.update('didCheckErrors', v => !v);
|
||||
}
|
||||
case 'RESET_PROPS':
|
||||
return initialState;
|
||||
case 'SET_COLLAPSES_COMPONENTS_STATE':
|
||||
return state.update('collapses', () => fromJS(action.collapses));
|
||||
case 'SET_ERRORS':
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-content-manager",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "A powerful UI to easily manage your data.",
|
||||
"strapi": {
|
||||
"name": "Content Manager",
|
||||
@ -32,8 +32,8 @@
|
||||
"redux-immutable": "^4.0.0",
|
||||
"reselect": "^3.0.1",
|
||||
"showdown": "^1.9.0",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4",
|
||||
"styled-components": "^4.2.0",
|
||||
"yup": "^0.27.0"
|
||||
},
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { has } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
@ -53,7 +54,7 @@ class AttributesPickerModal extends React.Component {
|
||||
const appPlugins = plugins;
|
||||
|
||||
return attributes.filter(attr => {
|
||||
if (appPlugins.hasOwnProperty('upload')) {
|
||||
if (has(appPlugins, 'upload')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-content-type-builder",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Strapi plugin to create content type (API).",
|
||||
"strapi": {
|
||||
"name": "Content Type Builder",
|
||||
@ -29,9 +29,9 @@
|
||||
"redux": "^4.0.1",
|
||||
"redux-immutable": "^4.0.0",
|
||||
"reselect": "^3.0.1",
|
||||
"strapi-generate": "3.0.0-beta.16.3",
|
||||
"strapi-generate-api": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-generate": "3.0.0-beta.16.4",
|
||||
"strapi-generate-api": "3.0.0-beta.16.4",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"yup": "^0.27.0"
|
||||
},
|
||||
"author": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-documentation",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "This is the description of the plugin.",
|
||||
"strapi": {
|
||||
"name": "Documentation",
|
||||
@ -32,7 +32,7 @@
|
||||
"redux": "^4.0.1",
|
||||
"redux-immutable": "^4.0.0",
|
||||
"reselect": "^4.0.0",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"swagger-ui-dist": "3.22.1"
|
||||
},
|
||||
"author": {
|
||||
|
||||
@ -381,8 +381,8 @@ module.exports = {
|
||||
(acc, curr) => {
|
||||
const attribute = attributes[curr];
|
||||
const isField =
|
||||
!attribute.hasOwnProperty('model') &&
|
||||
!attribute.hasOwnProperty('collection');
|
||||
!_.has(attribute, 'model') &&
|
||||
!_.has(attribute, 'collection');
|
||||
|
||||
if (attribute.required) {
|
||||
acc.required.push(curr);
|
||||
@ -660,7 +660,8 @@ module.exports = {
|
||||
const { repeatable, group, min, max } = attribute;
|
||||
|
||||
const cmp = this.generateMainComponent(
|
||||
strapi.groups[group].attributes
|
||||
strapi.groups[group].attributes,
|
||||
strapi.groups[group].associations
|
||||
);
|
||||
|
||||
if (repeatable) {
|
||||
@ -1550,8 +1551,8 @@ module.exports = {
|
||||
.map(attr => {
|
||||
const attribute = modelAttributes[attr];
|
||||
const isField =
|
||||
!attribute.hasOwnProperty('model') &&
|
||||
!attribute.hasOwnProperty('collection');
|
||||
!_.has(attribute, 'model') &&
|
||||
!_.has(attribute, 'collection');
|
||||
|
||||
if (!isField) {
|
||||
const name = attribute.model || attribute.collection;
|
||||
@ -1758,7 +1759,7 @@ module.exports = {
|
||||
mergeComponents: (initObj, srcObj) => {
|
||||
const cleanedObj = Object.keys(_.get(initObj, 'schemas', {})).reduce(
|
||||
(acc, current) => {
|
||||
const targetObj = _.get(srcObj, ['schemas'], {}).hasOwnProperty(current)
|
||||
const targetObj = _.has(_.get(srcObj, ['schemas'], {}), current)
|
||||
? srcObj
|
||||
: initObj;
|
||||
|
||||
@ -1778,7 +1779,7 @@ module.exports = {
|
||||
|
||||
mergePaths: function(initObj, srcObj) {
|
||||
return Object.keys(initObj.paths).reduce((acc, current) => {
|
||||
if (_.get(srcObj, ['paths'], {}).hasOwnProperty(current)) {
|
||||
if (_.has(_.get(srcObj, ['paths'], {}), current)) {
|
||||
const verbs = Object.keys(initObj.paths[current]).reduce(
|
||||
(acc1, curr) => {
|
||||
const verb = this.mergeVerbObject(
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-email",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "This is the description of the plugin.",
|
||||
"strapi": {
|
||||
"name": "Email",
|
||||
@ -12,13 +12,13 @@
|
||||
"test": "echo \"no tests yet\""
|
||||
},
|
||||
"dependencies": {
|
||||
"strapi-provider-email-sendmail": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-provider-email-sendmail": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-copy-to-clipboard": "5.0.1",
|
||||
"rimraf": "^2.6.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3"
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Strapi team",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-graphql",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "This is the description of the plugin.",
|
||||
"strapi": {
|
||||
"name": "graphql",
|
||||
@ -23,7 +23,7 @@
|
||||
"graphql-type-long": "^0.1.1",
|
||||
"koa-compose": "^4.1.0",
|
||||
"pluralize": "^7.0.0",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^5.2.0",
|
||||
|
||||
@ -143,8 +143,8 @@ const extractType = function(_type, attributeType) {
|
||||
return isPrimitiveType(_type)
|
||||
? _type.replace('!', '')
|
||||
: isEnumType(attributeType)
|
||||
? 'String'
|
||||
: 'ID';
|
||||
? 'String'
|
||||
: 'ID';
|
||||
};
|
||||
|
||||
/**
|
||||
@ -169,11 +169,20 @@ const extractType = function(_type, attributeType) {
|
||||
* age: function ageResolver() { .... }
|
||||
* }
|
||||
*/
|
||||
const createAggregationFieldsResolver = function(model, fields, operation, typeCheck) {
|
||||
const createAggregationFieldsResolver = function(
|
||||
model,
|
||||
fields,
|
||||
operation,
|
||||
typeCheck
|
||||
) {
|
||||
return createFieldsResolver(
|
||||
fields,
|
||||
async (filters, options, context, fieldResolver, fieldKey) => {
|
||||
// eslint-disable-line no-unused-vars
|
||||
async (obj, options, context, fieldResolver, fieldKey) => {
|
||||
const filters = convertRestQueryParams({
|
||||
...GraphQLQuery.convertToParams(_.omit(obj, 'where')),
|
||||
...GraphQLQuery.convertToQuery(obj.where),
|
||||
});
|
||||
|
||||
return buildQuery({ model, filters, aggregate: true })
|
||||
.group({
|
||||
_id: null,
|
||||
@ -194,7 +203,16 @@ const preProcessGroupByData = function({ result, fieldKey, filters, model }) {
|
||||
return _.map(_result, value => {
|
||||
return {
|
||||
key: value._id,
|
||||
connection: () => filters,
|
||||
connection: () => {
|
||||
// filter by the grouped by value in next connection
|
||||
return {
|
||||
...filters,
|
||||
where: {
|
||||
...(filters.where || {}),
|
||||
[fieldKey]: value._id,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
@ -219,7 +237,13 @@ const preProcessGroupByData = function({ result, fieldKey, filters, model }) {
|
||||
* }
|
||||
*/
|
||||
const createGroupByFieldsResolver = function(model, fields, name) {
|
||||
const resolver = async (filters, options, context, fieldResolver, fieldKey) => {
|
||||
const resolver = async (
|
||||
filters,
|
||||
options,
|
||||
context,
|
||||
fieldResolver,
|
||||
fieldKey
|
||||
) => {
|
||||
const params = {
|
||||
...GraphQLQuery.convertToParams(_.omit(filters, 'where')),
|
||||
...GraphQLQuery.convertToQuery(filters.where),
|
||||
@ -250,8 +274,10 @@ const createGroupByFieldsResolver = function(model, fields, name) {
|
||||
*/
|
||||
const generateConnectionFieldsTypes = function(fields, model) {
|
||||
const { globalId, attributes } = model;
|
||||
const primitiveFields = getFieldsByTypes(fields, isNotOfTypeArray, (type, name) =>
|
||||
extractType(type, (attributes[name] || {}).type)
|
||||
const primitiveFields = getFieldsByTypes(
|
||||
fields,
|
||||
isNotOfTypeArray,
|
||||
(type, name) => extractType(type, (attributes[name] || {}).type)
|
||||
);
|
||||
|
||||
const connectionFields = _.mapValues(primitiveFields, fieldType => ({
|
||||
@ -262,9 +288,9 @@ const generateConnectionFieldsTypes = function(fields, model) {
|
||||
return Object.keys(primitiveFields)
|
||||
.map(
|
||||
fieldKey =>
|
||||
`type ${globalId}Connection${_.upperFirst(fieldKey)} {${Schema.formatGQL(
|
||||
connectionFields[fieldKey]
|
||||
)}}`
|
||||
`type ${globalId}Connection${_.upperFirst(
|
||||
fieldKey
|
||||
)} {${Schema.formatGQL(connectionFields[fieldKey])}}`
|
||||
)
|
||||
.join('\n\n');
|
||||
};
|
||||
@ -277,23 +303,30 @@ const formatConnectionGroupBy = function(fields, model, name) {
|
||||
const groupByFields = getFieldsByTypes(
|
||||
fields,
|
||||
isNotOfTypeArray,
|
||||
(fieldType, fieldName) => `[${globalId}Connection${_.upperFirst(fieldName)}]`
|
||||
(fieldType, fieldName) =>
|
||||
`[${globalId}Connection${_.upperFirst(fieldName)}]`
|
||||
);
|
||||
|
||||
// Get the generated field types
|
||||
let groupByTypes = `type ${groupByGlobalId} {${Schema.formatGQL(groupByFields)}}\n\n`;
|
||||
let groupByTypes = `type ${groupByGlobalId} {${Schema.formatGQL(
|
||||
groupByFields
|
||||
)}}\n\n`;
|
||||
groupByTypes += generateConnectionFieldsTypes(fields, model);
|
||||
|
||||
return {
|
||||
globalId: groupByGlobalId,
|
||||
type: groupByTypes,
|
||||
resolver: {
|
||||
[groupByGlobalId]: createGroupByFieldsResolver(model, groupByFields, name),
|
||||
[groupByGlobalId]: createGroupByFieldsResolver(
|
||||
model,
|
||||
groupByFields,
|
||||
name
|
||||
),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const formatConnectionAggregator = function(fields, model) {
|
||||
const formatConnectionAggregator = function(fields, model, modelName) {
|
||||
const { globalId } = model;
|
||||
|
||||
// Extract all fields of type Integer and Float and change their type to Float
|
||||
@ -314,26 +347,22 @@ const formatConnectionAggregator = function(fields, model) {
|
||||
}
|
||||
|
||||
const gqlNumberFormat = Schema.formatGQL(numericFields);
|
||||
let aggregatorTypes = `type ${aggregatorGlobalId} {${Schema.formatGQL(initialFields)}}\n\n`;
|
||||
let aggregatorTypes = `type ${aggregatorGlobalId} {${Schema.formatGQL(
|
||||
initialFields
|
||||
)}}\n\n`;
|
||||
|
||||
let resolvers = {
|
||||
[aggregatorGlobalId]: {
|
||||
count: async (obj, options, context) => {
|
||||
return buildQuery({
|
||||
model,
|
||||
filters: {
|
||||
limit: obj.limit,
|
||||
where: obj.where,
|
||||
},
|
||||
}).count();
|
||||
count(obj, options, context) {
|
||||
const opts = GraphQLQuery.convertToQuery(obj.where);
|
||||
|
||||
if (opts._q) { // allow search param
|
||||
return strapi.query(modelName).countSearch(opts);
|
||||
}
|
||||
return strapi.query(modelName).count(opts);
|
||||
},
|
||||
totalCount: async (obj, options, context) => {
|
||||
return buildQuery({
|
||||
model,
|
||||
filters: {
|
||||
where: obj.where,
|
||||
},
|
||||
}).count();
|
||||
totalCount(obj, options, context) {
|
||||
return strapi.query(modelName).count({});
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -483,12 +512,7 @@ const formatModelConnectionsGQL = function(fields, model, name, modelResolver) {
|
||||
return obj;
|
||||
},
|
||||
aggregate(obj, options, context) {
|
||||
const params = {
|
||||
...GraphQLQuery.convertToParams(_.omit(obj, 'where')),
|
||||
...GraphQLQuery.convertToQuery(obj.where),
|
||||
};
|
||||
|
||||
return convertRestQueryParams(params);
|
||||
return obj;
|
||||
},
|
||||
},
|
||||
...aggregatorFormat.resolver,
|
||||
|
||||
@ -59,6 +59,7 @@ module.exports = {
|
||||
|
||||
this.loaders[name] = new DataLoader(
|
||||
keys => {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
// Extract queries from keys and merge similar queries.
|
||||
|
||||
@ -23,10 +23,11 @@ module.exports = {
|
||||
// Extract custom resolver or type description.
|
||||
const { resolver: handler = {} } = _schema;
|
||||
|
||||
let queryName = `${action}${_.capitalize(name)}`;
|
||||
|
||||
let queryName;
|
||||
if (_.has(handler, `Mutation.${action}`)) {
|
||||
queryName = action;
|
||||
} else {
|
||||
queryName = `${action}${_.capitalize(name)}`;
|
||||
}
|
||||
|
||||
// Retrieve policies.
|
||||
@ -201,19 +202,8 @@ module.exports = {
|
||||
if (_.isFunction(resolver)) {
|
||||
const normalizedName = _.toLower(name);
|
||||
|
||||
let primaryKey;
|
||||
|
||||
if (plugin) {
|
||||
primaryKey = strapi.plugins[plugin].models[normalizedName].primaryKey;
|
||||
} else {
|
||||
primaryKey = strapi.models[normalizedName].primaryKey;
|
||||
}
|
||||
|
||||
if (options.input && options.input.where) {
|
||||
context.params = Query.convertToParams(
|
||||
options.input.where || {},
|
||||
primaryKey
|
||||
);
|
||||
context.params = Query.convertToParams(options.input.where || {});
|
||||
} else {
|
||||
context.params = {};
|
||||
}
|
||||
|
||||
@ -18,9 +18,9 @@ module.exports = {
|
||||
* @return Object
|
||||
*/
|
||||
|
||||
convertToParams: (params, primaryKey) => {
|
||||
convertToParams: params => {
|
||||
return Object.keys(params).reduce((acc, current) => {
|
||||
const key = current === 'id' ? primaryKey : `_${current}`;
|
||||
const key = current === 'id' ? 'id' : `_${current}`;
|
||||
acc[key] = params[current];
|
||||
return acc;
|
||||
}, {});
|
||||
@ -74,10 +74,6 @@ module.exports = {
|
||||
model: name,
|
||||
};
|
||||
|
||||
const model = plugin
|
||||
? strapi.plugins[plugin].models[name]
|
||||
: strapi.models[name];
|
||||
|
||||
// Extract custom resolver or type description.
|
||||
const { resolver: handler = {} } = _schema;
|
||||
|
||||
@ -190,7 +186,7 @@ module.exports = {
|
||||
return async (ctx, next) => {
|
||||
ctx.params = {
|
||||
...params,
|
||||
[model.primaryKey]: ctx.query[model.primaryKey],
|
||||
id: ctx.query.id,
|
||||
};
|
||||
|
||||
// Return the controller.
|
||||
@ -282,24 +278,12 @@ module.exports = {
|
||||
// cause a lost of the Object prototype.
|
||||
const opts = this.amountLimiting(_options);
|
||||
|
||||
Object.defineProperties(ctx, {
|
||||
query: {
|
||||
value: {
|
||||
...this.convertToParams(
|
||||
_.omit(opts, 'where'),
|
||||
model ? model.primaryKey : 'id'
|
||||
),
|
||||
...this.convertToQuery(opts.where),
|
||||
},
|
||||
writable: true,
|
||||
configurable: true,
|
||||
},
|
||||
params: {
|
||||
value: this.convertToParams(opts, model ? model.primaryKey : 'id'),
|
||||
writable: true,
|
||||
configurable: true,
|
||||
},
|
||||
});
|
||||
ctx.query = {
|
||||
...this.convertToParams(_.omit(opts, 'where')),
|
||||
...this.convertToQuery(opts.where),
|
||||
};
|
||||
|
||||
ctx.params = this.convertToParams(opts);
|
||||
|
||||
if (isController) {
|
||||
const values = await resolver.call(null, ctx, null);
|
||||
|
||||
@ -224,14 +224,20 @@ const schemaBuilder = {
|
||||
|
||||
switch (type) {
|
||||
case 'Mutation': {
|
||||
// TODO: Verify this...
|
||||
const [name, action] = acc[type][resolver].split('.');
|
||||
const normalizedName = _.toLower(name);
|
||||
let name, action;
|
||||
if (_.isString(acc[type][resolver])) {
|
||||
[name, action] = acc[type][resolver].split('.');
|
||||
} else if (
|
||||
_.isPlainObject(acc[type][resolver]) &&
|
||||
_.isString(acc[type][resolver].handler)
|
||||
) {
|
||||
[name, action] = acc[type][resolver].handler.split('.');
|
||||
}
|
||||
|
||||
acc[type][resolver] = Mutation.composeMutationResolver({
|
||||
_schema: strapi.plugins.graphql.config._schema.graphql,
|
||||
plugin,
|
||||
name: normalizedName,
|
||||
name: _.toLower(name),
|
||||
action,
|
||||
});
|
||||
break;
|
||||
|
||||
@ -21,7 +21,6 @@ import WithInput from '../WithInput';
|
||||
/* eslint-disable react/require-default-props */
|
||||
class InputPassword extends React.Component {
|
||||
// eslint-disable-line react/prefer-stateless-function
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
@ -45,7 +45,7 @@ class RowLanguage extends React.Component {
|
||||
onClick={this.handleToggleWarning}
|
||||
id={this.props.name}
|
||||
/>
|
||||
); // eslint-disable-line jsx-a11y/no-static-element-interactions
|
||||
);
|
||||
// format the locale to
|
||||
const defaultLanguageArray = formatLanguageLocale(this.props.name);
|
||||
const flag = getFlag(defaultLanguageArray);
|
||||
|
||||
@ -153,7 +153,6 @@ export class HomePage extends React.Component {
|
||||
}
|
||||
|
||||
/* eslint-disable react/sort-comp */
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
addConnection = e => {
|
||||
e.preventDefault();
|
||||
const newData = {};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-settings-manager",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Strapi plugin to manage settings.",
|
||||
"strapi": {
|
||||
"name": "Settings Manager",
|
||||
@ -27,7 +27,7 @@
|
||||
"redux": "^4.0.1",
|
||||
"reselect": "^3.0.1",
|
||||
"shelljs": "^0.7.8",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3"
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Strapi team",
|
||||
|
||||
@ -11,7 +11,6 @@ import Label from './Label';
|
||||
import P from './P';
|
||||
|
||||
/* eslint-disable react/no-string-refs */
|
||||
/* eslint-disable jsx-a11y/label-has-for */
|
||||
/* eslint-disable react/jsx-tag-spacing */
|
||||
class PluginInputFile extends React.PureComponent {
|
||||
state = { isDraging: false };
|
||||
|
||||
@ -23,7 +23,10 @@ module.exports = {
|
||||
Query: {
|
||||
file: false,
|
||||
files: {
|
||||
resolver: 'Upload.find',
|
||||
resolver: {
|
||||
plugin: 'upload',
|
||||
handler: 'Upload.find'
|
||||
}
|
||||
},
|
||||
},
|
||||
Mutation: {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-upload",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "This is the description of the plugin.",
|
||||
"strapi": {
|
||||
"name": "Files Upload",
|
||||
@ -23,9 +23,9 @@
|
||||
"react-router-dom": "^5.0.0",
|
||||
"react-transition-group": "^2.5.0",
|
||||
"reactstrap": "^5.0.0",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-provider-upload-local": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"strapi-provider-upload-local": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4",
|
||||
"stream-to-array": "^2.3.0",
|
||||
"uuid": "^3.2.1"
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-plugin-users-permissions",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Protect your API with a full-authentication process based on JWT",
|
||||
"strapi": {
|
||||
"name": "Roles & Permissions",
|
||||
@ -31,8 +31,8 @@
|
||||
"reactstrap": "^5.0.0",
|
||||
"redux-saga": "^0.16.0",
|
||||
"request": "^2.83.0",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3",
|
||||
"strapi-helper-plugin": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4",
|
||||
"uuid": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
/* eslint-disable prefer-template */
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-email-amazon-ses",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Amazon SES provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
/* eslint-disable prefer-template */
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-email-mailgun",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Mailgun provider for strapi email plugin",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
/* eslint-disable prefer-template */
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-email-sendgrid",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Sendgrid provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-email-sendmail",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Sendmail provider for strapi email",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
/* eslint-disable no-unused-vars */
|
||||
// Public node modules.
|
||||
const _ = require('lodash');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-upload-aws-s3",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "AWS S3 provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
// Public node modules.
|
||||
/* eslint-disable import/no-unresolved */
|
||||
/* eslint-disable prefer-template */
|
||||
const cloudinary = require('cloudinary').v2;
|
||||
const intoStream = require('into-stream');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-upload-cloudinary",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Cloudinary provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-upload-local",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Local provider for strapi upload",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
// Public node modules.
|
||||
const pkgcloud = require('pkgcloud');
|
||||
const streamifier = require('streamifier');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-provider-upload-rackspace",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Rackspace provider for strapi upload",
|
||||
"main": "./lib",
|
||||
"keywords": [],
|
||||
|
||||
@ -15,7 +15,7 @@ module.exports = (api, controller) => {
|
||||
throw new Error('Should be an object');
|
||||
}
|
||||
|
||||
if (_.isObject(controller) && controller.hasOwnProperty('identity')) {
|
||||
if (_.isObject(controller) && _.has(controller, 'identity')) {
|
||||
controller = controller.identity.toLowerCase();
|
||||
} else if (_.isString(controller)) {
|
||||
controller = controller.toLowerCase();
|
||||
|
||||
@ -52,9 +52,9 @@ module.exports = {
|
||||
}
|
||||
|
||||
if (
|
||||
(association.hasOwnProperty('collection') &&
|
||||
(_.has(association, 'collection') &&
|
||||
association.collection === '*') ||
|
||||
(association.hasOwnProperty('model') && association.model === '*')
|
||||
(_.has(association, 'model') && association.model === '*')
|
||||
) {
|
||||
if (association.model) {
|
||||
types.current = 'morphToD';
|
||||
@ -80,16 +80,16 @@ module.exports = {
|
||||
_.forIn(allModels, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (
|
||||
attribute.hasOwnProperty('via') &&
|
||||
_.has(attribute, 'via') &&
|
||||
attribute.via === key &&
|
||||
attribute.model === currentModelName
|
||||
) {
|
||||
if (attribute.hasOwnProperty('collection')) {
|
||||
if (_.has(attribute, 'collection')) {
|
||||
types.other = 'collection';
|
||||
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (attribute.hasOwnProperty('model')) {
|
||||
} else if (_.has(attribute, 'model')) {
|
||||
types.other = 'model';
|
||||
|
||||
// Break loop
|
||||
@ -99,8 +99,8 @@ module.exports = {
|
||||
});
|
||||
});
|
||||
} else if (
|
||||
association.hasOwnProperty('via') &&
|
||||
association.hasOwnProperty('collection')
|
||||
_.has(association, 'via') &&
|
||||
_.has(association, 'collection')
|
||||
) {
|
||||
const relatedAttribute =
|
||||
models[association.collection].attributes[association.via];
|
||||
@ -120,31 +120,31 @@ module.exports = {
|
||||
types.current = 'collection';
|
||||
|
||||
if (
|
||||
relatedAttribute.hasOwnProperty('collection') &&
|
||||
_.has(relatedAttribute, 'collection') &&
|
||||
relatedAttribute.collection !== '*' &&
|
||||
relatedAttribute.hasOwnProperty('via')
|
||||
_.has(relatedAttribute, 'via')
|
||||
) {
|
||||
types.other = 'collection';
|
||||
} else if (
|
||||
relatedAttribute.hasOwnProperty('collection') &&
|
||||
_.has(relatedAttribute, 'collection') &&
|
||||
relatedAttribute.collection !== '*' &&
|
||||
!relatedAttribute.hasOwnProperty('via')
|
||||
!_.has(relatedAttribute, 'via')
|
||||
) {
|
||||
types.other = 'collectionD';
|
||||
} else if (
|
||||
relatedAttribute.hasOwnProperty('model') &&
|
||||
_.has(relatedAttribute, 'model') &&
|
||||
relatedAttribute.model !== '*'
|
||||
) {
|
||||
types.other = 'model';
|
||||
} else if (
|
||||
relatedAttribute.hasOwnProperty('collection') ||
|
||||
relatedAttribute.hasOwnProperty('model')
|
||||
_.has(relatedAttribute, 'collection') ||
|
||||
_.has(relatedAttribute, 'model')
|
||||
) {
|
||||
types.other = 'morphTo';
|
||||
}
|
||||
} else if (
|
||||
association.hasOwnProperty('via') &&
|
||||
association.hasOwnProperty('model')
|
||||
_.has(association, 'via') &&
|
||||
_.has(association, 'model')
|
||||
) {
|
||||
types.current = 'modelD';
|
||||
|
||||
@ -153,32 +153,32 @@ module.exports = {
|
||||
const attribute = model.attributes[association.via];
|
||||
|
||||
if (
|
||||
attribute.hasOwnProperty('via') &&
|
||||
_.has(attribute, 'via') &&
|
||||
attribute.via === key &&
|
||||
attribute.hasOwnProperty('collection') &&
|
||||
_.has(attribute, 'collection') &&
|
||||
attribute.collection !== '*'
|
||||
) {
|
||||
types.other = 'collection';
|
||||
} else if (
|
||||
attribute.hasOwnProperty('model') &&
|
||||
_.has(attribute, 'model') &&
|
||||
attribute.model !== '*'
|
||||
) {
|
||||
types.other = 'model';
|
||||
} else if (
|
||||
attribute.hasOwnProperty('collection') ||
|
||||
attribute.hasOwnProperty('model')
|
||||
_.has(attribute, 'collection') ||
|
||||
_.has(attribute, 'model')
|
||||
) {
|
||||
types.other = 'morphTo';
|
||||
}
|
||||
} else if (association.hasOwnProperty('model')) {
|
||||
} else if (_.has(association, 'model')) {
|
||||
types.current = 'model';
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(models, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (_.has(attribute, 'via') && attribute.via === key) {
|
||||
if (
|
||||
attribute.hasOwnProperty('collection') &&
|
||||
_.has(attribute, 'collection') &&
|
||||
attribute.collection === currentModelName
|
||||
) {
|
||||
types.other = 'collection';
|
||||
@ -186,7 +186,7 @@ module.exports = {
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (
|
||||
attribute.hasOwnProperty('model') &&
|
||||
_.has(attribute, 'model') &&
|
||||
attribute.model === currentModelName
|
||||
) {
|
||||
types.other = 'modelD';
|
||||
@ -197,15 +197,15 @@ module.exports = {
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (association.hasOwnProperty('collection')) {
|
||||
} else if (_.has(association, 'collection')) {
|
||||
types.current = 'collectionD';
|
||||
|
||||
// We have to find if they are a model linked to this key
|
||||
_.forIn(models, model => {
|
||||
_.forIn(model.attributes, attribute => {
|
||||
if (attribute.hasOwnProperty('via') && attribute.via === key) {
|
||||
if (_.has(attribute, 'via') && attribute.via === key) {
|
||||
if (
|
||||
attribute.hasOwnProperty('collection') &&
|
||||
_.has(attribute, 'collection') &&
|
||||
attribute.collection === currentModelName
|
||||
) {
|
||||
types.other = 'collection';
|
||||
@ -213,7 +213,7 @@ module.exports = {
|
||||
// Break loop
|
||||
return false;
|
||||
} else if (
|
||||
attribute.hasOwnProperty('model') &&
|
||||
_.has(attribute, 'model') &&
|
||||
attribute.model === currentModelName
|
||||
) {
|
||||
types.other = 'modelD';
|
||||
@ -258,7 +258,7 @@ module.exports = {
|
||||
};
|
||||
} else if (
|
||||
types.current === 'morphTo' &&
|
||||
(types.other === 'model' || association.hasOwnProperty('model'))
|
||||
(types.other === 'model' || _.has(association, 'model'))
|
||||
) {
|
||||
return {
|
||||
nature: 'manyMorphToOne',
|
||||
@ -267,7 +267,7 @@ module.exports = {
|
||||
} else if (
|
||||
types.current === 'morphTo' &&
|
||||
(types.other === 'collection' ||
|
||||
association.hasOwnProperty('collection'))
|
||||
_.has(association, 'collection'))
|
||||
) {
|
||||
return {
|
||||
nature: 'manyMorphToMany',
|
||||
@ -557,7 +557,7 @@ module.exports = {
|
||||
}, {})
|
||||
);
|
||||
|
||||
if (!models.hasOwnProperty(model)) {
|
||||
if (!_.has(models, model)) {
|
||||
return this.log.error(`The model ${model} can't be found.`);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi-utils",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.4",
|
||||
"description": "Shared utilities for the Strapi packages",
|
||||
"homepage": "http://strapi.io",
|
||||
"keywords": [
|
||||
|
||||
@ -89,6 +89,14 @@ const productFixtures = [
|
||||
rank: 99,
|
||||
big_rank: '999999999999',
|
||||
},
|
||||
{
|
||||
name: 'Продукт 5, Product 5',
|
||||
description: 'Опис на продукт 5',
|
||||
price: null,
|
||||
decimal_field: 142.43,
|
||||
rank: 142,
|
||||
big_rank: 345678912983,
|
||||
},
|
||||
];
|
||||
|
||||
async function createFixtures() {
|
||||
@ -203,7 +211,7 @@ describe('Filtering API', () => {
|
||||
});
|
||||
|
||||
describe('Filter null', () => {
|
||||
test('Should return only one match', async () => {
|
||||
test('Should return only matching items', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/products',
|
||||
@ -212,9 +220,12 @@ describe('Filtering API', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const matching = data.products.filter(x => x.price === null);
|
||||
res.body.sort((a, b) => (a.id > b.id ? 1 : -1));
|
||||
expect(Array.isArray(res.body)).toBe(true);
|
||||
expect(res.body.length).toBe(1);
|
||||
expect(res.body[0]).toMatchObject(data.products[3]);
|
||||
expect(res.body.length).toBe(matching.length);
|
||||
expect(res.body).toMatchObject(matching);
|
||||
expect(res.body).toEqual(expect.arrayContaining(matching));
|
||||
});
|
||||
|
||||
test('Should return three matches', async () => {
|
||||
@ -983,7 +994,9 @@ describe('Filtering API', () => {
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(
|
||||
data.products.slice(0).sort((a, b) => a.rank - b.rank)
|
||||
expect.arrayContaining(
|
||||
data.products.slice(0).sort((a, b) => a.rank - b.rank)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
@ -997,7 +1010,9 @@ describe('Filtering API', () => {
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(
|
||||
data.products.slice(0).sort((a, b) => a.rank - b.rank)
|
||||
expect.arrayContaining(
|
||||
data.products.slice(0).sort((a, b) => a.rank - b.rank)
|
||||
)
|
||||
);
|
||||
|
||||
const res2 = await rq({
|
||||
@ -1009,7 +1024,9 @@ describe('Filtering API', () => {
|
||||
});
|
||||
|
||||
expect(res2.body).toEqual(
|
||||
data.products.slice(0).sort((a, b) => b.rank - a.rank)
|
||||
expect.arrayContaining(
|
||||
data.products.slice(0).sort((a, b) => b.rank - a.rank)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
@ -1043,7 +1060,7 @@ describe('Filtering API', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual([data.products[0]]);
|
||||
expect(res.body).toEqual(expect.arrayContaining([data.products[0]]));
|
||||
});
|
||||
|
||||
test('Limit with sorting', async () => {
|
||||
@ -1056,7 +1073,9 @@ describe('Filtering API', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual([data.products[data.products.length - 1]]);
|
||||
expect(res.body).toEqual(
|
||||
expect.arrayContaining([data.products[data.products.length - 1]])
|
||||
);
|
||||
});
|
||||
|
||||
test('Offset', async () => {
|
||||
@ -1068,7 +1087,7 @@ describe('Filtering API', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(data.products.slice(1));
|
||||
expect(res.body).toEqual(expect.arrayContaining(data.products.slice(1)));
|
||||
});
|
||||
|
||||
test('Offset with limit', async () => {
|
||||
@ -1081,7 +1100,47 @@ describe('Filtering API', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(data.products.slice(1, 2));
|
||||
expect(res.body).toEqual(
|
||||
expect.arrayContaining(data.products.slice(1, 2))
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Text query', () => {
|
||||
test('Cyrillic query', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/products',
|
||||
qs: {
|
||||
_q: 'Опис',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(expect.arrayContaining([data.products[4]]));
|
||||
});
|
||||
|
||||
test('Multi word query', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/products',
|
||||
qs: {
|
||||
_q: 'Product description',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(expect.arrayContaining([data.products[0]]));
|
||||
});
|
||||
|
||||
test('Multi word cyrillic query', async () => {
|
||||
const res = await rq({
|
||||
method: 'GET',
|
||||
url: '/products',
|
||||
qs: {
|
||||
_q: 'Опис на продукт',
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.body).toEqual(expect.arrayContaining([data.products[4]]));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
4
packages/strapi/lib/core/bootstrap.js
vendored
4
packages/strapi/lib/core/bootstrap.js
vendored
@ -265,7 +265,7 @@ module.exports = function(strapi) {
|
||||
);
|
||||
acc[current] = !_.isObject(currentSettings) ? {} : currentSettings;
|
||||
|
||||
if (!acc[current].hasOwnProperty('enabled')) {
|
||||
if (!_.has(acc[current], 'enabled')) {
|
||||
strapi.log.warn(
|
||||
`(middleware:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
|
||||
);
|
||||
@ -291,7 +291,7 @@ module.exports = function(strapi) {
|
||||
|
||||
acc[current] = !_.isObject(currentSettings) ? {} : currentSettings;
|
||||
|
||||
if (!acc[current].hasOwnProperty('enabled')) {
|
||||
if (!_.has(acc[current], 'enabled')) {
|
||||
strapi.log.warn(
|
||||
`(hook:${current}) wasn't loaded due to missing key \`enabled\` in the configuration`
|
||||
);
|
||||
|
||||
@ -54,7 +54,7 @@ module.exports = strapi => {
|
||||
// Exclude routes with prefix.
|
||||
const excludedRoutes = _.omitBy(
|
||||
plugin.config.routes,
|
||||
o => !o.config.hasOwnProperty('prefix')
|
||||
o => !_.has(o.config, 'prefix')
|
||||
);
|
||||
|
||||
_.forEach(
|
||||
|
||||
@ -24,7 +24,7 @@ module.exports = strapi => {
|
||||
strapi.config.hooks.session.secretKeys;
|
||||
|
||||
if (
|
||||
strapi.config.middleware.settings.session.hasOwnProperty('client') &&
|
||||
_.has(strapi.config.middleware.settings.session, 'client') &&
|
||||
_.isString(strapi.config.middleware.settings.session.client) &&
|
||||
strapi.config.middleware.settings.session.client !== 'cookie'
|
||||
) {
|
||||
@ -52,7 +52,7 @@ module.exports = strapi => {
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
strapi.config.middleware.settings.session.hasOwnProperty('client') &&
|
||||
_.has(strapi.config.middleware.settings.session, 'client') &&
|
||||
_.isString(strapi.config.middleware.settings.session.client) &&
|
||||
strapi.config.middleware.settings.session.client === 'cookie'
|
||||
) {
|
||||
@ -159,6 +159,7 @@ module.exports = strapi => {
|
||||
},
|
||||
|
||||
requireStore(store) {
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
try {
|
||||
return require(path.resolve(
|
||||
strapi.config.appPath,
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable import/order */
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* eslint-disable prefer-template */
|
||||
// Dependencies.
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { map } = require('async'); // eslint-disable-line import/order
|
||||
const { map } = require('async');
|
||||
const {
|
||||
setWith,
|
||||
merge,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "strapi",
|
||||
"version": "3.0.0-beta.16.3",
|
||||
"version": "3.0.0-beta.16.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": {
|
||||
@ -47,15 +47,15 @@
|
||||
"resolve-cwd": "^3.0.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"shelljs": "^0.8.3",
|
||||
"strapi-generate": "3.0.0-beta.16.3",
|
||||
"strapi-generate-api": "3.0.0-beta.16.3",
|
||||
"strapi-generate-controller": "3.0.0-beta.16.3",
|
||||
"strapi-generate-model": "3.0.0-beta.16.3",
|
||||
"strapi-generate-new": "3.0.0-beta.16.3",
|
||||
"strapi-generate-plugin": "3.0.0-beta.16.3",
|
||||
"strapi-generate-policy": "3.0.0-beta.16.3",
|
||||
"strapi-generate-service": "3.0.0-beta.16.3",
|
||||
"strapi-utils": "3.0.0-beta.16.3"
|
||||
"strapi-generate": "3.0.0-beta.16.4",
|
||||
"strapi-generate-api": "3.0.0-beta.16.4",
|
||||
"strapi-generate-controller": "3.0.0-beta.16.4",
|
||||
"strapi-generate-model": "3.0.0-beta.16.4",
|
||||
"strapi-generate-new": "3.0.0-beta.16.4",
|
||||
"strapi-generate-plugin": "3.0.0-beta.16.4",
|
||||
"strapi-generate-policy": "3.0.0-beta.16.4",
|
||||
"strapi-generate-service": "3.0.0-beta.16.4",
|
||||
"strapi-utils": "3.0.0-beta.16.4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest --verbose",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user