@strapi/content-type-builder 5.44.0 → 5.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.js +3 -0
  2. package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.js.map +1 -1
  3. package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.mjs +3 -0
  4. package/dist/admin/components/AIChat/lib/transforms/schemas/fromCTB.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js +53 -1
  6. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.js.map +1 -1
  7. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs +53 -1
  8. package/dist/admin/components/AIChat/lib/transforms/schemas/toCTB.mjs.map +1 -1
  9. package/dist/admin/src/components/AIChat/lib/types/schema.d.ts +2 -0
  10. package/dist/server/controllers/validation/content-type.js.map +1 -1
  11. package/dist/server/controllers/validation/content-type.mjs.map +1 -1
  12. package/dist/server/controllers/validation/schema.js +5 -2
  13. package/dist/server/controllers/validation/schema.js.map +1 -1
  14. package/dist/server/controllers/validation/schema.mjs +6 -3
  15. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  16. package/dist/server/services/api-handler.js +8 -0
  17. package/dist/server/services/api-handler.js.map +1 -1
  18. package/dist/server/services/api-handler.mjs +8 -0
  19. package/dist/server/services/api-handler.mjs.map +1 -1
  20. package/dist/server/services/schema-builder/content-type-builder.js +3 -2
  21. package/dist/server/services/schema-builder/content-type-builder.js.map +1 -1
  22. package/dist/server/services/schema-builder/content-type-builder.mjs +3 -2
  23. package/dist/server/services/schema-builder/content-type-builder.mjs.map +1 -1
  24. package/dist/server/services/schema.js +8 -6
  25. package/dist/server/services/schema.js.map +1 -1
  26. package/dist/server/services/schema.mjs +8 -6
  27. package/dist/server/services/schema.mjs.map +1 -1
  28. package/dist/server/src/controllers/validation/content-type.d.ts +1 -0
  29. package/dist/server/src/controllers/validation/content-type.d.ts.map +1 -1
  30. package/dist/server/src/controllers/validation/schema.d.ts +9 -1
  31. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  32. package/dist/server/src/services/api-handler.d.ts.map +1 -1
  33. package/dist/server/src/services/schema-builder/content-type-builder.d.ts.map +1 -1
  34. package/dist/server/src/services/schema.d.ts.map +1 -1
  35. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"api-handler.js","sources":["../../../server/src/services/api-handler.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Internal } from '@strapi/types';\n\n/**\n * Deletes the API folder of a contentType\n */\nexport async function clear(uid: Internal.UID.ContentType) {\n // TODO double check if this is the correct way to get the apiName\n const { apiName, modelName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n\n await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));\n await deleteBackup(uid);\n}\n\n/**\n * Backups the API folder of a contentType\n * @param {string} uid content type uid\n */\nexport async function backup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n // backup the api folder\n await fse.copy(apiFolder, backupFolder);\n}\n\n/**\n * Deletes an API backup folder\n */\nasync function deleteBackup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const backupFolder = path.join(strapi.dirs.app.api, '.backup');\n const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n await fse.remove(apiBackupFolder);\n\n const list = await fse.readdir(backupFolder);\n if (list.length === 0) {\n await fse.remove(backupFolder);\n }\n}\n\n/**\n * Rollbacks the API folder of a contentType\n */\nexport async function rollback(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n try {\n await fse.access(backupFolder);\n } catch {\n throw new Error('Cannot rollback api that was not backed up');\n }\n\n await fse.remove(apiFolder);\n await fse.copy(backupFolder, apiFolder);\n await deleteBackup(uid);\n}\n\n/**\n * Creates a delete function to clear an api folder\n */\nconst createDeleteApiFunction = (baseName: string) => {\n /**\n * Delets a file in an api.\n * Will only update routes.json instead of deleting it if other routes are present\n */\n return async (filePath: string) => {\n const fileName = path.basename(filePath, path.extname(filePath));\n\n const isSchemaFile = filePath.endsWith(`${baseName}/schema.json`);\n if (fileName === baseName || isSchemaFile) {\n return fse.remove(filePath);\n }\n };\n};\n\n/**\n * Deletes a folder recursively using a delete function\n * @param {string} folder folder to delete\n */\nconst recursiveRemoveFiles = async (folder: string, deleteFn: (file: string) => unknown) => {\n const filesName = await fse.readdir(folder);\n\n for (const fileName of filesName) {\n const filePath = path.join(folder, fileName);\n\n const stat = await fse.stat(filePath);\n\n if (stat.isDirectory()) {\n await recursiveRemoveFiles(filePath, deleteFn);\n } else {\n await deleteFn(filePath);\n }\n }\n\n const files = await fse.readdir(folder);\n if (files.length === 0) {\n await fse.remove(folder);\n }\n};\n"],"names":["clear","uid","apiName","modelName","strapi","contentTypes","apiFolder","path","join","dirs","app","api","recursiveRemoveFiles","createDeleteApiFunction","deleteBackup","backup","backupFolder","fse","copy","apiBackupFolder","remove","list","readdir","length","rollback","access","Error","baseName","filePath","fileName","basename","extname","isSchemaFile","endsWith","folder","deleteFn","filesName","stat","isDirectory","files"],"mappings":"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"}
1
+ {"version":3,"file":"api-handler.js","sources":["../../../server/src/services/api-handler.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Internal } from '@strapi/types';\n\n/**\n * Deletes the API folder of a contentType\n */\nexport async function clear(uid: Internal.UID.ContentType) {\n // TODO double check if this is the correct way to get the apiName\n const { apiName, modelName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n\n await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));\n await deleteBackup(uid);\n}\n\n/**\n * Backups the API folder of a contentType\n * @param {string} uid content type uid\n */\nexport async function backup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n // backup the api folder\n await fse.copy(apiFolder, backupFolder);\n}\n\n/**\n * Deletes an API backup folder\n */\nasync function deleteBackup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const backupFolder = path.join(strapi.dirs.app.api, '.backup');\n const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n await fse.remove(apiBackupFolder);\n\n const list = await fse.readdir(backupFolder);\n if (list.length === 0) {\n await fse.remove(backupFolder);\n }\n}\n\n/**\n * Rollbacks the API folder of a contentType\n */\nexport async function rollback(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n try {\n await fse.access(backupFolder);\n } catch {\n throw new Error('Cannot rollback api that was not backed up');\n }\n\n await fse.remove(apiFolder);\n await fse.copy(backupFolder, apiFolder);\n await deleteBackup(uid);\n}\n\n/**\n * Creates a delete function to clear an api folder\n */\nconst createDeleteApiFunction = (baseName: string) => {\n /**\n * Delets a file in an api.\n * Will only update routes.json instead of deleting it if other routes are present\n */\n return async (filePath: string) => {\n const fileName = path.basename(filePath, path.extname(filePath));\n\n const isSchemaFile = filePath.endsWith(`${baseName}/schema.json`);\n if (fileName === baseName || isSchemaFile) {\n return fse.remove(filePath);\n }\n };\n};\n\n/**\n * Deletes a folder recursively using a delete function\n * @param {string} folder folder to delete\n */\nconst recursiveRemoveFiles = async (folder: string, deleteFn: (file: string) => unknown) => {\n const filesName = await fse.readdir(folder);\n\n for (const fileName of filesName) {\n const filePath = path.join(folder, fileName);\n\n const stat = await fse.stat(filePath);\n\n if (stat.isDirectory()) {\n await recursiveRemoveFiles(filePath, deleteFn);\n } else {\n await deleteFn(filePath);\n }\n }\n\n const files = await fse.readdir(folder);\n if (files.length === 0) {\n await fse.remove(folder);\n }\n};\n"],"names":["clear","uid","apiName","modelName","strapi","contentTypes","apiFolder","path","join","dirs","app","api","recursiveRemoveFiles","createDeleteApiFunction","deleteBackup","backup","backupFolder","fse","copy","apiBackupFolder","remove","list","readdir","length","rollback","access","Error","baseName","filePath","fileName","basename","extname","isSchemaFile","endsWith","folder","deleteFn","filesName","stat","isDirectory","files"],"mappings":"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"}
@@ -6,6 +6,8 @@ import * as fse from 'fs-extra';
6
6
  */ async function clear(uid) {
7
7
  // TODO double check if this is the correct way to get the apiName
8
8
  const { apiName, modelName } = strapi.contentTypes[uid];
9
+ // Opt out if the content type is not linked to an API (e.g. plugin content type)
10
+ if (!apiName) return;
9
11
  const apiFolder = path.join(strapi.dirs.app.api, apiName);
10
12
  await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));
11
13
  await deleteBackup(uid);
@@ -15,6 +17,8 @@ import * as fse from 'fs-extra';
15
17
  * @param {string} uid content type uid
16
18
  */ async function backup(uid) {
17
19
  const { apiName } = strapi.contentTypes[uid];
20
+ // Opt out if the content type is not linked to an API (e.g. plugin content type)
21
+ if (!apiName) return;
18
22
  const apiFolder = path.join(strapi.dirs.app.api, apiName);
19
23
  const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);
20
24
  // backup the api folder
@@ -24,6 +28,8 @@ import * as fse from 'fs-extra';
24
28
  * Deletes an API backup folder
25
29
  */ async function deleteBackup(uid) {
26
30
  const { apiName } = strapi.contentTypes[uid];
31
+ // Opt out if the content type is not linked to an API (e.g. plugin content type)
32
+ if (!apiName) return;
27
33
  const backupFolder = path.join(strapi.dirs.app.api, '.backup');
28
34
  const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);
29
35
  await fse.remove(apiBackupFolder);
@@ -36,6 +42,8 @@ import * as fse from 'fs-extra';
36
42
  * Rollbacks the API folder of a contentType
37
43
  */ async function rollback(uid) {
38
44
  const { apiName } = strapi.contentTypes[uid];
45
+ // Opt out if the content type is not linked to an API (e.g. plugin content type)
46
+ if (!apiName) return;
39
47
  const apiFolder = path.join(strapi.dirs.app.api, apiName);
40
48
  const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);
41
49
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"api-handler.mjs","sources":["../../../server/src/services/api-handler.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Internal } from '@strapi/types';\n\n/**\n * Deletes the API folder of a contentType\n */\nexport async function clear(uid: Internal.UID.ContentType) {\n // TODO double check if this is the correct way to get the apiName\n const { apiName, modelName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n\n await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));\n await deleteBackup(uid);\n}\n\n/**\n * Backups the API folder of a contentType\n * @param {string} uid content type uid\n */\nexport async function backup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n // backup the api folder\n await fse.copy(apiFolder, backupFolder);\n}\n\n/**\n * Deletes an API backup folder\n */\nasync function deleteBackup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const backupFolder = path.join(strapi.dirs.app.api, '.backup');\n const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n await fse.remove(apiBackupFolder);\n\n const list = await fse.readdir(backupFolder);\n if (list.length === 0) {\n await fse.remove(backupFolder);\n }\n}\n\n/**\n * Rollbacks the API folder of a contentType\n */\nexport async function rollback(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n try {\n await fse.access(backupFolder);\n } catch {\n throw new Error('Cannot rollback api that was not backed up');\n }\n\n await fse.remove(apiFolder);\n await fse.copy(backupFolder, apiFolder);\n await deleteBackup(uid);\n}\n\n/**\n * Creates a delete function to clear an api folder\n */\nconst createDeleteApiFunction = (baseName: string) => {\n /**\n * Delets a file in an api.\n * Will only update routes.json instead of deleting it if other routes are present\n */\n return async (filePath: string) => {\n const fileName = path.basename(filePath, path.extname(filePath));\n\n const isSchemaFile = filePath.endsWith(`${baseName}/schema.json`);\n if (fileName === baseName || isSchemaFile) {\n return fse.remove(filePath);\n }\n };\n};\n\n/**\n * Deletes a folder recursively using a delete function\n * @param {string} folder folder to delete\n */\nconst recursiveRemoveFiles = async (folder: string, deleteFn: (file: string) => unknown) => {\n const filesName = await fse.readdir(folder);\n\n for (const fileName of filesName) {\n const filePath = path.join(folder, fileName);\n\n const stat = await fse.stat(filePath);\n\n if (stat.isDirectory()) {\n await recursiveRemoveFiles(filePath, deleteFn);\n } else {\n await deleteFn(filePath);\n }\n }\n\n const files = await fse.readdir(folder);\n if (files.length === 0) {\n await fse.remove(folder);\n }\n};\n"],"names":["clear","uid","apiName","modelName","strapi","contentTypes","apiFolder","path","join","dirs","app","api","recursiveRemoveFiles","createDeleteApiFunction","deleteBackup","backup","backupFolder","fse","copy","apiBackupFolder","remove","list","readdir","length","rollback","access","Error","baseName","filePath","fileName","basename","extname","isSchemaFile","endsWith","folder","deleteFn","filesName","stat","isDirectory","files"],"mappings":"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"}
1
+ {"version":3,"file":"api-handler.mjs","sources":["../../../server/src/services/api-handler.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fse from 'fs-extra';\nimport type { Internal } from '@strapi/types';\n\n/**\n * Deletes the API folder of a contentType\n */\nexport async function clear(uid: Internal.UID.ContentType) {\n // TODO double check if this is the correct way to get the apiName\n const { apiName, modelName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n\n await recursiveRemoveFiles(apiFolder, createDeleteApiFunction(modelName));\n await deleteBackup(uid);\n}\n\n/**\n * Backups the API folder of a contentType\n * @param {string} uid content type uid\n */\nexport async function backup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n // backup the api folder\n await fse.copy(apiFolder, backupFolder);\n}\n\n/**\n * Deletes an API backup folder\n */\nasync function deleteBackup(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const backupFolder = path.join(strapi.dirs.app.api, '.backup');\n const apiBackupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n await fse.remove(apiBackupFolder);\n\n const list = await fse.readdir(backupFolder);\n if (list.length === 0) {\n await fse.remove(backupFolder);\n }\n}\n\n/**\n * Rollbacks the API folder of a contentType\n */\nexport async function rollback(uid: Internal.UID.ContentType) {\n const { apiName } = strapi.contentTypes[uid] as any;\n\n // Opt out if the content type is not linked to an API (e.g. plugin content type)\n if (!apiName) return;\n\n const apiFolder = path.join(strapi.dirs.app.api, apiName);\n const backupFolder = path.join(strapi.dirs.app.api, '.backup', apiName);\n\n try {\n await fse.access(backupFolder);\n } catch {\n throw new Error('Cannot rollback api that was not backed up');\n }\n\n await fse.remove(apiFolder);\n await fse.copy(backupFolder, apiFolder);\n await deleteBackup(uid);\n}\n\n/**\n * Creates a delete function to clear an api folder\n */\nconst createDeleteApiFunction = (baseName: string) => {\n /**\n * Delets a file in an api.\n * Will only update routes.json instead of deleting it if other routes are present\n */\n return async (filePath: string) => {\n const fileName = path.basename(filePath, path.extname(filePath));\n\n const isSchemaFile = filePath.endsWith(`${baseName}/schema.json`);\n if (fileName === baseName || isSchemaFile) {\n return fse.remove(filePath);\n }\n };\n};\n\n/**\n * Deletes a folder recursively using a delete function\n * @param {string} folder folder to delete\n */\nconst recursiveRemoveFiles = async (folder: string, deleteFn: (file: string) => unknown) => {\n const filesName = await fse.readdir(folder);\n\n for (const fileName of filesName) {\n const filePath = path.join(folder, fileName);\n\n const stat = await fse.stat(filePath);\n\n if (stat.isDirectory()) {\n await recursiveRemoveFiles(filePath, deleteFn);\n } else {\n await deleteFn(filePath);\n }\n }\n\n const files = await fse.readdir(folder);\n if (files.length === 0) {\n await fse.remove(folder);\n }\n};\n"],"names":["clear","uid","apiName","modelName","strapi","contentTypes","apiFolder","path","join","dirs","app","api","recursiveRemoveFiles","createDeleteApiFunction","deleteBackup","backup","backupFolder","fse","copy","apiBackupFolder","remove","list","readdir","length","rollback","access","Error","baseName","filePath","fileName","basename","extname","isSchemaFile","endsWith","folder","deleteFn","filesName","stat","isDirectory","files"],"mappings":"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"}
@@ -109,9 +109,10 @@ function createComponentBuilder() {
109
109
  if (this.contentTypes.has(uid)) {
110
110
  throw new ApplicationError('contentType.alreadyExists');
111
111
  }
112
+ const dir = infos.plugin ? path.join(strapi.dirs.app.extensions, infos.plugin, 'content-types', infos.singularName) : path.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName);
112
113
  const contentType = schemaHandler({
113
114
  modelName: infos.singularName,
114
- dir: path.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName),
115
+ dir,
115
116
  filename: `schema.json`
116
117
  });
117
118
  this.contentTypes.set(uid, contentType);
@@ -263,7 +264,7 @@ function createComponentBuilder() {
263
264
  * @param {object} options options
264
265
  * @param {string} options.singularName content-type singularName
265
266
  * @returns {string} uid
266
- */ const createContentTypeUID = ({ singularName })=>`api::${singularName}.${singularName}`;
267
+ */ const createContentTypeUID = ({ plugin, singularName })=>`${plugin ? `plugin` : `api`}::${plugin || singularName}.${singularName}`;
267
268
  const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
268
269
  const opts = {
269
270
  type: 'relation',
@@ -1 +1 @@
1
- {"version":3,"file":"content-type-builder.js","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\nimport type { InternalRelationAttribute, InternalAttribute } from './types';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n 'conditions', // Don't automatically preserve conditions\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(\n this: any,\n { key, uid, attribute }: { key: string; uid: string; attribute: InternalRelationAttribute }\n ) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n // When generating the inverse relation, preserve existing conditions if they exist\n // If the target attribute already exists and has conditions, preserve them\n const targetAttributeData = targetAttribute || {};\n\n // If the source doesn't have conditions but the target does, preserve target's conditions\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute: targetAttributeData })\n );\n },\n\n unsetRelation(\n this: any,\n attribute: Schema.Attribute.Relation<Schema.Attribute.RelationKind.Any>\n ) {\n if (!('target' in attribute) || !attribute.target) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = attributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir: path.join(\n strapi.dirs.app.api,\n infos.singularName,\n 'content-types',\n infos.singularName\n ),\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n\n if (targetAttributeName !== null && targetAttributeName !== undefined) {\n this.unsetRelation(attribute);\n }\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key] as InternalAttribute;\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute as InternalRelationAttribute,\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const relationAttribute = newAttribute as InternalRelationAttribute;\n const oldRelationAttribute = oldAttribute as InternalRelationAttribute;\n const oldTargetAttributeName =\n oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === relationAttribute.relation;\n const targetAttributeHasChanged =\n oldTargetAttributeName !== relationAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(relationAttribute, oldAttribute);\n\n // Handle conditions explicitly - only preserve if present and not undefined in new attribute\n const newAttributeFromInfos = newAttributes[key];\n const hasNewConditions =\n newAttributeFromInfos.conditions !== undefined &&\n newAttributeFromInfos.conditions !== null;\n\n if (oldAttribute.conditions) {\n if (hasNewConditions) {\n // Conditions are still present, keep them\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n } else {\n // Conditions were removed (undefined or null), ensure they're not preserved\n delete relationAttribute.conditions;\n }\n } else if (hasNewConditions) {\n // New conditions added\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n }\n\n if (oldRelationAttribute.inversedBy) {\n relationAttribute.dominant = true;\n } else if (oldRelationAttribute.mappedBy) {\n relationAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = newAttributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n singularName,\n}: {\n singularName: string;\n}): Internal.UID.ContentType => `api::${singularName}.${singularName}`;\n\nconst generateRelation = ({\n key,\n attribute,\n uid,\n targetAttribute = {},\n}: {\n key: string;\n attribute: InternalRelationAttribute;\n uid: string;\n targetAttribute?: Partial<InternalRelationAttribute>;\n}) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n // Preserve conditions from targetAttribute if they exist\n // This allows each side of the relation to maintain its own conditions\n ...(targetAttribute.conditions && { conditions: targetAttribute.conditions }),\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n const result = {\n type,\n relation,\n target,\n ...restOptions,\n };\n\n return result;\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","targetAttributeData","setAttribute","generateRelation","unsetRelation","relationAttribute","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","createSchemaHandler","modelName","singularName","dir","path","join","strapi","dirs","app","api","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","oldRelationAttribute","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","newAttributeFromInfos","hasNewConditions","conditions","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions","result"],"mappings":";;;;;;;;;AAWA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,YAAAA;AAE7B,MAAMC,4BAAAA,GAA+B,CACnCC,YAAAA,EACAC,YAAAA,GAAAA;AAEAC,IAAAA,CAAAA,CAAEC,QAAQ,CACRH,YAAAA,EACAE,CAAAA,CAAEE,IAAI,CAACH,YAAAA,EAAc;AACnB,QAAA,cAAA;AACA,QAAA,UAAA;AACA,QAAA,SAAA;AACA,QAAA,QAAA;AACA,QAAA,eAAA;AACA,QAAA,YAAA;AACA,QAAA,UAAA;AACA,QAAA;AACD,KAAA,CAAA,CAAA;AAEL,CAAA;AAEe,SAASI,sBAAAA,GAAAA;IACtB,OAAO;AACLC,QAAAA,WAAAA,CAAAA,CAEE,EAAEC,GAAG,EAAEC,GAAG,EAAEC,SAAS,EAAsE,EAAA;AAE3F,YAAA,IAAI,CAACP,CAAAA,CAAEQ,GAAG,CAACD,WAAW,QAAA,CAAA,EAAW;AAC/B,gBAAA;AACF,YAAA;YAEA,MAAME,QAAAA,GAAW,IAAI,CAACC,YAAY,CAACC,GAAG,CAACJ,UAAUK,MAAM,CAAA;AAEvD,YAAA,IAAI,CAACH,QAAAA,EAAU;gBACb,MAAM,IAAId,iBAAiB,CAAC,aAAa,EAAEY,SAAAA,CAAUK,MAAM,CAAC,UAAU,CAAC,CAAA;AACzE,YAAA;AAEA,YAAA,MAAMC,eAAAA,GAAkBJ,QAAAA,CAASK,YAAY,CAACP,UAAUM,eAAe,CAAA;YAEvE,IAAI,CAACN,SAAAA,CAAUM,eAAe,EAAE;AAC9B,gBAAA;AACF,YAAA;;;YAIA,MAAME,mBAAAA,GAAsBF,mBAAmB,EAAC;;AAIhDJ,YAAAA,QAAAA,CAASO,YAAY,CACnBT,SAAAA,CAAUM,eAAe,EACzBI,gBAAAA,CAAiB;AAAEZ,gBAAAA,GAAAA;AAAKE,gBAAAA,SAAAA;AAAWD,gBAAAA,GAAAA;gBAAKO,eAAAA,EAAiBE;AAAoB,aAAA,CAAA,CAAA;AAEjF,QAAA,CAAA;AAEAG,QAAAA,aAAAA,CAAAA,CAEEX,SAAuE,EAAA;YAEvE,IAAI,EAAE,QAAA,IAAYA,SAAQ,KAAM,CAACA,SAAAA,CAAUK,MAAM,EAAE;AACjD,gBAAA;AACF,YAAA;YAEA,MAAMH,QAAAA,GAAW,IAAI,CAACC,YAAY,CAACC,GAAG,CAACJ,UAAUK,MAAM,CAAA;AAEvD,YAAA,MAAMO,iBAAAA,GAAoBZ,SAAAA;AAC1B,YAAA,MAAMa,mBAAAA,GAAsBD,iBAAAA,CAAkBE,UAAU,IAAIF,kBAAkBG,QAAQ;YACtF,MAAMT,eAAAA,GAAkBJ,QAAAA,CAASK,YAAY,CAACM,mBAAAA,CAAAA;AAE9C,YAAA,IAAI,CAACP,eAAAA,EAAiB;YAEtB,OAAOJ,QAAAA,CAASc,eAAe,CAACH,mBAAAA,CAAAA;AAClC,QAAA,CAAA;QAEAI,2BAAAA,CAAAA,CAEElB,GAAW,EACXmB,YAAgD,EAAA;AAEhD,YAAA,IAAI,CAAC,IAAI,CAACf,YAAY,CAACF,GAAG,CAACF,GAAAA,CAAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIX,gBAAAA,CAAiB,sBAAA,CAAA;AAC7B,YAAA;AAEA,YAAA,MAAM+B,cAAc,IAAI,CAAChB,YAAY,CAACC,GAAG,CAACL,GAAAA,CAAAA;;AAG1CqB,YAAAA,MAAAA,CAAOC,IAAI,CAACH,YAAAA,CAAAA,CAAYI,OAAO,CAAC,CAACxB,GAAAA,GAAAA;AAC/B,gBAAA,MAAM,EAAEO,MAAM,EAAE,GAAGa,YAAU,CAACpB,GAAAA,CAAI;AAClC,gBAAA,IAAIO,WAAW,UAAA,EAAY;AACzBa,oBAAAA,YAAU,CAACpB,GAAAA,CAAI,CAACO,MAAM,GAAGN,GAAAA;AAC3B,gBAAA;AACF,YAAA,CAAA,CAAA;AAEAoB,YAAAA,WAAAA,CAAYI,aAAa,CAAC,IAAI,CAACC,iBAAiB,CAACN,YAAAA,CAAAA,CAAAA;AAEjDE,YAAAA,MAAAA,CAAOC,IAAI,CAACH,YAAAA,CAAAA,CAAYI,OAAO,CAAC,CAACxB,GAAAA,GAAAA;gBAC/B,MAAME,SAAAA,GAAYkB,YAAU,CAACpB,GAAAA,CAAI;AAEjC,gBAAA,IAAI2B,sBAAWzB,SAAAA,CAAAA,EAAY;AACzB,oBAAA,MAAMY,iBAAAA,GAAoBZ,SAAAA;oBAC1B,IAAI;AAAC,wBAAA,YAAA;AAAc,wBAAA;AAAW,qBAAA,CAAC0B,QAAQ,CAACd,iBAAAA,CAAkBe,QAAQ,CAAA,EAAG;AACnE,wBAAA,IACEf,kBAAkBP,MAAM,KAAKN,OAC7Ba,iBAAAA,CAAkBN,eAAe,KAAKsB,SAAAA,EACtC;;AAEA,4BAAA,MAAMtB,eAAAA,GAAkBY,YAAU,CAChCN,iBAAAA,CAAkBN,eAAe,CAClC;4BAED,IAAIA,eAAAA,CAAgBuB,QAAQ,KAAKD,SAAAA,EAAW;AAC1ChB,gCAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,IAAA;4BAC/B,CAAA,MAAO;AACLjB,gCAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,KAAA;AAC/B,4BAAA;wBACF,CAAA,MAAO;AACLjB,4BAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,IAAA;AAC/B,wBAAA;AACF,oBAAA;oBAEA,IAAI,CAAChC,WAAW,CAAC;AACfC,wBAAAA,GAAAA;AACAC,wBAAAA,GAAAA;wBACAC,SAAAA,EAAWY;AACb,qBAAA,CAAA;AACF,gBAAA;AACF,YAAA,CAAA,CAAA;YAEA,OAAOO,WAAAA;AACT,QAAA,CAAA;AAEA;;AAEC,QACDW,mBAA6BC,KAA6B,EAAA;;AAGxD,YAAA,IAAIA,MAAMhC,GAAG,IAAIgC,MAAMhC,GAAG,KAAKiC,qBAAqBD,KAAAA,CAAAA,EAAQ;AAC1D,gBAAA,MAAM,IAAI3C,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,YAAA;AAEA,YAAA,MAAMW,GAAAA,GAAMgC,KAAAA,CAAMhC,GAAG,IAAIiC,oBAAAA,CAAqBD,KAAAA,CAAAA;AAE9C,YAAA,IAAI,IAAI,CAAC5B,YAAY,CAACF,GAAG,CAACF,GAAAA,CAAAA,EAAM;AAC9B,gBAAA,MAAM,IAAIX,gBAAAA,CAAiB,2BAAA,CAAA;AAC7B,YAAA;AAEA,YAAA,MAAM+B,cAAcc,aAAAA,CAAoB;AACtCC,gBAAAA,SAAAA,EAAWH,MAAMI,YAAY;AAC7BC,gBAAAA,GAAAA,EAAKC,IAAAA,CAAKC,IAAI,CACZC,MAAAA,CAAOC,IAAI,CAACC,GAAG,CAACC,GAAG,EACnBX,KAAAA,CAAMI,YAAY,EAClB,eAAA,EACAJ,MAAMI,YAAY,CAAA;gBAEpBQ,QAAAA,EAAU,CAAC,WAAW;AACxB,aAAA,CAAA;AAEA,YAAA,IAAI,CAACxC,YAAY,CAACyC,GAAG,CAAC7C,GAAAA,EAAKoB,WAAAA,CAAAA;YAE3BA,WAAAA,CACG0B,MAAM,CAAC9C,GAAAA,CAAAA,CACP6C,GAAG,CAAC,MAAA,EAAQb,KAAAA,CAAMe,IAAI,IAAIC,mBAAAA,CAAUC,eAAe,CAAA,CACnDJ,GAAG,CACF,gBAAA,EACAb,KAAAA,CAAMkB,cAAc,IAAIC,aAAAA,CAAQC,oBAAoB,CAACpB,KAAAA,CAAMqB,UAAU,CAAA,CAAA,CAEtER,GAAG,CAAC,MAAA,EAAQ;AACXT,gBAAAA,YAAAA,EAAcJ,MAAMI,YAAY;AAChCiB,gBAAAA,UAAAA,EAAYrB,MAAMqB,UAAU;AAC5BC,gBAAAA,WAAAA,EAAatB,MAAMsB,WAAW;AAC9BC,gBAAAA,WAAAA,EAAavB,MAAMuB;aACrB,CAAA,CACCV,GAAG,CAAC,SAAA,EAAW;AACd,gBAAA,GAAIb,KAAAA,CAAMwB,OAAO,IAAI,EAAE;AACvBC,gBAAAA,eAAAA,EAAiBzB,MAAMyB;aACzB,CAAA,CACCZ,GAAG,CAAC,eAAA,EAAiBb,KAAAA,CAAM0B,aAAa,EACxCb,GAAG,CAAC,QAAA,EAAUb,KAAAA,CAAM2B,MAAM,CAAA;AAE7B,YAAA,IAAI,CAACzC,2BAA2B,CAAClB,GAAAA,EAAKgC,MAAMb,UAAU,CAAA;YAEtD,OAAOC,WAAAA;AACT,QAAA,CAAA;AAEAwC,QAAAA,eAAAA,CAAAA,CAA2B5B,KAAU,EAAA;YACnC,MAAM,EAAEhC,GAAG,EAAE,GAAGgC,KAAAA;AAEhB,YAAA,IAAI,CAAC,IAAI,CAAC5B,YAAY,CAACF,GAAG,CAACF,GAAAA,CAAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIX,gBAAAA,CAAiB,sBAAA,CAAA;AAC7B,YAAA;AAEA,YAAA,MAAM+B,cAAc,IAAI,CAAChB,YAAY,CAACC,GAAG,CAACL,GAAAA,CAAAA;AAE1C,YAAA,MAAM6D,aAAAA,GAAgBzC,WAAAA,CAAY0C,MAAM,CAAC3C,UAAU;YAEnD,MAAM4C,aAAAA,GAAgBrE,EAAEsE,MAAM,CAAChC,MAAMb,UAAU,EAAE,CAAC8C,IAAAA,EAAMlE,GAAAA,GAAAA;gBACtD,OAAOL,CAAAA,CAAEQ,GAAG,CAAC2D,aAAAA,EAAe9D,QAAQ,CAACmE,yBAAAA,CAAeL,aAAa,CAAC9D,GAAAA,CAAI,CAAA;AACxE,YAAA,CAAA,CAAA;YAEA,MAAMoE,OAAAA,GAAUzE,CAAAA,CAAE0E,UAAU,CAAC/C,MAAAA,CAAOC,IAAI,CAACyC,aAAAA,CAAAA,EAAgB1C,MAAAA,CAAOC,IAAI,CAACuC,aAAAA,CAAAA,CAAAA;YACrE,MAAMQ,WAAAA,GAAc3E,CAAAA,CAAE0E,UAAU,CAAC/C,MAAAA,CAAOC,IAAI,CAACuC,aAAAA,CAAAA,EAAgBxC,MAAAA,CAAOC,IAAI,CAACyC,aAAAA,CAAAA,CAAAA;YACzE,MAAMO,aAAAA,GAAgB5E,CAAAA,CAAE6E,YAAY,CAAClD,MAAAA,CAAOC,IAAI,CAACuC,aAAAA,CAAAA,EAAgBxC,MAAAA,CAAOC,IAAI,CAACyC,aAAAA,CAAAA,CAAAA;;YAG7EM,WAAAA,CAAY9C,OAAO,CAAC,CAACxB,GAAAA,GAAAA;gBACnB,MAAME,SAAAA,GAAY4D,aAAa,CAAC9D,GAAAA,CAAI;;gBAGpC,IAAImE,yBAAAA,CAAejE,SAAAA,CAAAA,IAAcyB,qBAAAA,CAAWzB,SAAAA,CAAAA,EAAY;AACtD,oBAAA,MAAMY,iBAAAA,GAAoBZ,SAAAA;AAC1B,oBAAA,MAAMa,mBAAAA,GAAsBD,iBAAAA,CAAkBE,UAAU,IAAIF,kBAAkBG,QAAQ;oBAEtF,IAAIF,mBAAAA,KAAwB,IAAA,IAAQA,mBAAAA,KAAwBe,SAAAA,EAAW;wBACrE,IAAI,CAACjB,aAAa,CAACX,SAAAA,CAAAA;AACrB,oBAAA;AACF,gBAAA;AACF,YAAA,CAAA,CAAA;YAEAqE,aAAAA,CAAc/C,OAAO,CAAC,CAACxB,GAAAA,GAAAA;gBACrB,MAAMN,YAAAA,GAAeoE,aAAa,CAAC9D,GAAAA,CAAI;gBACvC,MAAMP,YAAAA,GAAeuE,aAAa,CAAChE,GAAAA,CAAI;AAEvC,gBAAA,IAAI,CAAC2B,qBAAAA,CAAWjC,YAAAA,CAAAA,IAAiBiC,qBAAAA,CAAWlC,YAAAA,CAAAA,EAAe;oBACzD,OAAO,IAAI,CAACM,WAAW,CAAC;AACtBC,wBAAAA,GAAAA;AACAC,wBAAAA,GAAAA;wBACAC,SAAAA,EAAWT;AACb,qBAAA,CAAA;AACF,gBAAA;AAEA,gBAAA,IAAIkC,qBAAAA,CAAWjC,YAAAA,CAAAA,IAAiB,CAACiC,qBAAAA,CAAWlC,YAAAA,CAAAA,EAAe;oBACzD,OAAO,IAAI,CAACoB,aAAa,CAACnB,YAAAA,CAAAA;AAC5B,gBAAA;gBAEA,IAAIiC,qBAAAA,CAAWjC,YAAAA,CAAAA,IAAiBiC,qBAAAA,CAAWlC,YAAAA,CAAAA,EAAe;AACxD,oBAAA,MAAMqB,iBAAAA,GAAoBrB,YAAAA;AAC1B,oBAAA,MAAMgF,oBAAAA,GAAuB/E,YAAAA;AAC7B,oBAAA,MAAMgF,sBAAAA,GACJD,oBAAAA,CAAqBzD,UAAU,IAAIyD,qBAAqBxD,QAAQ;AAElE,oBAAA,MAAM0D,YAAAA,GAAejF,YAAAA,CAAamC,QAAQ,KAAKf,kBAAkBe,QAAQ;oBACzE,MAAM+C,yBAAAA,GACJF,sBAAAA,KAA2B5D,iBAAAA,CAAkBN,eAAe;oBAE9D,IAAI,CAACmE,gBAAgBC,yBAAAA,EAA2B;wBAC9C,IAAI,CAAC/D,aAAa,CAACnB,YAAAA,CAAAA;AACrB,oBAAA;;AAGAF,oBAAAA,4BAAAA,CAA6BsB,iBAAAA,EAAmBpB,YAAAA,CAAAA;;oBAGhD,MAAMmF,qBAAAA,GAAwBb,aAAa,CAAChE,GAAAA,CAAI;AAChD,oBAAA,MAAM8E,mBACJD,qBAAAA,CAAsBE,UAAU,KAAKjD,SAAAA,IACrC+C,qBAAAA,CAAsBE,UAAU,KAAK,IAAA;oBAEvC,IAAIrF,YAAAA,CAAaqF,UAAU,EAAE;AAC3B,wBAAA,IAAID,gBAAAA,EAAkB;;4BAEpBhE,iBAAAA,CAAkBiE,UAAU,GAAGF,qBAAAA,CAAsBE,UAAU;wBACjE,CAAA,MAAO;;AAEL,4BAAA,OAAOjE,kBAAkBiE,UAAU;AACrC,wBAAA;AACF,oBAAA,CAAA,MAAO,IAAID,gBAAAA,EAAkB;;wBAE3BhE,iBAAAA,CAAkBiE,UAAU,GAAGF,qBAAAA,CAAsBE,UAAU;AACjE,oBAAA;oBAEA,IAAIN,oBAAAA,CAAqBzD,UAAU,EAAE;AACnCF,wBAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,IAAA;oBAC/B,CAAA,MAAO,IAAI0C,oBAAAA,CAAqBxD,QAAQ,EAAE;AACxCH,wBAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,KAAA;AAC/B,oBAAA;oBAEA,OAAO,IAAI,CAAChC,WAAW,CAAC;AACtBC,wBAAAA,GAAAA;AACAC,wBAAAA,GAAAA;wBACAC,SAAAA,EAAWY;AACb,qBAAA,CAAA;AACF,gBAAA;AACF,YAAA,CAAA,CAAA;;YAGAsD,OAAAA,CAAQ5C,OAAO,CAAC,CAACxB,GAAAA,GAAAA;gBACf,MAAME,SAAAA,GAAY8D,aAAa,CAAChE,GAAAA,CAAI;AAEpC,gBAAA,IAAI2B,sBAAWzB,SAAAA,CAAAA,EAAY;AACzB,oBAAA,MAAMY,iBAAAA,GAAoBZ,SAAAA;oBAC1B,IAAI;AAAC,wBAAA,YAAA;AAAc,wBAAA;AAAW,qBAAA,CAAC0B,QAAQ,CAACd,iBAAAA,CAAkBe,QAAQ,CAAA,EAAG;AACnE,wBAAA,IACEf,kBAAkBP,MAAM,KAAKN,OAC7Ba,iBAAAA,CAAkBN,eAAe,KAAKsB,SAAAA,EACtC;;AAEA,4BAAA,MAAMtB,eAAAA,GAAkBwD,aAAa,CACnClD,iBAAAA,CAAkBN,eAAe,CAClC;4BAED,IAAIA,eAAAA,CAAgBuB,QAAQ,KAAKD,SAAAA,EAAW;AAC1ChB,gCAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,IAAA;4BAC/B,CAAA,MAAO;AACLjB,gCAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,KAAA;AAC/B,4BAAA;wBACF,CAAA,MAAO;AACLjB,4BAAAA,iBAAAA,CAAkBiB,QAAQ,GAAG,IAAA;AAC/B,wBAAA;AACF,oBAAA;oBAEA,IAAI,CAAChC,WAAW,CAAC;AACfC,wBAAAA,GAAAA;AACAC,wBAAAA,GAAAA;wBACAC,SAAAA,EAAWY;AACb,qBAAA,CAAA;AACF,gBAAA;AACF,YAAA,CAAA,CAAA;AAEAO,YAAAA,WAAAA,CACGyB,GAAG,CAAC,MAAA,EAAQb,KAAAA,CAAMe,IAAI,IAAI3B,WAAAA,CAAY0C,MAAM,CAACf,IAAI,CAAA,CACjDF,GAAG,CAAC;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc,aAAA,EAAEb,KAAAA,CAAMsB,WAAW,CAAA,CAC9CT,GAAG,CAAC;AAAC,gBAAA,MAAA;AAAQ,gBAAA;AAAc,aAAA,EAAEb,KAAAA,CAAMuB,WAAW,CAAA,CAC9CV,GAAG,CAAC,SAAA,EAAW;AACd,gBAAA,GAAIb,KAAAA,CAAMwB,OAAO,IAAI,EAAE;AACvBC,gBAAAA,eAAAA,EAAiBzB,MAAMyB;aACzB,CAAA,CACCZ,GAAG,CAAC,eAAA,EAAiBb,KAAAA,CAAM0B,aAAa,CAAA,CACxClC,aAAa,CAAC,IAAI,CAACC,iBAAiB,CAACsC,aAAAA,CAAAA,CAAAA;YAExC,OAAO3C,WAAAA;AACT,QAAA,CAAA;AAEA2D,QAAAA,iBAAAA,CAAAA,CAA6B/E,GAAW,EAAA;AACtC,YAAA,IAAI,CAAC,IAAI,CAACI,YAAY,CAACF,GAAG,CAACF,GAAAA,CAAAA,EAAM;AAC/B,gBAAA,MAAM,IAAIX,gBAAAA,CAAiB,sBAAA,CAAA;AAC7B,YAAA;AAEA,YAAA,IAAI,CAAC2F,UAAU,CAACzD,OAAO,CAAC,CAAC0D,KAAAA,GAAAA;AACvBA,gBAAAA,KAAAA,CAAMC,iBAAiB,CAAClF,GAAAA,CAAAA;AAC1B,YAAA,CAAA,CAAA;AAEA,YAAA,IAAI,CAACI,YAAY,CAACmB,OAAO,CAAC,CAAC4D,EAAAA,GAAAA;AACzBA,gBAAAA,EAAAA,CAAGD,iBAAiB,CAAClF,GAAAA,CAAAA;AACvB,YAAA,CAAA,CAAA;AAEA,YAAA,OAAO,IAAI,CAACI,YAAY,CAACC,GAAG,CAACL,KAAKoF,MAAM,EAAA;AAC1C,QAAA;AACF,KAAA;AACF;AAEA;;;;;;AAMC,IACD,MAAMnD,oBAAAA,GAAuB,CAAC,EAC5BG,YAAY,EAGb,GAA+B,CAAC,KAAK,EAAEA,YAAAA,CAAa,CAAC,EAAEA,YAAAA,CAAAA,CAAc;AAEtE,MAAMzB,gBAAAA,GAAmB,CAAC,EACxBZ,GAAG,EACHE,SAAS,EACTD,GAAG,EACHO,eAAAA,GAAkB,EAAE,EAMrB,GAAA;AACC,IAAA,MAAM8E,IAAAA,GAAY;QAChBC,IAAAA,EAAM,UAAA;QACNhF,MAAAA,EAAQN,GAAAA;QACRuF,OAAAA,EAAShF,eAAAA,CAAgBgF,OAAO,IAAI1D,SAAAA;QACpC6B,aAAAA,EAAenD,eAAAA,CAAgBmD,aAAa,IAAI7B,SAAAA;;;QAGhD,GAAItB,eAAAA,CAAgBuE,UAAU,IAAI;AAAEA,YAAAA,UAAAA,EAAYvE,gBAAgBuE;;AAClE,KAAA;AAEA,IAAA,OAAQ7E,UAAU2B,QAAQ;QACxB,KAAK,UAAA;AAAY,YAAA;AACfyD,gBAAAA,IAAAA,CAAKzD,QAAQ,GAAG,UAAA;gBAEhB,IAAI3B,SAAAA,CAAU6B,QAAQ,EAAE;AACtBuD,oBAAAA,IAAAA,CAAKrE,QAAQ,GAAGjB,GAAAA;gBAClB,CAAA,MAAO;AACLsF,oBAAAA,IAAAA,CAAKtE,UAAU,GAAGhB,GAAAA;AACpB,gBAAA;AACA,gBAAA;AACF,YAAA;QACA,KAAK,WAAA;AAAa,YAAA;AAChBsF,gBAAAA,IAAAA,CAAKzD,QAAQ,GAAG,WAAA;AAChByD,gBAAAA,IAAAA,CAAKtE,UAAU,GAAGhB,GAAAA;AAClB,gBAAA;AACF,YAAA;QACA,KAAK,WAAA;AAAa,YAAA;AAChBsF,gBAAAA,IAAAA,CAAKzD,QAAQ,GAAG,WAAA;AAChByD,gBAAAA,IAAAA,CAAKrE,QAAQ,GAAGjB,GAAAA;AAChB,gBAAA;AACF,YAAA;QACA,KAAK,YAAA;AAAc,YAAA;AACjBsF,gBAAAA,IAAAA,CAAKzD,QAAQ,GAAG,YAAA;gBAEhB,IAAI3B,SAAAA,CAAU6B,QAAQ,EAAE;AACtBuD,oBAAAA,IAAAA,CAAKrE,QAAQ,GAAGjB,GAAAA;gBAClB,CAAA,MAAO;AACLsF,oBAAAA,IAAAA,CAAKtE,UAAU,GAAGhB,GAAAA;AACpB,gBAAA;AAEA,gBAAA;AACF,YAAA;AAEF;;IAGA,MAAM,EAAEuF,IAAI,EAAE1D,QAAQ,EAAEtB,MAAM,EAAE,GAAGkF,WAAAA,EAAa,GAAGH,IAAAA;AAEnD,IAAA,MAAMI,MAAAA,GAAS;AACbH,QAAAA,IAAAA;AACA1D,QAAAA,QAAAA;AACAtB,QAAAA,MAAAA;AACA,QAAA,GAAGkF;AACL,KAAA;IAEA,OAAOC,MAAAA;AACT,CAAA;;;;"}
1
+ {"version":3,"file":"content-type-builder.js","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\nimport type { InternalRelationAttribute, InternalAttribute } from './types';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n 'conditions', // Don't automatically preserve conditions\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(\n this: any,\n { key, uid, attribute }: { key: string; uid: string; attribute: InternalRelationAttribute }\n ) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n // When generating the inverse relation, preserve existing conditions if they exist\n // If the target attribute already exists and has conditions, preserve them\n const targetAttributeData = targetAttribute || {};\n\n // If the source doesn't have conditions but the target does, preserve target's conditions\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute: targetAttributeData })\n );\n },\n\n unsetRelation(\n this: any,\n attribute: Schema.Attribute.Relation<Schema.Attribute.RelationKind.Any>\n ) {\n if (!('target' in attribute) || !attribute.target) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = attributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const dir = infos.plugin\n ? path.join(strapi.dirs.app.extensions, infos.plugin, 'content-types', infos.singularName)\n : path.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName);\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir,\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n\n if (targetAttributeName !== null && targetAttributeName !== undefined) {\n this.unsetRelation(attribute);\n }\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key] as InternalAttribute;\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute as InternalRelationAttribute,\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const relationAttribute = newAttribute as InternalRelationAttribute;\n const oldRelationAttribute = oldAttribute as InternalRelationAttribute;\n const oldTargetAttributeName =\n oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === relationAttribute.relation;\n const targetAttributeHasChanged =\n oldTargetAttributeName !== relationAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(relationAttribute, oldAttribute);\n\n // Handle conditions explicitly - only preserve if present and not undefined in new attribute\n const newAttributeFromInfos = newAttributes[key];\n const hasNewConditions =\n newAttributeFromInfos.conditions !== undefined &&\n newAttributeFromInfos.conditions !== null;\n\n if (oldAttribute.conditions) {\n if (hasNewConditions) {\n // Conditions are still present, keep them\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n } else {\n // Conditions were removed (undefined or null), ensure they're not preserved\n delete relationAttribute.conditions;\n }\n } else if (hasNewConditions) {\n // New conditions added\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n }\n\n if (oldRelationAttribute.inversedBy) {\n relationAttribute.dominant = true;\n } else if (oldRelationAttribute.mappedBy) {\n relationAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = newAttributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n plugin,\n singularName,\n}: {\n plugin?: string;\n singularName: string;\n}): Internal.UID.ContentType =>\n `${plugin ? `plugin` : `api`}::${plugin || singularName}.${singularName}`;\n\nconst generateRelation = ({\n key,\n attribute,\n uid,\n targetAttribute = {},\n}: {\n key: string;\n attribute: InternalRelationAttribute;\n uid: string;\n targetAttribute?: Partial<InternalRelationAttribute>;\n}) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n // Preserve conditions from targetAttribute if they exist\n // This allows each side of the relation to maintain its own conditions\n ...(targetAttribute.conditions && { conditions: targetAttribute.conditions }),\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n const result = {\n type,\n relation,\n target,\n ...restOptions,\n };\n\n return result;\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","targetAttributeData","setAttribute","generateRelation","unsetRelation","relationAttribute","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","dir","plugin","path","join","strapi","dirs","app","extensions","singularName","api","createSchemaHandler","modelName","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","oldRelationAttribute","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","newAttributeFromInfos","hasNewConditions","conditions","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions","result"],"mappings":"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"}
@@ -107,9 +107,10 @@ function createComponentBuilder() {
107
107
  if (this.contentTypes.has(uid)) {
108
108
  throw new ApplicationError('contentType.alreadyExists');
109
109
  }
110
+ const dir = infos.plugin ? path__default.join(strapi.dirs.app.extensions, infos.plugin, 'content-types', infos.singularName) : path__default.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName);
110
111
  const contentType = createSchemaHandler({
111
112
  modelName: infos.singularName,
112
- dir: path__default.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName),
113
+ dir,
113
114
  filename: `schema.json`
114
115
  });
115
116
  this.contentTypes.set(uid, contentType);
@@ -261,7 +262,7 @@ function createComponentBuilder() {
261
262
  * @param {object} options options
262
263
  * @param {string} options.singularName content-type singularName
263
264
  * @returns {string} uid
264
- */ const createContentTypeUID = ({ singularName })=>`api::${singularName}.${singularName}`;
265
+ */ const createContentTypeUID = ({ plugin, singularName })=>`${plugin ? `plugin` : `api`}::${plugin || singularName}.${singularName}`;
265
266
  const generateRelation = ({ key, attribute, uid, targetAttribute = {} })=>{
266
267
  const opts = {
267
268
  type: 'relation',
@@ -1 +1 @@
1
- {"version":3,"file":"content-type-builder.mjs","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\nimport type { InternalRelationAttribute, InternalAttribute } from './types';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n 'conditions', // Don't automatically preserve conditions\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(\n this: any,\n { key, uid, attribute }: { key: string; uid: string; attribute: InternalRelationAttribute }\n ) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n // When generating the inverse relation, preserve existing conditions if they exist\n // If the target attribute already exists and has conditions, preserve them\n const targetAttributeData = targetAttribute || {};\n\n // If the source doesn't have conditions but the target does, preserve target's conditions\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute: targetAttributeData })\n );\n },\n\n unsetRelation(\n this: any,\n attribute: Schema.Attribute.Relation<Schema.Attribute.RelationKind.Any>\n ) {\n if (!('target' in attribute) || !attribute.target) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = attributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir: path.join(\n strapi.dirs.app.api,\n infos.singularName,\n 'content-types',\n infos.singularName\n ),\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n\n if (targetAttributeName !== null && targetAttributeName !== undefined) {\n this.unsetRelation(attribute);\n }\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key] as InternalAttribute;\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute as InternalRelationAttribute,\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const relationAttribute = newAttribute as InternalRelationAttribute;\n const oldRelationAttribute = oldAttribute as InternalRelationAttribute;\n const oldTargetAttributeName =\n oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === relationAttribute.relation;\n const targetAttributeHasChanged =\n oldTargetAttributeName !== relationAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(relationAttribute, oldAttribute);\n\n // Handle conditions explicitly - only preserve if present and not undefined in new attribute\n const newAttributeFromInfos = newAttributes[key];\n const hasNewConditions =\n newAttributeFromInfos.conditions !== undefined &&\n newAttributeFromInfos.conditions !== null;\n\n if (oldAttribute.conditions) {\n if (hasNewConditions) {\n // Conditions are still present, keep them\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n } else {\n // Conditions were removed (undefined or null), ensure they're not preserved\n delete relationAttribute.conditions;\n }\n } else if (hasNewConditions) {\n // New conditions added\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n }\n\n if (oldRelationAttribute.inversedBy) {\n relationAttribute.dominant = true;\n } else if (oldRelationAttribute.mappedBy) {\n relationAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = newAttributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n singularName,\n}: {\n singularName: string;\n}): Internal.UID.ContentType => `api::${singularName}.${singularName}`;\n\nconst generateRelation = ({\n key,\n attribute,\n uid,\n targetAttribute = {},\n}: {\n key: string;\n attribute: InternalRelationAttribute;\n uid: string;\n targetAttribute?: Partial<InternalRelationAttribute>;\n}) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n // Preserve conditions from targetAttribute if they exist\n // This allows each side of the relation to maintain its own conditions\n ...(targetAttribute.conditions && { conditions: targetAttribute.conditions }),\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n const result = {\n type,\n relation,\n target,\n ...restOptions,\n };\n\n return result;\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","targetAttributeData","setAttribute","generateRelation","unsetRelation","relationAttribute","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","createSchemaHandler","modelName","singularName","dir","path","join","strapi","dirs","app","api","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","oldRelationAttribute","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","newAttributeFromInfos","hasNewConditions","conditions","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions","result"],"mappings":"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"}
1
+ {"version":3,"file":"content-type-builder.mjs","sources":["../../../../server/src/services/schema-builder/content-type-builder.ts"],"sourcesContent":["import path from 'path';\nimport _ from 'lodash';\n\nimport { strings, errors } from '@strapi/utils';\nimport type { Schema, Internal } from '@strapi/types';\nimport { isRelation, isConfigurable } from '../../utils/attributes';\nimport { typeKinds } from '../constants';\nimport createSchemaHandler from './schema-handler';\nimport { CreateContentTypeInput } from '../../controllers/validation/content-type';\nimport type { InternalRelationAttribute, InternalAttribute } from './types';\n\nconst { ApplicationError } = errors;\n\nconst reuseUnsetPreviousProperties = (\n newAttribute: Schema.Attribute.AnyAttribute,\n oldAttribute: Schema.Attribute.AnyAttribute\n) => {\n _.defaults(\n newAttribute,\n _.omit(oldAttribute, [\n 'configurable',\n 'required',\n 'private',\n 'unique',\n 'pluginOptions',\n 'inversedBy',\n 'mappedBy',\n 'conditions', // Don't automatically preserve conditions\n ])\n );\n};\n\nexport default function createComponentBuilder() {\n return {\n setRelation(\n this: any,\n { key, uid, attribute }: { key: string; uid: string; attribute: InternalRelationAttribute }\n ) {\n if (!_.has(attribute, 'target')) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n if (!targetCT) {\n throw new ApplicationError(`Content type ${attribute.target} not found`);\n }\n\n const targetAttribute = targetCT.getAttribute(attribute.targetAttribute);\n\n if (!attribute.targetAttribute) {\n return;\n }\n\n // When generating the inverse relation, preserve existing conditions if they exist\n // If the target attribute already exists and has conditions, preserve them\n const targetAttributeData = targetAttribute || {};\n\n // If the source doesn't have conditions but the target does, preserve target's conditions\n\n targetCT.setAttribute(\n attribute.targetAttribute,\n generateRelation({ key, attribute, uid, targetAttribute: targetAttributeData })\n );\n },\n\n unsetRelation(\n this: any,\n attribute: Schema.Attribute.Relation<Schema.Attribute.RelationKind.Any>\n ) {\n if (!('target' in attribute) || !attribute.target) {\n return;\n }\n\n const targetCT = this.contentTypes.get(attribute.target);\n\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n const targetAttribute = targetCT.getAttribute(targetAttributeName);\n\n if (!targetAttribute) return;\n\n return targetCT.deleteAttribute(targetAttributeName);\n },\n\n createContentTypeAttributes(\n this: any,\n uid: string,\n attributes: CreateContentTypeInput['attributes']\n ) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n // support self referencing content type relation\n Object.keys(attributes).forEach((key) => {\n const { target } = attributes[key];\n if (target === '__self__') {\n attributes[key].target = uid;\n }\n });\n\n contentType.setAttributes(this.convertAttributes(attributes));\n\n Object.keys(attributes).forEach((key) => {\n const attribute = attributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = attributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n return contentType;\n },\n\n /**\n * Creates a content type in memory to be written to files later on\n */\n createContentType(this: any, infos: CreateContentTypeInput) {\n // TODO:: check for unique uid / singularName & pluralName & collectionName\n\n if (infos.uid && infos.uid !== createContentTypeUID(infos)) {\n throw new ApplicationError('contentType.invalidUID');\n }\n\n const uid = infos.uid ?? createContentTypeUID(infos);\n\n if (this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.alreadyExists');\n }\n\n const dir = infos.plugin\n ? path.join(strapi.dirs.app.extensions, infos.plugin, 'content-types', infos.singularName)\n : path.join(strapi.dirs.app.api, infos.singularName, 'content-types', infos.singularName);\n\n const contentType = createSchemaHandler({\n modelName: infos.singularName,\n dir,\n filename: `schema.json`,\n });\n\n this.contentTypes.set(uid, contentType);\n\n contentType\n .setUID(uid)\n .set('kind', infos.kind || typeKinds.COLLECTION_TYPE)\n .set(\n 'collectionName',\n infos.collectionName || strings.nameToCollectionName(infos.pluralName)\n )\n .set('info', {\n singularName: infos.singularName,\n pluralName: infos.pluralName,\n displayName: infos.displayName,\n description: infos.description,\n })\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .set('config', infos.config);\n\n this.createContentTypeAttributes(uid, infos.attributes);\n\n return contentType;\n },\n\n editContentType(this: any, infos: any) {\n const { uid } = infos;\n\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n const contentType = this.contentTypes.get(uid);\n\n const oldAttributes = contentType.schema.attributes;\n\n const newAttributes = _.omitBy(infos.attributes, (attr, key) => {\n return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);\n });\n\n const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));\n const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));\n const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));\n\n // remove old relations\n deletedKeys.forEach((key) => {\n const attribute = oldAttributes[key];\n\n // if the old relation has a target attribute. we need to remove it in the target type\n if (isConfigurable(attribute) && isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n const targetAttributeName = relationAttribute.inversedBy || relationAttribute.mappedBy;\n\n if (targetAttributeName !== null && targetAttributeName !== undefined) {\n this.unsetRelation(attribute);\n }\n }\n });\n\n remainingKeys.forEach((key) => {\n const oldAttribute = oldAttributes[key];\n const newAttribute = newAttributes[key] as InternalAttribute;\n\n if (!isRelation(oldAttribute) && isRelation(newAttribute)) {\n return this.setRelation({\n key,\n uid,\n attribute: newAttribute as InternalRelationAttribute,\n });\n }\n\n if (isRelation(oldAttribute) && !isRelation(newAttribute)) {\n return this.unsetRelation(oldAttribute);\n }\n\n if (isRelation(oldAttribute) && isRelation(newAttribute)) {\n const relationAttribute = newAttribute as InternalRelationAttribute;\n const oldRelationAttribute = oldAttribute as InternalRelationAttribute;\n const oldTargetAttributeName =\n oldRelationAttribute.inversedBy || oldRelationAttribute.mappedBy;\n\n const sameRelation = oldAttribute.relation === relationAttribute.relation;\n const targetAttributeHasChanged =\n oldTargetAttributeName !== relationAttribute.targetAttribute;\n\n if (!sameRelation || targetAttributeHasChanged) {\n this.unsetRelation(oldAttribute);\n }\n\n // keep extra options that were set manually on oldAttribute\n reuseUnsetPreviousProperties(relationAttribute, oldAttribute);\n\n // Handle conditions explicitly - only preserve if present and not undefined in new attribute\n const newAttributeFromInfos = newAttributes[key];\n const hasNewConditions =\n newAttributeFromInfos.conditions !== undefined &&\n newAttributeFromInfos.conditions !== null;\n\n if (oldAttribute.conditions) {\n if (hasNewConditions) {\n // Conditions are still present, keep them\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n } else {\n // Conditions were removed (undefined or null), ensure they're not preserved\n delete relationAttribute.conditions;\n }\n } else if (hasNewConditions) {\n // New conditions added\n relationAttribute.conditions = newAttributeFromInfos.conditions;\n }\n\n if (oldRelationAttribute.inversedBy) {\n relationAttribute.dominant = true;\n } else if (oldRelationAttribute.mappedBy) {\n relationAttribute.dominant = false;\n }\n\n return this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n // add new relations\n newKeys.forEach((key) => {\n const attribute = newAttributes[key] as InternalAttribute;\n\n if (isRelation(attribute)) {\n const relationAttribute = attribute as InternalRelationAttribute;\n if (['manyToMany', 'oneToOne'].includes(relationAttribute.relation)) {\n if (\n relationAttribute.target === uid &&\n relationAttribute.targetAttribute !== undefined\n ) {\n // self referencing relation\n const targetAttribute = newAttributes[\n relationAttribute.targetAttribute\n ] as InternalRelationAttribute;\n\n if (targetAttribute.dominant === undefined) {\n relationAttribute.dominant = true;\n } else {\n relationAttribute.dominant = false;\n }\n } else {\n relationAttribute.dominant = true;\n }\n }\n\n this.setRelation({\n key,\n uid,\n attribute: relationAttribute,\n });\n }\n });\n\n contentType\n .set('kind', infos.kind || contentType.schema.kind)\n .set(['info', 'displayName'], infos.displayName)\n .set(['info', 'description'], infos.description)\n .set('options', {\n ...(infos.options ?? {}),\n draftAndPublish: infos.draftAndPublish,\n })\n .set('pluginOptions', infos.pluginOptions)\n .setAttributes(this.convertAttributes(newAttributes));\n\n return contentType;\n },\n\n deleteContentType(this: any, uid: string) {\n if (!this.contentTypes.has(uid)) {\n throw new ApplicationError('contentType.notFound');\n }\n\n this.components.forEach((compo: any) => {\n compo.removeContentType(uid);\n });\n\n this.contentTypes.forEach((ct: any) => {\n ct.removeContentType(uid);\n });\n\n return this.contentTypes.get(uid).delete();\n },\n };\n}\n\n/**\n * Returns a uid from a content type infos\n *\n * @param {object} options options\n * @param {string} options.singularName content-type singularName\n * @returns {string} uid\n */\nconst createContentTypeUID = ({\n plugin,\n singularName,\n}: {\n plugin?: string;\n singularName: string;\n}): Internal.UID.ContentType =>\n `${plugin ? `plugin` : `api`}::${plugin || singularName}.${singularName}`;\n\nconst generateRelation = ({\n key,\n attribute,\n uid,\n targetAttribute = {},\n}: {\n key: string;\n attribute: InternalRelationAttribute;\n uid: string;\n targetAttribute?: Partial<InternalRelationAttribute>;\n}) => {\n const opts: any = {\n type: 'relation',\n target: uid,\n private: targetAttribute.private || undefined,\n pluginOptions: targetAttribute.pluginOptions || undefined,\n // Preserve conditions from targetAttribute if they exist\n // This allows each side of the relation to maintain its own conditions\n ...(targetAttribute.conditions && { conditions: targetAttribute.conditions }),\n };\n\n switch (attribute.relation) {\n case 'oneToOne': {\n opts.relation = 'oneToOne';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n break;\n }\n case 'oneToMany': {\n opts.relation = 'manyToOne';\n opts.inversedBy = key;\n break;\n }\n case 'manyToOne': {\n opts.relation = 'oneToMany';\n opts.mappedBy = key;\n break;\n }\n case 'manyToMany': {\n opts.relation = 'manyToMany';\n\n if (attribute.dominant) {\n opts.mappedBy = key;\n } else {\n opts.inversedBy = key;\n }\n\n break;\n }\n default:\n }\n\n // we do this just to make sure we have the same key order when writing to files\n const { type, relation, target, ...restOptions } = opts;\n\n const result = {\n type,\n relation,\n target,\n ...restOptions,\n };\n\n return result;\n};\n"],"names":["ApplicationError","errors","reuseUnsetPreviousProperties","newAttribute","oldAttribute","_","defaults","omit","createComponentBuilder","setRelation","key","uid","attribute","has","targetCT","contentTypes","get","target","targetAttribute","getAttribute","targetAttributeData","setAttribute","generateRelation","unsetRelation","relationAttribute","targetAttributeName","inversedBy","mappedBy","deleteAttribute","createContentTypeAttributes","attributes","contentType","Object","keys","forEach","setAttributes","convertAttributes","isRelation","includes","relation","undefined","dominant","createContentType","infos","createContentTypeUID","dir","plugin","path","join","strapi","dirs","app","extensions","singularName","api","createSchemaHandler","modelName","filename","set","setUID","kind","typeKinds","COLLECTION_TYPE","collectionName","strings","nameToCollectionName","pluralName","displayName","description","options","draftAndPublish","pluginOptions","config","editContentType","oldAttributes","schema","newAttributes","omitBy","attr","isConfigurable","newKeys","difference","deletedKeys","remainingKeys","intersection","oldRelationAttribute","oldTargetAttributeName","sameRelation","targetAttributeHasChanged","newAttributeFromInfos","hasNewConditions","conditions","deleteContentType","components","compo","removeContentType","ct","delete","opts","type","private","restOptions","result"],"mappings":"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"}
@@ -141,12 +141,14 @@ const updateSchema = async (schema)=>{
141
141
  acc[attr.name] = attr.properties;
142
142
  return acc;
143
143
  }, {}));
144
- await index$1.getService('content-types').generateAPI({
145
- displayName: contentType.displayName,
146
- singularName: contentType.singularName,
147
- pluralName: contentType.pluralName,
148
- kind: contentType.kind
149
- });
144
+ if (!contentType.plugin) {
145
+ await index$1.getService('content-types').generateAPI({
146
+ displayName: contentType.displayName,
147
+ singularName: contentType.singularName,
148
+ pluralName: contentType.pluralName,
149
+ kind: contentType.kind
150
+ });
151
+ }
150
152
  }
151
153
  if (action === 'update') {
152
154
  builder.editContentType({
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sources":["../../../server/src/services/schema.ts"],"sourcesContent":["import utils from '@strapi/utils';\nimport { mapValues } from 'lodash/fp';\n\nimport type { Schema } from '@strapi/types';\n\nimport createBuilder from './schema-builder';\nimport { getService } from '../utils';\nimport type { Schema as CTBSchema } from '../controllers/validation/schema';\nimport { getRestrictRelationsTo, isContentTypeVisible } from './content-types';\n\nconst removeEmptyDefaultsOnUpdates = (schema: CTBSchema) => {\n schema.components.forEach((component) => {\n if (component.action === 'delete') {\n return;\n }\n\n component.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if ('default' in properties && properties.default === '') {\n properties.default = undefined;\n }\n }\n });\n });\n\n schema.contentTypes.forEach((contentType) => {\n if (contentType.action === 'delete') {\n return;\n }\n\n contentType.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if ('default' in properties && properties.default === '') {\n properties.default = undefined;\n }\n }\n });\n });\n};\n\nconst removeDeletedUIDTargetFieldsOnUpdates = (schema: CTBSchema) => {\n schema.contentTypes.forEach((contentType) => {\n if (contentType.action === 'delete') {\n return;\n }\n\n contentType.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if (\n properties.type === 'uid' &&\n properties.targetField &&\n !contentType.attributes.find((attr) => attr.name === properties.targetField)\n ) {\n properties.targetField = undefined;\n }\n }\n });\n });\n};\n\nconst formatAttributes = (model: any) => {\n const { getVisibleAttributes } = utils.contentTypes;\n\n // only get attributes that can be seen in the CTB\n return getVisibleAttributes(model).map((key) => {\n return { ...formatAttribute(model.attributes[key]), name: key };\n });\n};\n\nexport const formatAttribute = (attribute: Schema.Attribute.AnyAttribute & Record<string, any>) => {\n if (attribute.type === 'relation') {\n return {\n ...attribute,\n targetAttribute: attribute.inversedBy || attribute.mappedBy || null,\n // Explicitly preserve conditions if they exist\n ...(attribute.conditions && { conditions: attribute.conditions }),\n };\n }\n\n return attribute;\n};\n\nexport const getSchema = async () => {\n const contentTypes = mapValues((contentType) => {\n const {\n uid,\n options,\n globalId,\n pluginOptions,\n kind,\n modelName,\n plugin,\n collectionName,\n info,\n modelType,\n } = contentType;\n\n return {\n uid,\n modelName,\n kind,\n globalId,\n options,\n pluginOptions,\n plugin,\n collectionName,\n info,\n modelType,\n attributes: formatAttributes(contentType),\n visible: isContentTypeVisible(contentType),\n restrictRelationsTo: getRestrictRelationsTo(contentType),\n };\n }, strapi.contentTypes);\n\n const components = mapValues((component) => {\n const { uid, globalId, modelName, collectionName, info, category, modelType } = component;\n\n return {\n uid,\n modelName,\n globalId,\n modelType,\n collectionName,\n category,\n info,\n attributes: formatAttributes(component),\n };\n }, strapi.components);\n\n return {\n contentTypes,\n components,\n };\n};\n\nexport const updateSchema = async (schema: CTBSchema) => {\n const builder = createBuilder();\n const apiHandler = getService('api-handler');\n\n const { components, contentTypes } = schema;\n\n // pre-process data\n removeEmptyDefaultsOnUpdates(schema);\n removeDeletedUIDTargetFieldsOnUpdates(schema);\n\n // we pre create empty typesk\n for (const contentType of contentTypes) {\n if (contentType.action === 'create') {\n builder.createContentType({\n ...contentType,\n attributes: {},\n });\n }\n }\n\n // we pre create empty types\n for (const component of components) {\n if (component.action === 'create') {\n builder.createComponent({\n ...component,\n attributes: {},\n });\n }\n }\n\n for (const contentType of contentTypes) {\n const { action, uid } = contentType;\n\n if (action === 'create') {\n builder.createContentTypeAttributes(\n uid,\n contentType.attributes.reduce((acc: any, attr: any) => {\n acc[attr.name] = attr.properties;\n return acc;\n }, {})\n );\n\n await getService('content-types').generateAPI({\n displayName: contentType!.displayName,\n singularName: contentType!.singularName,\n pluralName: contentType!.pluralName,\n kind: contentType!.kind,\n });\n }\n\n if (action === 'update') {\n builder.editContentType({\n ...contentType,\n attributes: contentType.attributes.reduce((acc: any, attr: any) => {\n // NOTE: handle renaming migrations here by comparing attr name & attr.properties.name\n\n if (attr.action === 'delete') {\n return acc;\n }\n\n acc[attr.name] = attr.properties;\n return acc;\n }, {}),\n });\n }\n\n if (action === 'delete') {\n builder.deleteContentType(uid);\n await apiHandler.backup(uid);\n }\n }\n\n for (const component of components) {\n const { action, uid } = component;\n\n if (action === 'create') {\n builder.createComponentAttributes(\n uid,\n component.attributes.reduce((acc: any, attr: any) => {\n acc[attr.name] = attr.properties;\n return acc;\n }, {})\n );\n }\n\n if (action === 'update') {\n builder.editComponent({\n ...component,\n attributes: component.attributes.reduce((acc: any, attr: any) => {\n if (attr.action === 'delete') {\n return acc;\n }\n\n acc[attr.name] = attr.properties;\n return acc;\n }, {}),\n });\n }\n\n if (action === 'delete') {\n builder.deleteComponent(uid);\n }\n }\n\n // run sanity checks on the schema\n // Relations target existing types\n // Bidirectional relation have their counterpart in the schema\n // Components target existing components\n // Nested components target existing components\n // Dynamic zones target existing components\n\n const APIsToDelete = contentTypes\n .filter((ct: any) => ct.action === 'delete')\n .map((ct: any) => ct.uid);\n\n await builder.writeFiles();\n\n try {\n for (const uid of APIsToDelete) {\n await apiHandler.clear(uid);\n }\n } catch (error) {\n strapi.log.error(error);\n for (const uid of APIsToDelete) {\n await apiHandler.rollback(uid);\n }\n }\n\n for (const contentType of contentTypes) {\n if (contentType.action === 'delete') {\n strapi.eventHub.emit('content-type.delete', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n\n if (contentType.action === 'update') {\n strapi.eventHub.emit('content-type.update', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n\n if (contentType.action === 'create') {\n strapi.eventHub.emit('content-type.create', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n }\n\n for (const component of components) {\n if (component.action === 'delete') {\n strapi.eventHub.emit('component.delete', {\n component: builder.components.get(component.uid),\n });\n }\n\n if (component.action === 'update') {\n strapi.eventHub.emit('component.update', {\n component: builder.components.get(component.uid),\n });\n }\n\n if (component.action === 'create') {\n strapi.eventHub.emit('component.create', {\n component: builder.components.get(component.uid),\n });\n }\n }\n};\n"],"names":["removeEmptyDefaultsOnUpdates","schema","components","forEach","component","action","attributes","attribute","properties","default","undefined","contentTypes","contentType","removeDeletedUIDTargetFieldsOnUpdates","type","targetField","find","attr","name","formatAttributes","model","getVisibleAttributes","utils","map","key","formatAttribute","targetAttribute","inversedBy","mappedBy","conditions","getSchema","mapValues","uid","options","globalId","pluginOptions","kind","modelName","plugin","collectionName","info","modelType","visible","isContentTypeVisible","restrictRelationsTo","getRestrictRelationsTo","strapi","category","updateSchema","builder","createBuilder","apiHandler","getService","createContentType","createComponent","createContentTypeAttributes","reduce","acc","generateAPI","displayName","singularName","pluralName","editContentType","deleteContentType","backup","createComponentAttributes","editComponent","deleteComponent","APIsToDelete","filter","ct","writeFiles","clear","error","log","rollback","eventHub","emit","get"],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sources":["../../../server/src/services/schema.ts"],"sourcesContent":["import utils from '@strapi/utils';\nimport { mapValues } from 'lodash/fp';\n\nimport type { Schema } from '@strapi/types';\n\nimport createBuilder from './schema-builder';\nimport { getService } from '../utils';\nimport type { Schema as CTBSchema } from '../controllers/validation/schema';\nimport { getRestrictRelationsTo, isContentTypeVisible } from './content-types';\n\nconst removeEmptyDefaultsOnUpdates = (schema: CTBSchema) => {\n schema.components.forEach((component) => {\n if (component.action === 'delete') {\n return;\n }\n\n component.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if ('default' in properties && properties.default === '') {\n properties.default = undefined;\n }\n }\n });\n });\n\n schema.contentTypes.forEach((contentType) => {\n if (contentType.action === 'delete') {\n return;\n }\n\n contentType.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if ('default' in properties && properties.default === '') {\n properties.default = undefined;\n }\n }\n });\n });\n};\n\nconst removeDeletedUIDTargetFieldsOnUpdates = (schema: CTBSchema) => {\n schema.contentTypes.forEach((contentType) => {\n if (contentType.action === 'delete') {\n return;\n }\n\n contentType.attributes.forEach((attribute) => {\n if (attribute.action === 'update') {\n const { properties } = attribute;\n\n if (\n properties.type === 'uid' &&\n properties.targetField &&\n !contentType.attributes.find((attr) => attr.name === properties.targetField)\n ) {\n properties.targetField = undefined;\n }\n }\n });\n });\n};\n\nconst formatAttributes = (model: any) => {\n const { getVisibleAttributes } = utils.contentTypes;\n\n // only get attributes that can be seen in the CTB\n return getVisibleAttributes(model).map((key) => {\n return { ...formatAttribute(model.attributes[key]), name: key };\n });\n};\n\nexport const formatAttribute = (attribute: Schema.Attribute.AnyAttribute & Record<string, any>) => {\n if (attribute.type === 'relation') {\n return {\n ...attribute,\n targetAttribute: attribute.inversedBy || attribute.mappedBy || null,\n // Explicitly preserve conditions if they exist\n ...(attribute.conditions && { conditions: attribute.conditions }),\n };\n }\n\n return attribute;\n};\n\nexport const getSchema = async () => {\n const contentTypes = mapValues((contentType) => {\n const {\n uid,\n options,\n globalId,\n pluginOptions,\n kind,\n modelName,\n plugin,\n collectionName,\n info,\n modelType,\n } = contentType;\n\n return {\n uid,\n modelName,\n kind,\n globalId,\n options,\n pluginOptions,\n plugin,\n collectionName,\n info,\n modelType,\n attributes: formatAttributes(contentType),\n visible: isContentTypeVisible(contentType),\n restrictRelationsTo: getRestrictRelationsTo(contentType),\n };\n }, strapi.contentTypes);\n\n const components = mapValues((component) => {\n const { uid, globalId, modelName, collectionName, info, category, modelType } = component;\n\n return {\n uid,\n modelName,\n globalId,\n modelType,\n collectionName,\n category,\n info,\n attributes: formatAttributes(component),\n };\n }, strapi.components);\n\n return {\n contentTypes,\n components,\n };\n};\n\nexport const updateSchema = async (schema: CTBSchema) => {\n const builder = createBuilder();\n const apiHandler = getService('api-handler');\n\n const { components, contentTypes } = schema;\n\n // pre-process data\n removeEmptyDefaultsOnUpdates(schema);\n removeDeletedUIDTargetFieldsOnUpdates(schema);\n\n // we pre create empty typesk\n for (const contentType of contentTypes) {\n if (contentType.action === 'create') {\n builder.createContentType({\n ...contentType,\n attributes: {},\n });\n }\n }\n\n // we pre create empty types\n for (const component of components) {\n if (component.action === 'create') {\n builder.createComponent({\n ...component,\n attributes: {},\n });\n }\n }\n\n for (const contentType of contentTypes) {\n const { action, uid } = contentType;\n\n if (action === 'create') {\n builder.createContentTypeAttributes(\n uid,\n contentType.attributes.reduce((acc: any, attr: any) => {\n acc[attr.name] = attr.properties;\n return acc;\n }, {})\n );\n\n if (!contentType.plugin) {\n await getService('content-types').generateAPI({\n displayName: contentType!.displayName,\n singularName: contentType!.singularName,\n pluralName: contentType!.pluralName,\n kind: contentType!.kind,\n });\n }\n }\n\n if (action === 'update') {\n builder.editContentType({\n ...contentType,\n attributes: contentType.attributes.reduce((acc: any, attr: any) => {\n // NOTE: handle renaming migrations here by comparing attr name & attr.properties.name\n\n if (attr.action === 'delete') {\n return acc;\n }\n\n acc[attr.name] = attr.properties;\n return acc;\n }, {}),\n });\n }\n\n if (action === 'delete') {\n builder.deleteContentType(uid);\n await apiHandler.backup(uid);\n }\n }\n\n for (const component of components) {\n const { action, uid } = component;\n\n if (action === 'create') {\n builder.createComponentAttributes(\n uid,\n component.attributes.reduce((acc: any, attr: any) => {\n acc[attr.name] = attr.properties;\n return acc;\n }, {})\n );\n }\n\n if (action === 'update') {\n builder.editComponent({\n ...component,\n attributes: component.attributes.reduce((acc: any, attr: any) => {\n if (attr.action === 'delete') {\n return acc;\n }\n\n acc[attr.name] = attr.properties;\n return acc;\n }, {}),\n });\n }\n\n if (action === 'delete') {\n builder.deleteComponent(uid);\n }\n }\n\n // run sanity checks on the schema\n // Relations target existing types\n // Bidirectional relation have their counterpart in the schema\n // Components target existing components\n // Nested components target existing components\n // Dynamic zones target existing components\n\n const APIsToDelete = contentTypes\n .filter((ct: any) => ct.action === 'delete')\n .map((ct: any) => ct.uid);\n\n await builder.writeFiles();\n\n try {\n for (const uid of APIsToDelete) {\n await apiHandler.clear(uid);\n }\n } catch (error) {\n strapi.log.error(error);\n for (const uid of APIsToDelete) {\n await apiHandler.rollback(uid);\n }\n }\n\n for (const contentType of contentTypes) {\n if (contentType.action === 'delete') {\n strapi.eventHub.emit('content-type.delete', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n\n if (contentType.action === 'update') {\n strapi.eventHub.emit('content-type.update', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n\n if (contentType.action === 'create') {\n strapi.eventHub.emit('content-type.create', {\n contentType: builder.contentTypes.get(contentType.uid),\n });\n }\n }\n\n for (const component of components) {\n if (component.action === 'delete') {\n strapi.eventHub.emit('component.delete', {\n component: builder.components.get(component.uid),\n });\n }\n\n if (component.action === 'update') {\n strapi.eventHub.emit('component.update', {\n component: builder.components.get(component.uid),\n });\n }\n\n if (component.action === 'create') {\n strapi.eventHub.emit('component.create', {\n component: builder.components.get(component.uid),\n });\n }\n }\n};\n"],"names":["removeEmptyDefaultsOnUpdates","schema","components","forEach","component","action","attributes","attribute","properties","default","undefined","contentTypes","contentType","removeDeletedUIDTargetFieldsOnUpdates","type","targetField","find","attr","name","formatAttributes","model","getVisibleAttributes","utils","map","key","formatAttribute","targetAttribute","inversedBy","mappedBy","conditions","getSchema","mapValues","uid","options","globalId","pluginOptions","kind","modelName","plugin","collectionName","info","modelType","visible","isContentTypeVisible","restrictRelationsTo","getRestrictRelationsTo","strapi","category","updateSchema","builder","createBuilder","apiHandler","getService","createContentType","createComponent","createContentTypeAttributes","reduce","acc","generateAPI","displayName","singularName","pluralName","editContentType","deleteContentType","backup","createComponentAttributes","editComponent","deleteComponent","APIsToDelete","filter","ct","writeFiles","clear","error","log","rollback","eventHub","emit","get"],"mappings":"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"}
@@ -139,12 +139,14 @@ const updateSchema = async (schema)=>{
139
139
  acc[attr.name] = attr.properties;
140
140
  return acc;
141
141
  }, {}));
142
- await getService('content-types').generateAPI({
143
- displayName: contentType.displayName,
144
- singularName: contentType.singularName,
145
- pluralName: contentType.pluralName,
146
- kind: contentType.kind
147
- });
142
+ if (!contentType.plugin) {
143
+ await getService('content-types').generateAPI({
144
+ displayName: contentType.displayName,
145
+ singularName: contentType.singularName,
146
+ pluralName: contentType.pluralName,
147
+ kind: contentType.kind
148
+ });
149
+ }
148
150
  }
149
151
  if (action === 'update') {
150
152
  builder.editContentType({