diff --git a/examples/getstarted/src/api/kitchensink/content-types/kitchensink/schema.json b/examples/getstarted/src/api/kitchensink/content-types/kitchensink/schema.json index fc6904c1df..9a5ab18ddf 100644 --- a/examples/getstarted/src/api/kitchensink/content-types/kitchensink/schema.json +++ b/examples/getstarted/src/api/kitchensink/content-types/kitchensink/schema.json @@ -5,7 +5,8 @@ "displayName": "Kitchen Sink", "singularName": "kitchensink", "pluralName": "kitchensinks", - "description": "" + "description": "", + "name": "Kitchen Sink" }, "options": { "draftAndPublish": true @@ -100,7 +101,8 @@ "dynamiczone": { "type": "dynamiczone", "components": [ - "basic.simple" + "basic.simple", + "basic.kitchensink" ] }, "one_way_tag": { @@ -145,6 +147,11 @@ "morph_to_many": { "type": "relation", "relation": "morphToMany" + }, + "compo": { + "type": "component", + "repeatable": false, + "component": "basic.kitchensink" } } } diff --git a/examples/getstarted/src/components/basic/kitchensink.json b/examples/getstarted/src/components/basic/kitchensink.json new file mode 100644 index 0000000000..c34231b1fe --- /dev/null +++ b/examples/getstarted/src/components/basic/kitchensink.json @@ -0,0 +1,24 @@ +{ + "collectionName": "components_basic_kitchensinks", + "info": { + "name": "kitchensink", + "icon": "adjust", + "description": "" + }, + "options": {}, + "attributes": { + "address": { + "type": "relation", + "relation": "oneToOne", + "target": "api::address.address" + }, + "countries": { + "type": "relation", + "relation": "oneToMany", + "target": "api::country.country" + }, + "name": { + "type": "string" + } + } +} diff --git a/packages/core/content-type-builder/server/controllers/validation/component.js b/packages/core/content-type-builder/server/controllers/validation/component.js index 4624d7918a..0d57bd01dd 100644 --- a/packages/core/content-type-builder/server/controllers/validation/component.js +++ b/packages/core/content-type-builder/server/controllers/validation/component.js @@ -9,7 +9,7 @@ const { isValidCategoryName, isValidIcon } = require('./common'); const createSchema = require('./model-schema'); const { removeEmptyDefaults } = require('./data-transform'); -const VALID_RELATIONS = ['oneWay', 'manyWay']; +const VALID_RELATIONS = ['oneToOne', 'oneToMany']; const VALID_TYPES = [...DEFAULT_TYPES, 'component']; const componentSchema = createSchema(VALID_TYPES, VALID_RELATIONS, { diff --git a/packages/core/strapi/lib/core-api/controller/transform.js b/packages/core/strapi/lib/core-api/controller/transform.js index 84ca8dc2e4..2bfe587fa7 100644 --- a/packages/core/strapi/lib/core-api/controller/transform.js +++ b/packages/core/strapi/lib/core-api/controller/transform.js @@ -49,6 +49,22 @@ const transformEntry = (entry, contentType) => { const data = transformEntry(property, strapi.contentType(attribute.target)); attributeValues[key] = { data }; + } else if (attribute && attribute.type === 'component') { + const { id, attributes } = transformEntry(property, strapi.components[attribute.component]); + attributeValues[key] = { id, ...attributes }; + } else if (attribute && attribute.type === 'dynamiczone') { + if (Array.isArray(property)) { + attributeValues[key] = property.map(subProperty => { + const { id, attributes } = transformEntry( + subProperty, + strapi.components[subProperty.__component] + ); + + return { id, ...attributes }; + }); + } else { + attributeValues[key] = property; + } } else if (attribute && attribute.type === 'media') { const data = transformEntry(property, strapi.contentType('plugin::upload.file')); diff --git a/packages/core/strapi/tests/dynamiczones/with-media.test.e2e.js b/packages/core/strapi/tests/dynamiczones/with-media.test.e2e.js index f80ead28cd..c621b48462 100644 --- a/packages/core/strapi/tests/dynamiczones/with-media.test.e2e.js +++ b/packages/core/strapi/tests/dynamiczones/with-media.test.e2e.js @@ -126,19 +126,27 @@ describe('Not required dynamiczone', () => { id: expect.anything(), __component: 'default.one-media', media: { - id: mediaId, - url: expect.any(String), + data: { + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }, }, }, { id: expect.anything(), __component: 'default.many-media', - media: expect.arrayContaining([ - expect.objectContaining({ - id: mediaId, - url: expect.any(String), - }), - ]), + media: { + data: expect.arrayContaining([ + expect.objectContaining({ + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }), + ]), + }, }, ], }, @@ -209,19 +217,27 @@ describe('Not required dynamiczone', () => { id: expect.anything(), __component: 'default.one-media', media: { - id: newMediaId, - url: expect.any(String), + data: { + id: newMediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }, }, }, { id: expect.anything(), __component: 'default.many-media', - media: expect.arrayContaining([ - expect.objectContaining({ - id: newMediaId, - url: expect.any(String), - }), - ]), + media: { + data: expect.arrayContaining([ + expect.objectContaining({ + id: newMediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }), + ]), + }, }, ], }, @@ -273,19 +289,27 @@ describe('Not required dynamiczone', () => { id: expect.anything(), __component: 'default.one-media', media: { - id: mediaId, - url: expect.any(String), + data: { + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }, }, }, { id: expect.anything(), __component: 'default.many-media', - media: expect.arrayContaining([ - expect.objectContaining({ - id: mediaId, - url: expect.any(String), - }), - ]), + media: { + data: expect.arrayContaining([ + expect.objectContaining({ + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }), + ]), + }, }, ], }, @@ -333,17 +357,25 @@ describe('Not required dynamiczone', () => { __component: 'default.with-nested', singleMedia: { media: { - id: mediaId, - url: expect.any(String), + data: { + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }, }, }, multipleMedia: { - media: expect.arrayContaining([ - expect.objectContaining({ - id: mediaId, - url: expect.any(String), - }), - ]), + media: { + data: expect.arrayContaining([ + expect.objectContaining({ + id: mediaId, + attributes: expect.objectContaining({ + url: expect.any(String), + }), + }), + ]), + }, }, }, ],