diff --git a/examples/getstarted/api/address/models/Address.settings.json b/examples/getstarted/api/address/models/Address.settings.json index 47fd11d177..f4c1865a61 100755 --- a/examples/getstarted/api/address/models/Address.settings.json +++ b/examples/getstarted/api/address/models/Address.settings.json @@ -32,10 +32,8 @@ "inversedBy": "addresses" }, "cover": { - "model": "file", - "via": "related", + "type": "media", "allowedTypes": ["files", "images", "videos"], - "plugin": "upload", "required": false, "pluginOptions": { "i18n": { @@ -44,10 +42,9 @@ } }, "images": { - "collection": "file", - "via": "related", + "type": "media", + "multiple": true, "allowedTypes": ["images"], - "plugin": "upload", "required": false, "pluginOptions": { "i18n": { diff --git a/examples/getstarted/api/homepage/models/homepage.settings.json b/examples/getstarted/api/homepage/models/homepage.settings.json index 0abbc88755..dfe462ad61 100644 --- a/examples/getstarted/api/homepage/models/homepage.settings.json +++ b/examples/getstarted/api/homepage/models/homepage.settings.json @@ -35,17 +35,14 @@ } }, "single": { - "model": "file", - "via": "related", + "type": "media", "allowedTypes": ["images", "files", "videos"], - "plugin": "upload", "required": false }, "multiple": { - "collection": "file", - "via": "related", + "type": "media", + "multiple": true, "allowedTypes": ["images", "videos"], - "plugin": "upload", "required": false } } diff --git a/examples/getstarted/api/restaurant/models/Restaurant.settings.json b/examples/getstarted/api/restaurant/models/Restaurant.settings.json index bf6e4e271e..b243db6976 100755 --- a/examples/getstarted/api/restaurant/models/Restaurant.settings.json +++ b/examples/getstarted/api/restaurant/models/Restaurant.settings.json @@ -46,8 +46,8 @@ } } }, - "category_compo": { - "component": "application::category.category", + "closing_period": { + "component": "default.closingperiod", "type": "component", "pluginOptions": { "i18n": { @@ -80,18 +80,15 @@ "target": "application::address.address" }, "cover": { - "model": "file", - "via": "related", - "plugin": "upload", + "type": "media", "required": false }, "timestamp": { "type": "timestamp" }, "images": { - "collection": "file", - "via": "related", - "plugin": "upload", + "type": "media", + "multiple": true, "required": false }, "short_description": { diff --git a/examples/getstarted/components/default/closingperiod.json b/examples/getstarted/components/default/closingperiod.json index b98129d51b..55889fab9e 100644 --- a/examples/getstarted/components/default/closingperiod.json +++ b/examples/getstarted/components/default/closingperiod.json @@ -18,9 +18,7 @@ "required": true }, "media": { - "model": "file", - "via": "related", - "plugin": "upload", + "type": "media", "required": false }, "dish": { diff --git a/examples/getstarted/components/default/dish.json b/examples/getstarted/components/default/dish.json index 6831370c56..492d5b41df 100644 --- a/examples/getstarted/components/default/dish.json +++ b/examples/getstarted/components/default/dish.json @@ -18,9 +18,7 @@ "type": "float" }, "picture": { - "model": "file", - "via": "related", - "plugin": "upload", + "type": "media", "required": false }, "very_long_description": { diff --git a/examples/getstarted/components/default/restaurantservice.json b/examples/getstarted/components/default/restaurantservice.json index 6b751f3005..8ca52c5a0f 100644 --- a/examples/getstarted/components/default/restaurantservice.json +++ b/examples/getstarted/components/default/restaurantservice.json @@ -12,9 +12,7 @@ "default": "something" }, "media": { - "model": "file", - "via": "related", - "plugin": "upload" + "type": "media" }, "is_available": { "type": "boolean", diff --git a/examples/getstarted/extensions/users-permissions/models/User.settings.json b/examples/getstarted/extensions/users-permissions/models/User.settings.json index 670fdc46ab..00da9bd0eb 100644 --- a/examples/getstarted/extensions/users-permissions/models/User.settings.json +++ b/examples/getstarted/extensions/users-permissions/models/User.settings.json @@ -60,9 +60,7 @@ "configurable": false }, "picture": { - "model": "file", - "via": "related", - "plugin": "upload" + "type": "media" } } } diff --git a/packages/core/content-manager/services/data-mapper.js b/packages/core/content-manager/services/data-mapper.js index 14e1dd5956..ff35d9b3be 100644 --- a/packages/core/content-manager/services/data-mapper.js +++ b/packages/core/content-manager/services/data-mapper.js @@ -22,6 +22,10 @@ module.exports = { toContentManagerModel(contentType) { return { ...contentType, + options: { + ...contentType.options, + timestamps: [], + }, apiID: contentType.modelName, isDisplayed: isVisible(contentType), info: { @@ -30,7 +34,7 @@ module.exports = { }, attributes: { id: { - type: contentType.primaryKeyType, + type: 'integer', }, ...formatAttributes(contentType), ...contentTypesUtils.getTimestampsAttributes(contentType), @@ -66,8 +70,11 @@ const formatAttributes = model => { // FIXME: not needed const formatAttribute = (key, attribute, { model }) => { - return attribute; + if (attribute.type === 'relation') { + return toRelation(attribute); + } + return attribute; // if (has('type', attribute)) return attribute; @@ -91,12 +98,12 @@ const toMedia = attribute => { }; // FIXME: not needed -const toRelation = (attribute, relation) => { +const toRelation = attribute => { return { ...attribute, type: 'relation', - targetModel: relation.targetUid, - relationType: relation.nature, + targetModel: attribute.target, + relationType: attribute.relation, pluginOptions: attribute.pluginOptions, }; }; diff --git a/packages/core/content-manager/utils/index.d.ts b/packages/core/content-manager/utils/index.d.ts new file mode 100644 index 0000000000..4e7fa2b99b --- /dev/null +++ b/packages/core/content-manager/utils/index.d.ts @@ -0,0 +1,23 @@ +import * as components from '../services/components'; +import * as configuration from '../services/configuration'; +import * as contentTypes from '../services/content-types'; +import * as dataMapper from '../services/data-mapper'; +import * as entityManager from '../services/entity-manager'; +import * as metris from '../services/metris'; +import * as permissionChecker from '../services/permission-checker'; +import * as permission from '../services/permission'; +import * as uid from '../services/uid'; + +type S = { + ['content-types']: typeof contentTypes; + ['data-mapper']: typeof dataMapper; + ['entity-manager']: typeof entityManager; + ['permission-checker']: typeof permissionChecker; + components: typeof components; + configuration: typeof configuration; + metris: typeof metris; + permission: typeof permission; + uid: typeof uid; +}; + +export function getService(name: T): S[T]; diff --git a/packages/core/content-type-builder/config/routes.json b/packages/core/content-type-builder/config/routes.json index da41fca2d8..d6f10d88f9 100644 --- a/packages/core/content-type-builder/config/routes.json +++ b/packages/core/content-type-builder/config/routes.json @@ -3,7 +3,7 @@ { "method": "GET", "path": "/reserved-names", - "handler": "Builder.getReservedNames", + "handler": "builder.getReservedNames", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -11,7 +11,7 @@ { "method": "GET", "path": "/content-types", - "handler": "ContentTypes.getContentTypes", + "handler": "content-types.getContentTypes", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -19,7 +19,7 @@ { "method": "GET", "path": "/content-types/:uid", - "handler": "ContentTypes.getContentType", + "handler": "content-types.getContentType", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -27,7 +27,7 @@ { "method": "POST", "path": "/content-types", - "handler": "ContentTypes.createContentType", + "handler": "content-types.createContentType", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -35,7 +35,7 @@ { "method": "PUT", "path": "/content-types/:uid", - "handler": "ContentTypes.updateContentType", + "handler": "content-types.updateContentType", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -43,7 +43,7 @@ { "method": "DELETE", "path": "/content-types/:uid", - "handler": "ContentTypes.deleteContentType", + "handler": "content-types.deleteContentType", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -51,7 +51,7 @@ { "method": "GET", "path": "/components", - "handler": "Components.getComponents", + "handler": "components.getComponents", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -59,7 +59,7 @@ { "method": "GET", "path": "/components/:uid", - "handler": "Components.getComponent", + "handler": "components.getComponent", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -67,7 +67,7 @@ { "method": "POST", "path": "/components", - "handler": "Components.createComponent", + "handler": "components.createComponent", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -75,7 +75,7 @@ { "method": "PUT", "path": "/components/:uid", - "handler": "Components.updateComponent", + "handler": "components.updateComponent", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -83,7 +83,7 @@ { "method": "DELETE", "path": "/components/:uid", - "handler": "Components.deleteComponent", + "handler": "components.deleteComponent", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -91,7 +91,7 @@ { "method": "PUT", "path": "/component-categories/:name", - "handler": "ComponentCategories.editCategory", + "handler": "component-categories.editCategory", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } @@ -99,7 +99,7 @@ { "method": "DELETE", "path": "/component-categories/:name", - "handler": "ComponentCategories.deleteCategory", + "handler": "component-categories.deleteCategory", "config": { "policies": [["admin::hasPermissions", ["plugins::content-type-builder.read"]]] } diff --git a/packages/core/content-type-builder/controllers/Builder.js b/packages/core/content-type-builder/controllers/Builder.js deleted file mode 100644 index 6e934ef2d1..0000000000 --- a/packages/core/content-type-builder/controllers/Builder.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = { - getReservedNames(ctx) { - ctx.body = strapi.plugins['content-type-builder'].services.builder.getReservedNames(); - }, -}; diff --git a/packages/core/content-type-builder/controllers/builder.js b/packages/core/content-type-builder/controllers/builder.js new file mode 100644 index 0000000000..21b378dbc3 --- /dev/null +++ b/packages/core/content-type-builder/controllers/builder.js @@ -0,0 +1,9 @@ +'use strict'; + +const { getService } = require('../utils'); + +module.exports = { + getReservedNames(ctx) { + ctx.body = getService('builder').getReservedNames(); + }, +}; diff --git a/packages/core/content-type-builder/controllers/ComponentCategories.js b/packages/core/content-type-builder/controllers/component-categories.js similarity index 77% rename from packages/core/content-type-builder/controllers/ComponentCategories.js rename to packages/core/content-type-builder/controllers/component-categories.js index 16ce2a51e2..951fd64686 100644 --- a/packages/core/content-type-builder/controllers/ComponentCategories.js +++ b/packages/core/content-type-builder/controllers/component-categories.js @@ -1,5 +1,6 @@ 'use strict'; +const { getService } = require('../utils'); const validateComponentCategory = require('./validation/component-category'); module.exports = { @@ -16,8 +17,7 @@ module.exports = { strapi.reload.isWatching = false; - const componentCategoryService = - strapi.plugins['content-type-builder'].services.componentcategories; + const componentCategoryService = getService('component-categories'); const newName = await componentCategoryService.editCategory(name, body); @@ -31,8 +31,7 @@ module.exports = { strapi.reload.isWatching = false; - const componentCategoryService = - strapi.plugins['content-type-builder'].services.componentcategories; + const componentCategoryService = getService('component-categories'); await componentCategoryService.deleteCategory(name); diff --git a/packages/core/content-type-builder/controllers/Components.js b/packages/core/content-type-builder/controllers/components.js similarity index 87% rename from packages/core/content-type-builder/controllers/Components.js rename to packages/core/content-type-builder/controllers/components.js index 00f895f067..7a33adf7ac 100644 --- a/packages/core/content-type-builder/controllers/Components.js +++ b/packages/core/content-type-builder/controllers/components.js @@ -2,6 +2,7 @@ const _ = require('lodash'); +const { getService } = require('../utils'); const { validateComponentInput, validateUpdateComponentInput } = require('./validation/component'); /** @@ -15,7 +16,7 @@ module.exports = { * @param {Object} ctx - koa context */ async getComponents(ctx) { - const componentService = strapi.plugins['content-type-builder'].services.components; + const componentService = getService('components'); const data = Object.keys(strapi.components).map(uid => { return componentService.formatComponent(strapi.components[uid]); @@ -38,7 +39,7 @@ module.exports = { return ctx.send({ error: 'component.notFound' }, 404); } - const componentService = strapi.plugins['content-type-builder'].services.components; + const componentService = getService('components'); ctx.send({ data: componentService.formatComponent(component) }); }, @@ -60,7 +61,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const componentService = strapi.plugins['content-type-builder'].services.components; + const componentService = getService('components'); const component = await componentService.createComponent({ component: body.component, @@ -98,7 +99,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const componentService = strapi.plugins['content-type-builder'].services.components; + const componentService = getService('components'); const component = await componentService.editComponent(uid, { component: body.component, @@ -129,7 +130,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const componentService = strapi.plugins['content-type-builder'].services.components; + const componentService = getService('components'); const component = await componentService.deleteComponent(uid); diff --git a/packages/core/content-type-builder/controllers/ContentTypes.js b/packages/core/content-type-builder/controllers/content-types.js similarity index 87% rename from packages/core/content-type-builder/controllers/ContentTypes.js rename to packages/core/content-type-builder/controllers/content-types.js index 93f62f813a..69a3143aab 100644 --- a/packages/core/content-type-builder/controllers/ContentTypes.js +++ b/packages/core/content-type-builder/controllers/content-types.js @@ -3,7 +3,7 @@ const _ = require('lodash'); const { hasDraftAndPublish } = require('@strapi/utils').contentTypes; - +const { getService } = require('../utils'); const { validateContentTypeInput, validateUpdateContentTypeInput, @@ -20,7 +20,7 @@ module.exports = { return ctx.send({ error }, 400); } - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = getService('content-types'); const contentTypes = Object.keys(strapi.contentTypes) .filter(uid => !kind || _.get(strapi.contentTypes[uid], 'kind', 'collectionType') === kind) @@ -40,7 +40,7 @@ module.exports = { return ctx.send({ error: 'contentType.notFound' }, 404); } - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = getService('content-types'); ctx.send({ data: contentTypeService.formatContentType(contentType) }); }, @@ -57,7 +57,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = getService('content-types'); const contentType = await contentTypeService.createContentType({ contentType: body.contentType, @@ -102,7 +102,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = getService('content-types'); const component = await contentTypeService.editContentType(uid, { contentType: body.contentType, @@ -128,7 +128,7 @@ module.exports = { try { strapi.reload.isWatching = false; - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = getService('content-types'); const component = await contentTypeService.deleteContentType(uid); diff --git a/packages/core/content-type-builder/controllers/validation/content-type.js b/packages/core/content-type-builder/controllers/validation/content-type.js index fcb0a14881..628b036247 100644 --- a/packages/core/content-type-builder/controllers/validation/content-type.js +++ b/packages/core/content-type-builder/controllers/validation/content-type.js @@ -5,6 +5,7 @@ const yup = require('yup'); const { formatYupErrors, nameToSlug } = require('@strapi/utils'); const pluralize = require('pluralize'); +const { getService } = require('../../utils'); const { modelTypes, DEFAULT_TYPES, typeKinds } = require('../../services/constants'); const createSchema = require('./model-schema'); const { removeEmptyDefaults, removeDeletedUIDTargetFields } = require('./data-transform'); @@ -96,8 +97,7 @@ const validateUpdateContentTypeInput = data => { }; const forbiddenContentTypeNameValidator = () => { - const reservedNames = strapi.plugins['content-type-builder'].services.builder.getReservedNames() - .models; + const reservedNames = getService('builder').getReservedNames().models; return { name: 'forbiddenContentTypeName', diff --git a/packages/core/content-type-builder/controllers/validation/model-schema.js b/packages/core/content-type-builder/controllers/validation/model-schema.js index 4ef1ab2535..ee504a7b6f 100644 --- a/packages/core/content-type-builder/controllers/validation/model-schema.js +++ b/packages/core/content-type-builder/controllers/validation/model-schema.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const yup = require('yup'); const { modelTypes, FORBIDDEN_ATTRIBUTE_NAMES, typeKinds } = require('../../services/constants'); +const { getService } = require('../../utils'); const { isValidCollectionName, isValidKey } = require('./common'); const getTypeValidator = require('./types'); const getRelationValidator = require('./relations'); @@ -64,14 +65,14 @@ const createAttributesValidator = ({ types, modelType, relations }) => { const isForbiddenKey = key => { return [ ...FORBIDDEN_ATTRIBUTE_NAMES, - ...strapi.plugins['content-type-builder'].services.builder.getReservedNames().attributes, + ...getService('builder').getReservedNames().attributes, ].includes(key); }; const forbiddenValidator = () => { const reservedNames = [ ...FORBIDDEN_ATTRIBUTE_NAMES, - ...strapi.plugins['content-type-builder'].services.builder.getReservedNames().attributes, + ...getService('builder').getReservedNames().attributes, ]; return yup.mixed().test({ diff --git a/packages/core/content-type-builder/services/Builder.js b/packages/core/content-type-builder/services/Builder.js index 3dfa5e1cdc..830f10a90f 100644 --- a/packages/core/content-type-builder/services/Builder.js +++ b/packages/core/content-type-builder/services/Builder.js @@ -1,7 +1,9 @@ 'use strict'; module.exports = { + // TODO: Implement getReservedNames() { - return strapi.db.getReservedNames(); + return []; + // strapi.db.getReservedNames(); }, }; diff --git a/packages/core/content-type-builder/services/ComponentCategories.js b/packages/core/content-type-builder/services/component-categories.js similarity index 100% rename from packages/core/content-type-builder/services/ComponentCategories.js rename to packages/core/content-type-builder/services/component-categories.js diff --git a/packages/core/content-type-builder/services/ContentTypes.js b/packages/core/content-type-builder/services/content-types.js similarity index 100% rename from packages/core/content-type-builder/services/ContentTypes.js rename to packages/core/content-type-builder/services/content-types.js diff --git a/packages/core/content-type-builder/utils/attributes.js b/packages/core/content-type-builder/utils/attributes.js index 5d9f635de3..65810524b3 100644 --- a/packages/core/content-type-builder/utils/attributes.js +++ b/packages/core/content-type-builder/utils/attributes.js @@ -57,42 +57,39 @@ const formatAttributes = model => { * @param {Object} context.component - the associated component */ const formatAttribute = (key, attribute, { model }) => { - if (_.has(attribute, 'type')) return attribute; - + // FIXME: remove // format relations - const relation = (model.associations || []).find(assoc => assoc.alias === key); - const { plugin, configurable } = attribute; - let targetEntity = attribute.model || attribute.collection; - if (isMediaAttribute(attribute)) { + const { configurable, required, autoPopulate, pluginOptions } = attribute; + + if (attribute.type === 'media') { return { type: 'media', - multiple: attribute.collection ? true : false, - required: attribute.required ? true : false, + multiple: attribute.multiple ? true : false, + required: required ? true : false, configurable: configurable === false ? false : undefined, allowedTypes: attribute.allowedTypes, - pluginOptions: attribute.pluginOptions, - }; - } else { - return { - nature: relation.nature, - target: targetEntity === '*' ? targetEntity : toUID(targetEntity, plugin), - plugin: plugin || undefined, - dominant: attribute.dominant ? true : false, - targetAttribute: attribute.via || undefined, - columnName: attribute.columnName || undefined, - configurable: configurable === false ? false : undefined, - targetColumnName: _.get( - strapi.getModel(targetEntity, plugin), - ['attributes', attribute.via, 'columnName'], - undefined - ), - private: attribute.private ? true : false, - unique: attribute.unique ? true : false, - autoPopulate: attribute.autoPopulate, - pluginOptions: attribute.pluginOptions, + pluginOptions, }; } + + if (attribute.type === 'relation') { + return { + ...attribute, + type: 'relation', + nature: attribute.relation, + target: attribute.target, + required: required ? true : false, + configurable: configurable === false ? false : undefined, + private: attribute.private ? true : false, + unique: attribute.unique ? true : false, + // FIXME: remove + autoPopulate, + pluginOptions, + }; + } + + return attribute; }; // TODO: move to schema builder diff --git a/packages/core/content-type-builder/utils/index.d.ts b/packages/core/content-type-builder/utils/index.d.ts new file mode 100644 index 0000000000..61ee4df808 --- /dev/null +++ b/packages/core/content-type-builder/utils/index.d.ts @@ -0,0 +1,11 @@ +import * as components from '../services/components'; +import * as builder from '../services/builder'; +import * as contentTypes from '../services/content-types'; + +type S = { + ['content-types']: typeof contentTypes; + components: typeof components; + builder: typeof builder; +}; + +export function getService(name: T): S[T]; diff --git a/packages/core/content-type-builder/utils/index.js b/packages/core/content-type-builder/utils/index.js new file mode 100644 index 0000000000..7ff1675a78 --- /dev/null +++ b/packages/core/content-type-builder/utils/index.js @@ -0,0 +1,12 @@ +'use strict'; + +const { prop } = require('lodash/fp'); + +// retrieve a local service +const getService = name => { + return prop(`content-type-builder.services.${name}`, strapi.plugins); +}; + +module.exports = { + getService, +}; diff --git a/packages/core/database/lib/metadata/index.js b/packages/core/database/lib/metadata/index.js index ed6d132876..2b82b5854d 100644 --- a/packages/core/database/lib/metadata/index.js +++ b/packages/core/database/lib/metadata/index.js @@ -44,6 +44,10 @@ const createJoinColum = (metadata, { attribute /*attributeName, meta */ }) => { const createJoinTable = (metadata, { attributeName, attribute, meta }) => { const targetMeta = metadata.get(attribute.target); + if (!targetMeta) { + throw new Error(`Unknow target ${attribute.target}`); + } + const joinTableName = _.snakeCase(`${meta.tableName}_${attributeName}_links`); const joinColumnName = _.snakeCase(`${meta.singularName}_id`); @@ -155,7 +159,7 @@ const createMetadata = (models = []) => { const metadata = new Metadata(); // init pass - for (const model of models) { + for (const model of _.cloneDeep(models)) { metadata.add({ singularName: model.singularName, uid: model.uid, @@ -218,6 +222,7 @@ const createMetadata = (models = []) => { continue; } } catch (error) { + console.error(error); throw new Error( `Error on attribute ${attributeName} in model ${meta.singularName}(${meta.uid}): ${error.message}` ); diff --git a/packages/core/database/lib/utils/content-types.js b/packages/core/database/lib/utils/content-types.js index 153d10ac30..d4f45848ce 100644 --- a/packages/core/database/lib/utils/content-types.js +++ b/packages/core/database/lib/utils/content-types.js @@ -6,9 +6,9 @@ const transformAttribute = attribute => { // convert to relation return { type: 'relation', - relation: attribute.single === true ? 'morphOne' : 'morphMany', - target: 'file', - morphOn: 'related', + relation: attribute.single === true ? 'manyToOne' : 'manyToMany', //'morphOne' : 'morphMany', + target: 'plugins::upload.file', + // morphOn: 'related', }; } // case 'component': { @@ -30,11 +30,11 @@ const transformContentTypes = contentTypes => { singularName: contentType.modelName, tableName: contentType.collectionName, attributes: { - created_at: { + createdAt: { type: 'datetime', - default: () => new Date(), + // default: () => new Date(), }, - updated_at: { + updatedAt: { type: 'datetime', }, ...Object.keys(contentType.attributes).reduce((attrs, attrName) => { diff --git a/packages/core/upload/admin/src/components/Initializer/index.js b/packages/core/upload/admin/src/components/Initializer/index.js index 17ee12639b..217e72cb0b 100644 --- a/packages/core/upload/admin/src/components/Initializer/index.js +++ b/packages/core/upload/admin/src/components/Initializer/index.js @@ -28,11 +28,6 @@ const Initializer = ({ setPlugin }) => { const fileModel = data.find(model => model.uid === 'plugins::upload.file'); const timestamps = get(fileModel, ['options', 'timestamps']); - // All connectors must initialise the "timestamps" option as a tuple - if (!Array.isArray(timestamps) || timestamps.length !== 2) { - throw new Error('Unexpected timestamp field configuration.'); - } - dispatch(setFileModelTimestamps(timestamps)); ref.current(pluginId); diff --git a/packages/core/upload/models/File.js b/packages/core/upload/models/File.js index 507a6dd8b3..23644c5790 100644 --- a/packages/core/upload/models/File.js +++ b/packages/core/upload/models/File.js @@ -4,4 +4,90 @@ * Lifecycle callbacks for the `File` model. */ -module.exports = {}; +module.exports = { + collectionName: 'files', + info: { + name: 'file', + description: '', + }, + options: { + timestamps: true, + }, + pluginOptions: { + 'content-manager': { + visible: false, + }, + 'content-type-builder': { + visible: false, + }, + }, + attributes: { + name: { + type: 'string', + configurable: false, + required: true, + }, + alternativeText: { + type: 'string', + configurable: false, + }, + caption: { + type: 'string', + configurable: false, + }, + width: { + type: 'integer', + configurable: false, + }, + height: { + type: 'integer', + configurable: false, + }, + formats: { + type: 'json', + configurable: false, + }, + hash: { + type: 'string', + configurable: false, + required: true, + }, + ext: { + type: 'string', + configurable: false, + }, + mime: { + type: 'string', + configurable: false, + required: true, + }, + size: { + type: 'decimal', + configurable: false, + required: true, + }, + url: { + type: 'string', + configurable: false, + required: true, + }, + previewUrl: { + type: 'string', + configurable: false, + }, + provider: { + type: 'string', + configurable: false, + required: true, + }, + provider_metadata: { + type: 'json', + configurable: false, + }, + // related: { + // collection: '*', + // filter: 'field', + // configurable: false, + // }, + }, +}; diff --git a/packages/core/upload/models/File.settings.json b/packages/core/upload/models/File.settings.json deleted file mode 100644 index df0ce62d06..0000000000 --- a/packages/core/upload/models/File.settings.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "collectionName": "files", - "info": { - "name": "file", - "description": "" - }, - "options": { - "timestamps": true - }, - "pluginOptions": { - "content-manager": { - "visible": false - }, - "content-type-builder": { - "visible": false - } - }, - "attributes": { - "name": { - "type": "string", - "configurable": false, - "required": true - }, - "alternativeText": { - "type": "string", - "configurable": false - }, - "caption": { - "type": "string", - "configurable": false - }, - "width": { - "type": "integer", - "configurable": false - }, - "height": { - "type": "integer", - "configurable": false - }, - "formats": { - "type": "json", - "configurable": false - }, - "hash": { - "type": "string", - "configurable": false, - "required": true - }, - "ext": { - "type": "string", - "configurable": false - }, - "mime": { - "type": "string", - "configurable": false, - "required": true - }, - "size": { - "type": "decimal", - "configurable": false, - "required": true - }, - "url": { - "type": "string", - "configurable": false, - "required": true - }, - "previewUrl": { - "type": "string", - "configurable": false - }, - "provider": { - "type": "string", - "configurable": false, - "required": true - }, - "provider_metadata": { - "type": "json", - "configurable": false - }, - "related": { - "collection": "*", - "filter": "field", - "configurable": false - } - } -} diff --git a/packages/plugins/users-permissions/services/UsersPermissions.js b/packages/plugins/users-permissions/services/UsersPermissions.js index 9fba5fd1f3..9cef0cd82b 100644 --- a/packages/plugins/users-permissions/services/UsersPermissions.js +++ b/packages/plugins/users-permissions/services/UsersPermissions.js @@ -337,7 +337,7 @@ module.exports = { await Promise.all( toRemove.map(permission => { const { type, controller, action, roleId } = permission; - return query.delete({ type, controller, action, role: { id: roleId } }); + return query.delete({ where: { type, controller, action, role: { id: roleId } } }); }) ); } diff --git a/test/helpers/models.js b/test/helpers/models.js index 26502cc92c..d2863f1fff 100644 --- a/test/helpers/models.js +++ b/test/helpers/models.js @@ -5,7 +5,7 @@ const { createStrapiInstance } = require('./strapi'); const createHelpers = async ({ strapi: strapiInstance = null, ...options } = {}) => { const strapi = strapiInstance || (await createStrapiInstance(options)); - const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes; + const contentTypeService = strapi.plugins['content-type-builder'].services['content-types']; const componentsService = strapi.plugins['content-type-builder'].services.components; const cleanup = async () => {