mirror of
https://github.com/strapi/strapi.git
synced 2025-09-21 14:31:16 +00:00
Merge branch 'main' into features/deits
This commit is contained in:
commit
e47dfb35ae
1
.github/workflows/addToProject.yml
vendored
1
.github/workflows/addToProject.yml
vendored
@ -6,6 +6,7 @@ on:
|
|||||||
- opened
|
- opened
|
||||||
- transferred
|
- transferred
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
jobs:
|
jobs:
|
||||||
add-to-project:
|
add-to-project:
|
||||||
name: Add issue to Support Team project
|
name: Add issue to Support Team project
|
||||||
|
6
.github/workflows/checks.yml
vendored
6
.github/workflows/checks.yml
vendored
@ -17,8 +17,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/check-pr-status
|
- uses: ./.github/actions/check-pr-status
|
||||||
|
|
||||||
security-lockfile-analysis:
|
security-lockfile-analysis:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
cache: yarn
|
||||||
- uses: ./.github/actions/security/lockfile
|
- uses: ./.github/actions/security/lockfile
|
||||||
|
4
.github/workflows/contributor-doc.yml
vendored
4
.github/workflows/contributor-doc.yml
vendored
@ -17,8 +17,12 @@ defaults:
|
|||||||
run:
|
run:
|
||||||
working-directory: docs
|
working-directory: docs
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
|
permissions:
|
||||||
|
contents: write # to push pages branch (peaceiris/actions-gh-pages)
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
name: github-pages
|
name: github-pages
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
3
.github/workflows/nightly.yml
vendored
3
.github/workflows/nightly.yml
vendored
@ -5,6 +5,9 @@ on:
|
|||||||
- cron: '0 0 * * 2-6'
|
- cron: '0 0 * * 2-6'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # to fetch code (actions/checkout)
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
name: 'Publish'
|
name: 'Publish'
|
||||||
|
56
.github/workflows/tests.yml
vendored
56
.github/workflows/tests.yml
vendored
@ -13,6 +13,9 @@ concurrency:
|
|||||||
group: ${{ github.workflow }}-${{ github.ref_name }}
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # to fetch code (actions/checkout)
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
name: 'lint (node: ${{ matrix.node }})'
|
name: 'lint (node: ${{ matrix.node }})'
|
||||||
@ -25,7 +28,11 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Run lint
|
- name: Run lint
|
||||||
run: yarn run -s lint
|
run: yarn run -s lint
|
||||||
@ -42,7 +49,11 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: yarn run -s test:unit --coverage
|
run: yarn run -s test:unit --coverage
|
||||||
@ -65,7 +76,11 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- name: Build
|
- name: Build
|
||||||
run: yarn build
|
run: yarn build
|
||||||
@ -109,7 +124,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
with:
|
with:
|
||||||
@ -144,7 +162,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
with:
|
with:
|
||||||
@ -179,7 +200,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
with:
|
with:
|
||||||
@ -198,7 +222,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
env:
|
env:
|
||||||
@ -240,7 +267,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
with:
|
with:
|
||||||
@ -278,7 +308,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
with:
|
with:
|
||||||
@ -301,7 +334,10 @@ jobs:
|
|||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: '**/node_modules'
|
||||||
|
key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
- run: yarn install --frozen-lockfile
|
- run: yarn install --frozen-lockfile
|
||||||
- uses: ./.github/actions/run-api-tests
|
- uses: ./.github/actions/run-api-tests
|
||||||
env:
|
env:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"description": "Generate a new Strapi application.",
|
"description": "Generate a new Strapi application.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strapi/generate-new": "4.5.2",
|
"@strapi/generate-new": "4.5.2",
|
||||||
"commander": "6.1.0",
|
"commander": "7.2.0",
|
||||||
"inquirer": "8.2.4"
|
"inquirer": "8.2.4"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
"@strapi/generate-new": "4.5.2",
|
"@strapi/generate-new": "4.5.2",
|
||||||
"chalk": "4.1.1",
|
"chalk": "4.1.1",
|
||||||
"ci-info": "3.5.0",
|
"ci-info": "3.5.0",
|
||||||
"commander": "7.1.0",
|
"commander": "7.2.0",
|
||||||
"execa": "5.1.1",
|
"execa": "5.1.1",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"inquirer": "8.2.4",
|
"inquirer": "8.2.4",
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
||||||
|
import Inputs from '../../../components/Inputs';
|
||||||
|
import FieldComponent from '../../../components/FieldComponent';
|
||||||
|
|
||||||
|
const GridRow = ({ columns }) => {
|
||||||
|
return (
|
||||||
|
<Grid gap={4}>
|
||||||
|
{columns.map(({ fieldSchema, labelAction, metadatas, name, size, queryInfos }) => {
|
||||||
|
const isComponent = fieldSchema.type === 'component';
|
||||||
|
|
||||||
|
if (isComponent) {
|
||||||
|
const { component, max, min, repeatable = false, required = false } = fieldSchema;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GridItem col={size} s={12} xs={12} key={component}>
|
||||||
|
<FieldComponent
|
||||||
|
componentUid={component}
|
||||||
|
labelAction={labelAction}
|
||||||
|
isRepeatable={repeatable}
|
||||||
|
intlLabel={{
|
||||||
|
id: metadatas.label,
|
||||||
|
defaultMessage: metadatas.label,
|
||||||
|
}}
|
||||||
|
max={max}
|
||||||
|
min={min}
|
||||||
|
name={name}
|
||||||
|
required={required}
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GridItem col={size} key={name} s={12} xs={12}>
|
||||||
|
<Inputs
|
||||||
|
size={size}
|
||||||
|
fieldSchema={fieldSchema}
|
||||||
|
keys={name}
|
||||||
|
labelAction={labelAction}
|
||||||
|
metadatas={metadatas}
|
||||||
|
queryInfos={queryInfos}
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
GridRow.propTypes = {
|
||||||
|
columns: PropTypes.array.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GridRow;
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Suspense, memo, useCallback, useMemo } from 'react';
|
import React, { Suspense, memo } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import get from 'lodash/get';
|
import { useSelector } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
CheckPermissions,
|
CheckPermissions,
|
||||||
LoadingIndicatorPage,
|
LoadingIndicatorPage,
|
||||||
@ -18,8 +18,7 @@ import Pencil from '@strapi/icons/Pencil';
|
|||||||
import { InjectionZone } from '../../../shared/components';
|
import { InjectionZone } from '../../../shared/components';
|
||||||
import permissions from '../../../permissions';
|
import permissions from '../../../permissions';
|
||||||
import DynamicZone from '../../components/DynamicZone';
|
import DynamicZone from '../../components/DynamicZone';
|
||||||
import FieldComponent from '../../components/FieldComponent';
|
|
||||||
import Inputs from '../../components/Inputs';
|
|
||||||
import CollectionTypeFormWrapper from '../../components/CollectionTypeFormWrapper';
|
import CollectionTypeFormWrapper from '../../components/CollectionTypeFormWrapper';
|
||||||
import EditViewDataManagerProvider from '../../components/EditViewDataManagerProvider';
|
import EditViewDataManagerProvider from '../../components/EditViewDataManagerProvider';
|
||||||
import SingleTypeFormWrapper from '../../components/SingleTypeFormWrapper';
|
import SingleTypeFormWrapper from '../../components/SingleTypeFormWrapper';
|
||||||
@ -27,64 +26,43 @@ import { getTrad } from '../../utils';
|
|||||||
import DraftAndPublishBadge from './DraftAndPublishBadge';
|
import DraftAndPublishBadge from './DraftAndPublishBadge';
|
||||||
import Informations from './Informations';
|
import Informations from './Informations';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import { createAttributesLayout, getFieldsActionMatchingPermissions } from './utils';
|
import { getFieldsActionMatchingPermissions } from './utils';
|
||||||
import DeleteLink from './DeleteLink';
|
import DeleteLink from './DeleteLink';
|
||||||
|
import GridRow from './GridRow';
|
||||||
|
import { selectCurrentLayout, selectAttributesLayout } from './selectors';
|
||||||
|
|
||||||
const cmPermissions = permissions.contentManager;
|
const cmPermissions = permissions.contentManager;
|
||||||
const ctbPermissions = [{ action: 'plugin::content-type-builder.read', subject: null }];
|
const ctbPermissions = [{ action: 'plugin::content-type-builder.read', subject: null }];
|
||||||
|
|
||||||
/* eslint-disable react/no-array-index-key */
|
/* eslint-disable react/no-array-index-key */
|
||||||
const EditView = ({
|
const EditView = ({ allowedActions, isSingleType, goBack, slug, id, origin, userPermissions }) => {
|
||||||
allowedActions,
|
|
||||||
isSingleType,
|
|
||||||
goBack,
|
|
||||||
layout,
|
|
||||||
slug,
|
|
||||||
id,
|
|
||||||
origin,
|
|
||||||
userPermissions,
|
|
||||||
}) => {
|
|
||||||
const { trackUsage } = useTracking();
|
const { trackUsage } = useTracking();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const { createActionAllowedFields, readActionAllowedFields, updateActionAllowedFields } =
|
const { createActionAllowedFields, readActionAllowedFields, updateActionAllowedFields } =
|
||||||
useMemo(() => {
|
getFieldsActionMatchingPermissions(userPermissions, slug);
|
||||||
return getFieldsActionMatchingPermissions(userPermissions, slug);
|
|
||||||
}, [userPermissions, slug]);
|
|
||||||
|
|
||||||
const configurationPermissions = useMemo(() => {
|
const { layout, formattedContentTypeLayout } = useSelector((state) => ({
|
||||||
return isSingleType
|
layout: selectCurrentLayout(state),
|
||||||
? cmPermissions.singleTypesConfigurations
|
formattedContentTypeLayout: selectAttributesLayout(state),
|
||||||
: cmPermissions.collectionTypesConfigurations;
|
}));
|
||||||
}, [isSingleType]);
|
|
||||||
|
const configurationPermissions = isSingleType
|
||||||
|
? cmPermissions.singleTypesConfigurations
|
||||||
|
: cmPermissions.collectionTypesConfigurations;
|
||||||
|
|
||||||
// // FIXME when changing the routing
|
// // FIXME when changing the routing
|
||||||
const configurationsURL = `/content-manager/${
|
const configurationsURL = `/content-manager/${
|
||||||
isSingleType ? 'singleType' : 'collectionType'
|
isSingleType ? 'singleType' : 'collectionType'
|
||||||
}/${slug}/configurations/edit`;
|
}/${slug}/configurations/edit`;
|
||||||
const currentContentTypeLayoutData = get(layout, ['contentType'], {});
|
|
||||||
|
|
||||||
const DataManagementWrapper = useMemo(
|
const DataManagementWrapper = isSingleType ? SingleTypeFormWrapper : CollectionTypeFormWrapper;
|
||||||
() => (isSingleType ? SingleTypeFormWrapper : CollectionTypeFormWrapper),
|
|
||||||
[isSingleType]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if a block is a dynamic zone
|
// Check if a block is a dynamic zone
|
||||||
const isDynamicZone = useCallback((block) => {
|
const isDynamicZone = (block) => {
|
||||||
return block.every((subBlock) => {
|
return block.every((subBlock) => {
|
||||||
return subBlock.every((obj) => obj.fieldSchema.type === 'dynamiczone');
|
return subBlock.every((obj) => obj.fieldSchema.type === 'dynamiczone');
|
||||||
});
|
});
|
||||||
}, []);
|
};
|
||||||
|
|
||||||
const formattedContentTypeLayout = useMemo(() => {
|
|
||||||
if (!currentContentTypeLayoutData.layouts) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return createAttributesLayout(
|
|
||||||
currentContentTypeLayoutData.layouts.edit,
|
|
||||||
currentContentTypeLayoutData.attributes
|
|
||||||
);
|
|
||||||
}, [currentContentTypeLayoutData]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataManagementWrapper allLayoutData={layout} slug={slug} id={id} origin={origin}>
|
<DataManagementWrapper allLayoutData={layout} slug={slug} id={id} origin={origin}>
|
||||||
@ -171,65 +149,9 @@ const EditView = ({
|
|||||||
borderColor="neutral150"
|
borderColor="neutral150"
|
||||||
>
|
>
|
||||||
<Stack spacing={6}>
|
<Stack spacing={6}>
|
||||||
{row.map((grid, gridIndex) => {
|
{row.map((grid, gridRowIndex) => (
|
||||||
return (
|
<GridRow columns={grid} key={gridRowIndex} />
|
||||||
<Grid gap={4} key={gridIndex}>
|
))}
|
||||||
{grid.map(
|
|
||||||
({
|
|
||||||
fieldSchema,
|
|
||||||
labelAction,
|
|
||||||
metadatas,
|
|
||||||
name,
|
|
||||||
size,
|
|
||||||
queryInfos,
|
|
||||||
}) => {
|
|
||||||
const isComponent = fieldSchema.type === 'component';
|
|
||||||
|
|
||||||
if (isComponent) {
|
|
||||||
const {
|
|
||||||
component,
|
|
||||||
max,
|
|
||||||
min,
|
|
||||||
repeatable = false,
|
|
||||||
required = false,
|
|
||||||
} = fieldSchema;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<GridItem col={size} s={12} xs={12} key={component}>
|
|
||||||
<FieldComponent
|
|
||||||
componentUid={component}
|
|
||||||
labelAction={labelAction}
|
|
||||||
isRepeatable={repeatable}
|
|
||||||
intlLabel={{
|
|
||||||
id: metadatas.label,
|
|
||||||
defaultMessage: metadatas.label,
|
|
||||||
}}
|
|
||||||
max={max}
|
|
||||||
min={min}
|
|
||||||
name={name}
|
|
||||||
required={required}
|
|
||||||
/>
|
|
||||||
</GridItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<GridItem col={size} key={name} s={12} xs={12}>
|
|
||||||
<Inputs
|
|
||||||
size={size}
|
|
||||||
fieldSchema={fieldSchema}
|
|
||||||
keys={name}
|
|
||||||
labelAction={labelAction}
|
|
||||||
metadatas={metadatas}
|
|
||||||
queryInfos={queryInfos}
|
|
||||||
/>
|
|
||||||
</GridItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -328,16 +250,6 @@ EditView.propTypes = {
|
|||||||
canCreate: PropTypes.bool.isRequired,
|
canCreate: PropTypes.bool.isRequired,
|
||||||
canDelete: PropTypes.bool.isRequired,
|
canDelete: PropTypes.bool.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
layout: PropTypes.shape({
|
|
||||||
components: PropTypes.object.isRequired,
|
|
||||||
contentType: PropTypes.shape({
|
|
||||||
uid: PropTypes.string.isRequired,
|
|
||||||
settings: PropTypes.object.isRequired,
|
|
||||||
metadatas: PropTypes.object.isRequired,
|
|
||||||
options: PropTypes.object.isRequired,
|
|
||||||
attributes: PropTypes.object.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
isSingleType: PropTypes.bool,
|
isSingleType: PropTypes.bool,
|
||||||
goBack: PropTypes.func.isRequired,
|
goBack: PropTypes.func.isRequired,
|
||||||
@ -346,7 +258,4 @@ EditView.propTypes = {
|
|||||||
userPermissions: PropTypes.array,
|
userPermissions: PropTypes.array,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { EditView };
|
|
||||||
export default memo(EditView);
|
export default memo(EditView);
|
||||||
|
|
||||||
// export default () => 'TODO Edit view';
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import { createAttributesLayout } from './utils';
|
||||||
|
|
||||||
|
const selectCurrentLayout = (state) => state['content-manager_editViewLayoutManager'].currentLayout;
|
||||||
|
|
||||||
|
const selectAttributesLayout = createSelector(selectCurrentLayout, (layout) =>
|
||||||
|
createAttributesLayout(layout?.contentType ?? {})
|
||||||
|
);
|
||||||
|
|
||||||
|
export { selectCurrentLayout, selectAttributesLayout };
|
@ -1,14 +1,19 @@
|
|||||||
import { get, isEmpty } from 'lodash';
|
import { get, isEmpty } from 'lodash';
|
||||||
// TODO: refacto this file to avoid eslint issues
|
|
||||||
/* eslint-disable no-restricted-syntax */
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
|
|
||||||
const createAttributesLayout = (currentLayout, attributes) => {
|
const createAttributesLayout = (currentContentTypeLayoutData) => {
|
||||||
|
if (!currentContentTypeLayoutData.layouts) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentLayout = currentContentTypeLayoutData.layouts.edit;
|
||||||
|
const attributes = currentContentTypeLayoutData.attributes;
|
||||||
|
|
||||||
const getType = (name) => get(attributes, [name, 'type'], '');
|
const getType = (name) => get(attributes, [name, 'type'], '');
|
||||||
|
|
||||||
let currentRowIndex = 0;
|
let currentRowIndex = 0;
|
||||||
const newLayout = [];
|
const newLayout = [];
|
||||||
|
|
||||||
for (let row of currentLayout) {
|
currentLayout.forEach((row) => {
|
||||||
const hasDynamicZone = row.some(({ name }) => getType(name) === 'dynamiczone');
|
const hasDynamicZone = row.some(({ name }) => getType(name) === 'dynamiczone');
|
||||||
|
|
||||||
if (!newLayout[currentRowIndex]) {
|
if (!newLayout[currentRowIndex]) {
|
||||||
@ -27,7 +32,7 @@ const createAttributesLayout = (currentLayout, attributes) => {
|
|||||||
} else {
|
} else {
|
||||||
newLayout[currentRowIndex].push(row);
|
newLayout[currentRowIndex].push(row);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return newLayout.filter((arr) => arr.length > 0);
|
return newLayout.filter((arr) => arr.length > 0);
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,12 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[{ name: 'postal_code', size: 6 }],
|
[{ name: 'postal_code', size: 6 }],
|
||||||
[{ name: 'geolocation', size: 12 }],
|
[{ name: 'geolocation', size: 12 }],
|
||||||
];
|
];
|
||||||
|
const currentLayoutData = {
|
||||||
|
layouts: {
|
||||||
|
edit: currentLayout,
|
||||||
|
},
|
||||||
|
attributes,
|
||||||
|
};
|
||||||
const expected = [
|
const expected = [
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
@ -38,7 +44,7 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(createAttributesLayout(currentLayout, attributes)).toEqual(expected);
|
expect(createAttributesLayout(currentLayoutData)).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should return an array of size 2 if there is a dynamic zone at the end of the layout', () => {
|
it('Should return an array of size 2 if there is a dynamic zone at the end of the layout', () => {
|
||||||
@ -68,6 +74,12 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[{ name: 'geolocation', size: 12 }],
|
[{ name: 'geolocation', size: 12 }],
|
||||||
[{ name: 'dynamicZone1', size: 12 }],
|
[{ name: 'dynamicZone1', size: 12 }],
|
||||||
];
|
];
|
||||||
|
const currentLayoutData = {
|
||||||
|
layouts: {
|
||||||
|
edit: currentLayout,
|
||||||
|
},
|
||||||
|
attributes,
|
||||||
|
};
|
||||||
const expected = [
|
const expected = [
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
@ -80,7 +92,7 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[[{ name: 'dynamicZone1', size: 12 }]],
|
[[{ name: 'dynamicZone1', size: 12 }]],
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(createAttributesLayout(currentLayout, attributes)).toEqual(expected);
|
expect(createAttributesLayout(currentLayoutData)).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should return an array of size 2 if there is a dynamic zone at the beginning of the layout', () => {
|
it('Should return an array of size 2 if there is a dynamic zone at the beginning of the layout', () => {
|
||||||
@ -114,6 +126,12 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[{ name: 'postal_code', size: 6 }],
|
[{ name: 'postal_code', size: 6 }],
|
||||||
[{ name: 'geolocation', size: 12 }],
|
[{ name: 'geolocation', size: 12 }],
|
||||||
];
|
];
|
||||||
|
const currentLayoutData = {
|
||||||
|
layouts: {
|
||||||
|
edit: currentLayout,
|
||||||
|
},
|
||||||
|
attributes,
|
||||||
|
};
|
||||||
const expected = [
|
const expected = [
|
||||||
[[{ name: 'dynamicZone1', size: 12 }]],
|
[[{ name: 'dynamicZone1', size: 12 }]],
|
||||||
[
|
[
|
||||||
@ -126,7 +144,7 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(createAttributesLayout(currentLayout, attributes)).toEqual(expected);
|
expect(createAttributesLayout(currentLayoutData)).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should return an array of size 5 if there are 3 dynamic zones', () => {
|
it('Should return an array of size 5 if there are 3 dynamic zones', () => {
|
||||||
@ -164,6 +182,12 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[{ name: 'geolocation', size: 12 }],
|
[{ name: 'geolocation', size: 12 }],
|
||||||
[{ name: 'dynamicZone3', size: 12 }],
|
[{ name: 'dynamicZone3', size: 12 }],
|
||||||
];
|
];
|
||||||
|
const currentLayoutData = {
|
||||||
|
layouts: {
|
||||||
|
edit: currentLayout,
|
||||||
|
},
|
||||||
|
attributes,
|
||||||
|
};
|
||||||
const expected = [
|
const expected = [
|
||||||
[[{ name: 'dynamicZone1', size: 12 }]],
|
[[{ name: 'dynamicZone1', size: 12 }]],
|
||||||
[
|
[
|
||||||
@ -177,6 +201,11 @@ describe('Content Manager | EditView | utils | createAttributesLayout', () => {
|
|||||||
[[{ name: 'dynamicZone3', size: 12 }]],
|
[[{ name: 'dynamicZone3', size: 12 }]],
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(createAttributesLayout(currentLayout, attributes)).toEqual(expected);
|
expect(createAttributesLayout(currentLayoutData)).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should return an empty array when no layouts are found', () => {
|
||||||
|
const currentLayoutData = {};
|
||||||
|
expect(createAttributesLayout(currentLayoutData)).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@ const EditViewLayoutManager = ({ layout, ...rest }) => {
|
|||||||
return <LoadingIndicatorPage />;
|
return <LoadingIndicatorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Permissions {...rest} layout={currentLayout} userPermissions={permissions} />;
|
return <Permissions {...rest} userPermissions={permissions} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
EditViewLayoutManager.propTypes = {
|
EditViewLayoutManager.propTypes = {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ const createContentType = (uid, definition) => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Incorrect Content Type UID "${uid}". The UID should start with api::, plugin:: or strapi::.`
|
`Incorrect Content Type UID "${uid}". The UID should start with api::, plugin:: or admin::.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ const { ValidationError } = require('@strapi/utils').errors;
|
|||||||
const createEntityService = require('..');
|
const createEntityService = require('..');
|
||||||
const entityValidator = require('../../entity-validator');
|
const entityValidator = require('../../entity-validator');
|
||||||
|
|
||||||
|
jest.mock('../../utils/upload-files', () => jest.fn(() => Promise.resolve()));
|
||||||
|
|
||||||
describe('Entity service', () => {
|
describe('Entity service', () => {
|
||||||
global.strapi = {
|
global.strapi = {
|
||||||
getModel: jest.fn(() => ({})),
|
getModel: jest.fn(() => ({})),
|
||||||
@ -15,6 +17,7 @@ describe('Entity service', () => {
|
|||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
query: jest.fn(() => ({})),
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Decorator', () => {
|
describe('Decorator', () => {
|
||||||
@ -80,6 +83,26 @@ describe('Entity service', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Create', () => {
|
describe('Create', () => {
|
||||||
|
const fakeQuery = {
|
||||||
|
count: jest.fn(() => 0),
|
||||||
|
create: jest.fn(({ data }) => ({
|
||||||
|
id: 1,
|
||||||
|
...data,
|
||||||
|
})),
|
||||||
|
findOne: jest.fn(),
|
||||||
|
};
|
||||||
|
const fakeModels = {};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
global.strapi.getModel.mockImplementation((modelName) => fakeModels[modelName]);
|
||||||
|
global.strapi.query.mockImplementation(() => fakeQuery);
|
||||||
|
});
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
global.strapi.getModel.mockImplementation(() => ({}));
|
||||||
|
});
|
||||||
describe('assign default values', () => {
|
describe('assign default values', () => {
|
||||||
let instance;
|
let instance;
|
||||||
const entityUID = 'api::entity.entity';
|
const entityUID = 'api::entity.entity';
|
||||||
@ -105,67 +128,59 @@ describe('Entity service', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const fakeModels = {
|
fakeModels[entityUID] = {
|
||||||
[entityUID]: {
|
uid: entityUID,
|
||||||
uid: entityUID,
|
kind: 'contentType',
|
||||||
kind: 'contentType',
|
modelName: 'test-model',
|
||||||
modelName: 'test-model',
|
privateAttributes: [],
|
||||||
privateAttributes: [],
|
options: {},
|
||||||
options: {},
|
attributes: {
|
||||||
attributes: {
|
attrStringDefaultRequired: {
|
||||||
attrStringDefaultRequired: {
|
type: 'string',
|
||||||
type: 'string',
|
default: 'default value',
|
||||||
default: 'default value',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
attrStringDefault: { type: 'string', default: 'default value' },
|
||||||
attrStringDefault: { type: 'string', default: 'default value' },
|
attrBoolDefaultRequired: { type: 'boolean', default: true, required: true },
|
||||||
attrBoolDefaultRequired: { type: 'boolean', default: true, required: true },
|
attrBoolDefault: { type: 'boolean', default: true },
|
||||||
attrBoolDefault: { type: 'boolean', default: true },
|
attrIntDefaultRequired: { type: 'integer', default: 1, required: true },
|
||||||
attrIntDefaultRequired: { type: 'integer', default: 1, required: true },
|
attrIntDefault: { type: 'integer', default: 1 },
|
||||||
attrIntDefault: { type: 'integer', default: 1 },
|
attrEnumDefaultRequired: {
|
||||||
attrEnumDefaultRequired: {
|
type: 'enumeration',
|
||||||
type: 'enumeration',
|
enum: ['a', 'b', 'c'],
|
||||||
enum: ['a', 'b', 'c'],
|
default: 'a',
|
||||||
default: 'a',
|
required: true,
|
||||||
required: true,
|
},
|
||||||
},
|
attrEnumDefault: {
|
||||||
attrEnumDefault: {
|
type: 'enumeration',
|
||||||
type: 'enumeration',
|
enum: ['a', 'b', 'c'],
|
||||||
enum: ['a', 'b', 'c'],
|
default: 'b',
|
||||||
default: 'b',
|
},
|
||||||
},
|
attrPassword: { type: 'password' },
|
||||||
attrPassword: { type: 'password' },
|
attrRelation: {
|
||||||
attrRelation: {
|
type: 'relation',
|
||||||
type: 'relation',
|
relation: 'oneToMany',
|
||||||
relation: 'oneToMany',
|
target: relationUID,
|
||||||
target: relationUID,
|
mappedBy: 'entity',
|
||||||
mappedBy: 'entity',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[relationUID]: {
|
};
|
||||||
uid: relationUID,
|
fakeModels[relationUID] = {
|
||||||
kind: 'contentType',
|
uid: relationUID,
|
||||||
modelName: 'relation',
|
kind: 'contentType',
|
||||||
attributes: {
|
modelName: 'relation',
|
||||||
Name: {
|
attributes: {
|
||||||
type: 'string',
|
Name: {
|
||||||
default: 'default value',
|
type: 'string',
|
||||||
required: true,
|
default: 'default value',
|
||||||
},
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const fakeQuery = (uid) => ({
|
const fakeQuery = (uid) => ({
|
||||||
create: jest.fn(({ data }) => data),
|
create: jest.fn(({ data }) => data),
|
||||||
count: jest.fn(({ where }) => {
|
count: jest.fn(({ where }) => {
|
||||||
let ret = 0;
|
return where.id.$in.filter((id) => Boolean(fakeEntities[uid][id])).length;
|
||||||
where.id.$in.forEach((id) => {
|
|
||||||
const entity = fakeEntities[uid][id];
|
|
||||||
if (!entity) return;
|
|
||||||
ret += 1;
|
|
||||||
});
|
|
||||||
return ret;
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -173,12 +188,7 @@ describe('Entity service', () => {
|
|||||||
query: jest.fn((uid) => fakeQuery(uid)),
|
query: jest.fn((uid) => fakeQuery(uid)),
|
||||||
};
|
};
|
||||||
|
|
||||||
global.strapi = {
|
global.strapi.db = fakeDB;
|
||||||
getModel: jest.fn((uid) => {
|
|
||||||
return fakeModels[uid];
|
|
||||||
}),
|
|
||||||
db: fakeDB,
|
|
||||||
};
|
|
||||||
|
|
||||||
instance = createEntityService({
|
instance = createEntityService({
|
||||||
strapi: global.strapi,
|
strapi: global.strapi,
|
||||||
@ -187,7 +197,11 @@ describe('Entity service', () => {
|
|||||||
entityValidator,
|
entityValidator,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
afterAll(() => {
|
||||||
|
global.strapi.db = {
|
||||||
|
query: jest.fn(() => fakeQuery),
|
||||||
|
};
|
||||||
|
});
|
||||||
test('should create record with all default attributes', async () => {
|
test('should create record with all default attributes', async () => {
|
||||||
const data = {};
|
const data = {};
|
||||||
|
|
||||||
@ -298,6 +312,108 @@ describe('Entity service', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('with files', () => {
|
||||||
|
let instance;
|
||||||
|
beforeAll(() => {
|
||||||
|
fakeModels['test-model'] = {
|
||||||
|
uid: 'test-model',
|
||||||
|
kind: 'collectionType',
|
||||||
|
collectionName: 'test-model',
|
||||||
|
options: {},
|
||||||
|
attributes: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
activity: {
|
||||||
|
displayName: 'activity',
|
||||||
|
type: 'component',
|
||||||
|
repeatable: true,
|
||||||
|
component: 'basic.activity',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
modelType: 'contentType',
|
||||||
|
modelName: 'test-model',
|
||||||
|
};
|
||||||
|
fakeModels['basic.activity'] = {
|
||||||
|
collectionName: 'components_basic_activities',
|
||||||
|
info: {
|
||||||
|
displayName: 'activity',
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
attributes: {
|
||||||
|
docs: {
|
||||||
|
allowedTypes: ['images', 'files', 'videos', 'audios'],
|
||||||
|
type: 'media',
|
||||||
|
multiple: true,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uid: 'basic.activity',
|
||||||
|
category: 'basic',
|
||||||
|
modelType: 'component',
|
||||||
|
modelName: 'activity',
|
||||||
|
globalId: 'ComponentBasicActivity',
|
||||||
|
};
|
||||||
|
|
||||||
|
const fakeDB = {
|
||||||
|
query: jest.fn(() => fakeQuery),
|
||||||
|
};
|
||||||
|
|
||||||
|
const fakeStrapi = {
|
||||||
|
getModel: jest.fn((modelName) => fakeModels[modelName]),
|
||||||
|
};
|
||||||
|
instance = createEntityService({
|
||||||
|
strapi: fakeStrapi,
|
||||||
|
db: fakeDB,
|
||||||
|
eventHub: new EventEmitter(),
|
||||||
|
entityValidator,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('should create record with attached files', async () => {
|
||||||
|
const uploadFiles = require('../../utils/upload-files');
|
||||||
|
const data = {
|
||||||
|
name: 'demoEvent',
|
||||||
|
activity: [{ name: 'Powering the Aviation of the Future' }],
|
||||||
|
};
|
||||||
|
const files = {
|
||||||
|
'activity.0.docs': {
|
||||||
|
size: 381924,
|
||||||
|
path: '/tmp/upload_4cab76a3a443b584a1fd3aa52e045130',
|
||||||
|
name: 'thisisajpeg.jpeg',
|
||||||
|
type: 'image/jpeg',
|
||||||
|
mtime: '2022-11-03T13:36:51.764Z',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
fakeQuery.findOne.mockResolvedValue({ id: 1, ...data });
|
||||||
|
|
||||||
|
await instance.create('test-model', { data, files });
|
||||||
|
|
||||||
|
expect(global.strapi.getModel).toBeCalled();
|
||||||
|
expect(uploadFiles).toBeCalled();
|
||||||
|
expect(uploadFiles).toBeCalledTimes(1);
|
||||||
|
expect(uploadFiles).toBeCalledWith(
|
||||||
|
'test-model',
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'demoEvent',
|
||||||
|
activity: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
__pivot: {
|
||||||
|
field: 'activity',
|
||||||
|
component_type: 'basic.activity',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
files
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Update', () => {
|
describe('Update', () => {
|
||||||
|
@ -134,17 +134,20 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|||||||
// TODO: wrap into transaction
|
// TODO: wrap into transaction
|
||||||
const componentData = await createComponents(uid, validData);
|
const componentData = await createComponents(uid, validData);
|
||||||
|
|
||||||
|
const entityData = creationPipeline(
|
||||||
|
Object.assign(omitComponentData(model, validData), componentData),
|
||||||
|
{
|
||||||
|
contentType: model,
|
||||||
|
}
|
||||||
|
);
|
||||||
let entity = await db.query(uid).create({
|
let entity = await db.query(uid).create({
|
||||||
...query,
|
...query,
|
||||||
data: creationPipeline(Object.assign(omitComponentData(model, validData), componentData), {
|
data: entityData,
|
||||||
contentType: model,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: upload the files then set the links in the entity like with compo to avoid making too many queries
|
// TODO: upload the files then set the links in the entity like with compo to avoid making too many queries
|
||||||
// FIXME: upload in components
|
|
||||||
if (files && Object.keys(files).length > 0) {
|
if (files && Object.keys(files).length > 0) {
|
||||||
await this.uploadFiles(uid, entity, files);
|
await this.uploadFiles(uid, Object.assign(entityData, entity), files);
|
||||||
entity = await this.findOne(uid, entity.id, wrappedParams);
|
entity = await this.findOne(uid, entity.id, wrappedParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,19 +183,22 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|||||||
|
|
||||||
// TODO: wrap in transaction
|
// TODO: wrap in transaction
|
||||||
const componentData = await updateComponents(uid, entityToUpdate, validData);
|
const componentData = await updateComponents(uid, entityToUpdate, validData);
|
||||||
|
const entityData = updatePipeline(
|
||||||
|
Object.assign(omitComponentData(model, validData), componentData),
|
||||||
|
{
|
||||||
|
contentType: model,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
let entity = await db.query(uid).update({
|
let entity = await db.query(uid).update({
|
||||||
...query,
|
...query,
|
||||||
where: { id: entityId },
|
where: { id: entityId },
|
||||||
data: updatePipeline(Object.assign(omitComponentData(model, validData), componentData), {
|
data: entityData,
|
||||||
contentType: model,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: upload the files then set the links in the entity like with compo to avoid making too many queries
|
// TODO: upload the files then set the links in the entity like with compo to avoid making too many queries
|
||||||
// FIXME: upload in components
|
|
||||||
if (files && Object.keys(files).length > 0) {
|
if (files && Object.keys(files).length > 0) {
|
||||||
await this.uploadFiles(uid, entity, files);
|
await this.uploadFiles(uid, Object.assign(entityData, entity), files);
|
||||||
entity = await this.findOne(uid, entity.id, wrappedParams);
|
entity = await this.findOne(uid, entity.id, wrappedParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
"chokidar": "3.5.2",
|
"chokidar": "3.5.2",
|
||||||
"ci-info": "3.5.0",
|
"ci-info": "3.5.0",
|
||||||
"cli-table3": "0.6.2",
|
"cli-table3": "0.6.2",
|
||||||
"commander": "8.2.0",
|
"commander": "7.2.0",
|
||||||
"configstore": "5.0.1",
|
"configstore": "5.0.1",
|
||||||
"debug": "4.3.2",
|
"debug": "4.3.2",
|
||||||
"delegates": "1.0.0",
|
"delegates": "1.0.0",
|
||||||
|
@ -25,9 +25,45 @@ const dogModel = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const todoListModel = {
|
||||||
|
displayName: 'TodoList',
|
||||||
|
singularName: 'todolist',
|
||||||
|
pluralName: 'todolists',
|
||||||
|
kind: 'collectionType',
|
||||||
|
attributes: {
|
||||||
|
title: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
todo: {
|
||||||
|
displayName: 'todo',
|
||||||
|
type: 'component',
|
||||||
|
repeatable: true,
|
||||||
|
component: 'default.todo',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const todoComponent = {
|
||||||
|
displayName: 'Todo',
|
||||||
|
attributes: {
|
||||||
|
docs: {
|
||||||
|
allowedTypes: ['images', 'files', 'videos', 'audios'],
|
||||||
|
type: 'media',
|
||||||
|
multiple: true,
|
||||||
|
},
|
||||||
|
task: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
describe('Upload plugin', () => {
|
describe('Upload plugin', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await builder.addContentType(dogModel).build();
|
await builder
|
||||||
|
.addContentType(dogModel)
|
||||||
|
.addComponent(todoComponent)
|
||||||
|
.addContentType(todoListModel)
|
||||||
|
.build();
|
||||||
strapi = await createStrapiInstance();
|
strapi = await createStrapiInstance();
|
||||||
rq = await createContentAPIRequest({ strapi });
|
rq = await createContentAPIRequest({ strapi });
|
||||||
});
|
});
|
||||||
@ -190,6 +226,63 @@ describe('Upload plugin', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Create an entity with a component with a file', () => {
|
||||||
|
test('With an image', async () => {
|
||||||
|
const res = await rq({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/todolists',
|
||||||
|
formData: {
|
||||||
|
data: '{"title":"Test todolist title","todo":[{"task":"First todo"},{"task":"Second todo"}]}',
|
||||||
|
'files.todo.0.docs': fs.createReadStream(path.join(__dirname, '../utils/rec.jpg')),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(200);
|
||||||
|
expect(res.body).toMatchObject({
|
||||||
|
data: {
|
||||||
|
attributes: {
|
||||||
|
title: 'Test todolist title',
|
||||||
|
},
|
||||||
|
id: expect.anything(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const newlyCreatedTodolist = await rq({
|
||||||
|
method: 'GET',
|
||||||
|
url: `/todolists/${res.body.data.id}`,
|
||||||
|
qs: {
|
||||||
|
populate: ['todo', 'todo.docs'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(newlyCreatedTodolist.body).toBeDefined();
|
||||||
|
expect(newlyCreatedTodolist.body).toMatchObject({
|
||||||
|
data: {
|
||||||
|
attributes: {
|
||||||
|
title: 'Test todolist title',
|
||||||
|
todo: [
|
||||||
|
{
|
||||||
|
id: expect.anything(),
|
||||||
|
task: 'First todo',
|
||||||
|
docs: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: expect.anything(),
|
||||||
|
attributes: {
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
name: 'rec.jpg',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expect.any(Object),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// see https://github.com/strapi/strapi/issues/14125
|
// see https://github.com/strapi/strapi/issues/14125
|
||||||
describe('File relations are correctly removed', () => {
|
describe('File relations are correctly removed', () => {
|
||||||
test('Update an entity with a file correctly removes the relation between the entity and its old file', async () => {
|
test('Update an entity with a file correctly removes the relation between the entity and its old file', async () => {
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
"reselect": "^4.0.0",
|
"reselect": "^4.0.0",
|
||||||
"swagger-ui-dist": "4.12.0",
|
"swagger-ui-dist": "4.15.5",
|
||||||
"yaml": "1.10.2"
|
"yaml": "1.10.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -14,7 +14,7 @@ module.exports = [
|
|||||||
{
|
{
|
||||||
name: 'pagination[withCount]',
|
name: 'pagination[withCount]',
|
||||||
in: 'query',
|
in: 'query',
|
||||||
description: 'Retun page/pageSize (default: true)',
|
description: 'Return page/pageSize (default: true)',
|
||||||
deprecated: false,
|
deprecated: false,
|
||||||
required: false,
|
required: false,
|
||||||
schema: {
|
schema: {
|
||||||
@ -92,4 +92,14 @@ module.exports = [
|
|||||||
},
|
},
|
||||||
style: 'deepObject',
|
style: 'deepObject',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'locale',
|
||||||
|
in: 'query',
|
||||||
|
description: 'Locale to apply',
|
||||||
|
deprecated: false,
|
||||||
|
required: false,
|
||||||
|
schema: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@graphql-tools/schema": "8.1.2",
|
"@graphql-tools/schema": "8.5.1",
|
||||||
"@graphql-tools/utils": "^8.12.0",
|
"@graphql-tools/utils": "^8.12.0",
|
||||||
"@strapi/utils": "4.5.2",
|
"@strapi/utils": "4.5.2",
|
||||||
"apollo-server-core": "3.1.2",
|
"apollo-server-core": "3.1.2",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { getInitLocale } = require('..');
|
const { getInitLocale, isoLocales } = require('..');
|
||||||
|
|
||||||
describe('I18N default locale', () => {
|
describe('I18N default locale', () => {
|
||||||
describe('getInitLocale', () => {
|
describe('getInitLocale', () => {
|
||||||
@ -23,5 +23,10 @@ describe('I18N default locale', () => {
|
|||||||
process.env.STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE = 'zzzzz';
|
process.env.STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE = 'zzzzz';
|
||||||
expect(() => getInitLocale()).toThrow();
|
expect(() => getInitLocale()).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Checks if there are any duplicate locales present in the "iso-locales.json" file', () => {
|
||||||
|
const set = new Set(isoLocales.map((item) => item.code)).size !== isoLocales.length;
|
||||||
|
expect(set).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -591,22 +591,6 @@
|
|||||||
"code":"en-GG",
|
"code":"en-GG",
|
||||||
"name":"English (Guernsey) (en-GG)"
|
"name":"English (Guernsey) (en-GG)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-CA",
|
|
||||||
"name":"English (Canada) (en-CA)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-EG",
|
|
||||||
"name":"English (Egypt) (en-EG)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-EU",
|
|
||||||
"name":"English (Europe) (en-EU)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-GU",
|
|
||||||
"name":"English (Guam) (en-GU)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-GY",
|
"code":"en-GY",
|
||||||
"name":"English (Guyana) (en-GY)"
|
"name":"English (Guyana) (en-GY)"
|
||||||
@ -667,10 +651,6 @@
|
|||||||
"code":"en-MY",
|
"code":"en-MY",
|
||||||
"name":"English (Malaysia) (en-MY)"
|
"name":"English (Malaysia) (en-MY)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-JM",
|
|
||||||
"name":"English (Jamaica) (en-JM)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-MT",
|
"code":"en-MT",
|
||||||
"name":"English (Malta) (en-MT)"
|
"name":"English (Malta) (en-MT)"
|
||||||
@ -719,14 +699,6 @@
|
|||||||
"code":"en-NF",
|
"code":"en-NF",
|
||||||
"name":"English (Norfolk Island) (en-NF)"
|
"name":"English (Norfolk Island) (en-NF)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-NA",
|
|
||||||
"name":"English (Namibia) (en-NA)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-NZ",
|
|
||||||
"name":"English (New Zealand) (en-NZ)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-MP",
|
"code":"en-MP",
|
||||||
"name":"English (Northern Mariana Islands) (en-MP)"
|
"name":"English (Northern Mariana Islands) (en-MP)"
|
||||||
@ -795,10 +767,6 @@
|
|||||||
"code":"en-SB",
|
"code":"en-SB",
|
||||||
"name":"English (Solomon Islands) (en-SB)"
|
"name":"English (Solomon Islands) (en-SB)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-ZA",
|
|
||||||
"name":"English (South Africa) (en-ZA)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-SS",
|
"code":"en-SS",
|
||||||
"name":"English (South Sudan) (en-SS)"
|
"name":"English (South Sudan) (en-SS)"
|
||||||
@ -859,26 +827,10 @@
|
|||||||
"code":"en-TV",
|
"code":"en-TV",
|
||||||
"name":"English (Tuvalu) (en-TV)"
|
"name":"English (Tuvalu) (en-TV)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-PH",
|
|
||||||
"name":"English (Philippines) (en-PH)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-SA",
|
|
||||||
"name":"English (Saudi Arabia) (en-SA)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code":"en-SG",
|
|
||||||
"name":"English (Singapore) (en-SG)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-ZA",
|
"code":"en-ZA",
|
||||||
"name":"English (South Africa) (en-ZA)"
|
"name":"English (South Africa) (en-ZA)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code":"en-TT",
|
|
||||||
"name":"English (Trinidad and Tobago) (en-TT)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code":"en-AE",
|
"code":"en-AE",
|
||||||
"name":"English (U.A.E.) (en-AE)"
|
"name":"English (U.A.E.) (en-AE)"
|
||||||
|
@ -594,22 +594,6 @@ exports[`ISO locales getIsoLocales 1`] = `
|
|||||||
"code": "en-GG",
|
"code": "en-GG",
|
||||||
"name": "English (Guernsey) (en-GG)",
|
"name": "English (Guernsey) (en-GG)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-CA",
|
|
||||||
"name": "English (Canada) (en-CA)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-EG",
|
|
||||||
"name": "English (Egypt) (en-EG)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-EU",
|
|
||||||
"name": "English (Europe) (en-EU)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-GU",
|
|
||||||
"name": "English (Guam) (en-GU)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-GY",
|
"code": "en-GY",
|
||||||
"name": "English (Guyana) (en-GY)",
|
"name": "English (Guyana) (en-GY)",
|
||||||
@ -670,10 +654,6 @@ exports[`ISO locales getIsoLocales 1`] = `
|
|||||||
"code": "en-MY",
|
"code": "en-MY",
|
||||||
"name": "English (Malaysia) (en-MY)",
|
"name": "English (Malaysia) (en-MY)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-JM",
|
|
||||||
"name": "English (Jamaica) (en-JM)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-MT",
|
"code": "en-MT",
|
||||||
"name": "English (Malta) (en-MT)",
|
"name": "English (Malta) (en-MT)",
|
||||||
@ -722,14 +702,6 @@ exports[`ISO locales getIsoLocales 1`] = `
|
|||||||
"code": "en-NF",
|
"code": "en-NF",
|
||||||
"name": "English (Norfolk Island) (en-NF)",
|
"name": "English (Norfolk Island) (en-NF)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-NA",
|
|
||||||
"name": "English (Namibia) (en-NA)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-NZ",
|
|
||||||
"name": "English (New Zealand) (en-NZ)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-MP",
|
"code": "en-MP",
|
||||||
"name": "English (Northern Mariana Islands) (en-MP)",
|
"name": "English (Northern Mariana Islands) (en-MP)",
|
||||||
@ -798,10 +770,6 @@ exports[`ISO locales getIsoLocales 1`] = `
|
|||||||
"code": "en-SB",
|
"code": "en-SB",
|
||||||
"name": "English (Solomon Islands) (en-SB)",
|
"name": "English (Solomon Islands) (en-SB)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-ZA",
|
|
||||||
"name": "English (South Africa) (en-ZA)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-SS",
|
"code": "en-SS",
|
||||||
"name": "English (South Sudan) (en-SS)",
|
"name": "English (South Sudan) (en-SS)",
|
||||||
@ -862,26 +830,10 @@ exports[`ISO locales getIsoLocales 1`] = `
|
|||||||
"code": "en-TV",
|
"code": "en-TV",
|
||||||
"name": "English (Tuvalu) (en-TV)",
|
"name": "English (Tuvalu) (en-TV)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-PH",
|
|
||||||
"name": "English (Philippines) (en-PH)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-SA",
|
|
||||||
"name": "English (Saudi Arabia) (en-SA)",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"code": "en-SG",
|
|
||||||
"name": "English (Singapore) (en-SG)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-ZA",
|
"code": "en-ZA",
|
||||||
"name": "English (South Africa) (en-ZA)",
|
"name": "English (South Africa) (en-ZA)",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"code": "en-TT",
|
|
||||||
"name": "English (Trinidad and Tobago) (en-TT)",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"code": "en-AE",
|
"code": "en-AE",
|
||||||
"name": "English (U.A.E.) (en-AE)",
|
"name": "English (U.A.E.) (en-AE)",
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"test": "echo \"no tests yet\""
|
"test": "echo \"no tests yet\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aws-sdk": "2.1215.0",
|
"aws-sdk": "2.1260.0",
|
||||||
"lodash": "4.17.21"
|
"lodash": "4.17.21"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
80
yarn.lock
80
yarn.lock
@ -1865,7 +1865,7 @@
|
|||||||
"@graphql-tools/utils" "8.9.0"
|
"@graphql-tools/utils" "8.9.0"
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
"@graphql-tools/merge@8.3.12", "@graphql-tools/merge@^8.0.2":
|
"@graphql-tools/merge@8.3.12":
|
||||||
version "8.3.12"
|
version "8.3.12"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.12.tgz#e3f2e5d8a7b34fb689cda66799d845cbc919e464"
|
resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.3.12.tgz#e3f2e5d8a7b34fb689cda66799d845cbc919e464"
|
||||||
integrity sha512-BFL8r4+FrqecPnIW0H8UJCBRQ4Y8Ep60aujw9c/sQuFmQTiqgWgpphswMGfaosP2zUinDE3ojU5wwcS2IJnumA==
|
integrity sha512-BFL8r4+FrqecPnIW0H8UJCBRQ4Y8Ep60aujw9c/sQuFmQTiqgWgpphswMGfaosP2zUinDE3ojU5wwcS2IJnumA==
|
||||||
@ -1883,15 +1883,15 @@
|
|||||||
fast-json-stable-stringify "^2.1.0"
|
fast-json-stable-stringify "^2.1.0"
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
"@graphql-tools/schema@8.1.2":
|
"@graphql-tools/schema@8.5.1", "@graphql-tools/schema@^8.0.0":
|
||||||
version "8.1.2"
|
version "8.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.1.2.tgz#913879da1a7889a9488e9b7dc189e7c83eff74be"
|
resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.5.1.tgz#c2f2ff1448380919a330312399c9471db2580b58"
|
||||||
integrity sha512-rX2pg42a0w7JLVYT+f/yeEKpnoZL5PpLq68TxC3iZ8slnNBNjfVfvzzOn8Q8Q6Xw3t17KP9QespmJEDfuQe4Rg==
|
integrity sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@graphql-tools/merge" "^8.0.2"
|
"@graphql-tools/merge" "8.3.1"
|
||||||
"@graphql-tools/utils" "^8.1.1"
|
"@graphql-tools/utils" "8.9.0"
|
||||||
tslib "~2.3.0"
|
tslib "^2.4.0"
|
||||||
value-or-promise "1.0.10"
|
value-or-promise "1.0.11"
|
||||||
|
|
||||||
"@graphql-tools/schema@9.0.10":
|
"@graphql-tools/schema@9.0.10":
|
||||||
version "9.0.10"
|
version "9.0.10"
|
||||||
@ -1903,16 +1903,6 @@
|
|||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
value-or-promise "1.0.11"
|
value-or-promise "1.0.11"
|
||||||
|
|
||||||
"@graphql-tools/schema@^8.0.0":
|
|
||||||
version "8.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.5.1.tgz#c2f2ff1448380919a330312399c9471db2580b58"
|
|
||||||
integrity sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg==
|
|
||||||
dependencies:
|
|
||||||
"@graphql-tools/merge" "8.3.1"
|
|
||||||
"@graphql-tools/utils" "8.9.0"
|
|
||||||
tslib "^2.4.0"
|
|
||||||
value-or-promise "1.0.11"
|
|
||||||
|
|
||||||
"@graphql-tools/utils@8.9.0":
|
"@graphql-tools/utils@8.9.0":
|
||||||
version "8.9.0"
|
version "8.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.9.0.tgz#c6aa5f651c9c99e1aca55510af21b56ec296cdb7"
|
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.9.0.tgz#c6aa5f651c9c99e1aca55510af21b56ec296cdb7"
|
||||||
@ -1927,10 +1917,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
"@graphql-tools/utils@^8.0.0", "@graphql-tools/utils@^8.1.1", "@graphql-tools/utils@^8.12.0":
|
"@graphql-tools/utils@^8.0.0", "@graphql-tools/utils@^8.12.0":
|
||||||
version "8.13.1"
|
version "8.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.13.1.tgz#b247607e400365c2cd87ff54654d4ad25a7ac491"
|
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.12.0.tgz#243bc4f5fc2edbc9e8fd1038189e57d837cbe31f"
|
||||||
integrity sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==
|
integrity sha512-TeO+MJWGXjUTS52qfK4R8HiPoF/R7X+qmgtOYd8DTH0l6b+5Y/tlg5aGeUJefqImRq7nvi93Ms40k/Uz4D5CWw==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.4.0"
|
tslib "^2.4.0"
|
||||||
|
|
||||||
@ -7585,10 +7575,10 @@ available-typed-arrays@^1.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
|
||||||
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
|
||||||
|
|
||||||
aws-sdk@2.1215.0:
|
aws-sdk@2.1260.0:
|
||||||
version "2.1215.0"
|
version "2.1260.0"
|
||||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1215.0.tgz#dafc339c2f9039a8f9de30d863a8665716df2ec0"
|
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1260.0.tgz#3dc18f49dd4aaa18e4e9787c62f1ad02e5aaac4c"
|
||||||
integrity sha512-btOexIY0O2F+HhjytToaYuub2HEdLqccZSM8rbT3nrbXo7U4k4Gqi6SbMGi2a+vEpj8lY8dAuMR2lvvVs4Ib9Q==
|
integrity sha512-iciXVukPbhmh44xcF+5/CO15jtESqRkXuEH54XaU8IpCzbYkAcPBaS29vLRN2SRuN1Dy2S3X7SaZZxFJWLAHrg==
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer "4.9.2"
|
buffer "4.9.2"
|
||||||
events "1.1.1"
|
events "1.1.1"
|
||||||
@ -9114,20 +9104,10 @@ comma-separated-tokens@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
|
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
|
||||||
integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
|
integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
|
||||||
|
|
||||||
commander@6.1.0:
|
commander@7.2.0, commander@^7.0.0, commander@^7.2.0:
|
||||||
version "6.1.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
|
||||||
integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==
|
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
|
||||||
|
|
||||||
commander@7.1.0:
|
|
||||||
version "7.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff"
|
|
||||||
integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==
|
|
||||||
|
|
||||||
commander@8.2.0:
|
|
||||||
version "8.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.2.0.tgz#37fe2bde301d87d47a53adeff8b5915db1381ca8"
|
|
||||||
integrity sha512-LLKxDvHeL91/8MIyTAD5BFMNtoIwztGPMiM/7Bl8rIPmHCZXRxmSWr91h57dpOpnQ6jIUqEWdXE/uBYMfiVZDA==
|
|
||||||
|
|
||||||
commander@^2.19.0, commander@^2.20.0, commander@^2.20.3:
|
commander@^2.19.0, commander@^2.20.0, commander@^2.20.3:
|
||||||
version "2.20.3"
|
version "2.20.3"
|
||||||
@ -9144,11 +9124,6 @@ commander@^6.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
|
||||||
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
|
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
|
||||||
|
|
||||||
commander@^7.0.0, commander@^7.2.0:
|
|
||||||
version "7.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
|
|
||||||
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
|
|
||||||
|
|
||||||
commander@^8.3.0:
|
commander@^8.3.0:
|
||||||
version "8.3.0"
|
version "8.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
|
||||||
@ -21169,10 +21144,10 @@ svg-tags@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
|
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
|
||||||
integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
|
integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
|
||||||
|
|
||||||
swagger-ui-dist@4.12.0:
|
swagger-ui-dist@4.15.5:
|
||||||
version "4.12.0"
|
version "4.15.5"
|
||||||
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.12.0.tgz#986d90f05e81fb9db3ca40372278a5d8ce71db3a"
|
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz#cda226a79db2a9192579cc1f37ec839398a62638"
|
||||||
integrity sha512-B0Iy2ueXtbByE6OOyHTi3lFQkpPi/L7kFOKFeKTr44za7dJIELa9kzaca6GkndCgpK1QTjArnoXG+aUy0XQp1w==
|
integrity sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA==
|
||||||
|
|
||||||
swap-case@^1.1.0:
|
swap-case@^1.1.0:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
@ -22287,11 +22262,6 @@ value-equal@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
|
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
|
||||||
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
|
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
|
||||||
|
|
||||||
value-or-promise@1.0.10:
|
|
||||||
version "1.0.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.10.tgz#5bf041f1e9a8e7043911875547636768a836e446"
|
|
||||||
integrity sha512-1OwTzvcfXkAfabk60UVr5NdjtjJ0Fg0T5+B1bhxtrOEwSH2fe8y4DnLgoksfCyd8yZCOQQHB0qLMQnwgCjbXLQ==
|
|
||||||
|
|
||||||
value-or-promise@1.0.11:
|
value-or-promise@1.0.11:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140"
|
resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user