@strapi/strapi 4.25.2 → 4.25.4

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 (115) hide show
  1. package/dist/Strapi.js +3 -3
  2. package/dist/Strapi.js.map +1 -1
  3. package/dist/commands/actions/routes/list/action.js +2 -2
  4. package/dist/commands/actions/routes/list/action.js.map +1 -1
  5. package/dist/commands/utils/helpers.js +2 -2
  6. package/dist/commands/utils/helpers.js.map +1 -1
  7. package/dist/core/app-configuration/index.js +2 -2
  8. package/dist/core/app-configuration/index.js.map +1 -1
  9. package/dist/core/domain/content-type/index.js +4 -4
  10. package/dist/core/domain/content-type/index.js.map +1 -1
  11. package/dist/core/loaders/apis.js +2 -2
  12. package/dist/core/loaders/apis.js.map +1 -1
  13. package/dist/core/loaders/plugins/get-enabled-plugins.js +8 -8
  14. package/dist/core/loaders/plugins/get-enabled-plugins.js.map +1 -1
  15. package/dist/core/loaders/plugins/get-user-plugins-config.js +2 -2
  16. package/dist/core/loaders/plugins/get-user-plugins-config.js.map +1 -1
  17. package/dist/core/loaders/plugins/index.js +6 -6
  18. package/dist/core/loaders/plugins/index.js.map +1 -1
  19. package/dist/core/registries/apis.js +2 -2
  20. package/dist/core/registries/apis.js.map +1 -1
  21. package/dist/core/registries/content-types.js +3 -3
  22. package/dist/core/registries/content-types.js.map +1 -1
  23. package/dist/core/registries/controllers.js +3 -3
  24. package/dist/core/registries/controllers.js.map +1 -1
  25. package/dist/core/registries/custom-fields.js +4 -4
  26. package/dist/core/registries/custom-fields.js.map +1 -1
  27. package/dist/core/registries/hooks.js +2 -2
  28. package/dist/core/registries/hooks.js.map +1 -1
  29. package/dist/core/registries/middlewares.js +3 -3
  30. package/dist/core/registries/middlewares.js.map +1 -1
  31. package/dist/core/registries/modules.js +3 -3
  32. package/dist/core/registries/modules.js.map +1 -1
  33. package/dist/core/registries/plugins.js +2 -2
  34. package/dist/core/registries/plugins.js.map +1 -1
  35. package/dist/core/registries/policies.js +3 -3
  36. package/dist/core/registries/policies.js.map +1 -1
  37. package/dist/core/registries/services.js +3 -3
  38. package/dist/core/registries/services.js.map +1 -1
  39. package/dist/core-api/controller/collection-type.js +3 -3
  40. package/dist/core-api/controller/collection-type.js.map +1 -1
  41. package/dist/core-api/controller/index.js +2 -2
  42. package/dist/core-api/controller/index.js.map +1 -1
  43. package/dist/core-api/controller/single-type.js +2 -2
  44. package/dist/core-api/controller/single-type.js.map +1 -1
  45. package/dist/core-api/controller/transform.js +7 -7
  46. package/dist/core-api/controller/transform.js.map +1 -1
  47. package/dist/core-api/service/collection-type.js +2 -2
  48. package/dist/core-api/service/collection-type.js.map +1 -1
  49. package/dist/core-api/service/pagination.js +10 -10
  50. package/dist/core-api/service/pagination.js.map +1 -1
  51. package/dist/core-api/service/single-type.js +2 -2
  52. package/dist/core-api/service/single-type.js.map +1 -1
  53. package/dist/ee/index.js +3 -3
  54. package/dist/ee/index.js.map +1 -1
  55. package/dist/factories.js +4 -4
  56. package/dist/factories.js.map +1 -1
  57. package/dist/load/filepath-to-prop-path.d.ts +1 -1
  58. package/dist/load/filepath-to-prop-path.d.ts.map +1 -1
  59. package/dist/load/filepath-to-prop-path.js +27 -6
  60. package/dist/load/filepath-to-prop-path.js.map +1 -1
  61. package/dist/load/filepath-to-prop-path.mjs +25 -5
  62. package/dist/load/filepath-to-prop-path.mjs.map +1 -1
  63. package/dist/load/load-files.js +2 -2
  64. package/dist/load/load-files.js.map +1 -1
  65. package/dist/load/load-files.mjs +2 -2
  66. package/dist/load/load-files.mjs.map +1 -1
  67. package/dist/middlewares/body.js +2 -2
  68. package/dist/middlewares/body.js.map +1 -1
  69. package/dist/middlewares/public/index.js +4 -4
  70. package/dist/middlewares/public/index.js.map +1 -1
  71. package/dist/middlewares/responses.js +2 -2
  72. package/dist/middlewares/responses.js.map +1 -1
  73. package/dist/middlewares/security.js +3 -3
  74. package/dist/middlewares/security.js.map +1 -1
  75. package/dist/middlewares/session.js +2 -2
  76. package/dist/middlewares/session.js.map +1 -1
  77. package/dist/services/auth/index.js +3 -3
  78. package/dist/services/auth/index.js.map +1 -1
  79. package/dist/services/core-store.js +3 -3
  80. package/dist/services/core-store.js.map +1 -1
  81. package/dist/services/cron.js +3 -3
  82. package/dist/services/cron.js.map +1 -1
  83. package/dist/services/entity-service/attributes/transforms.js +3 -3
  84. package/dist/services/entity-service/attributes/transforms.js.map +1 -1
  85. package/dist/services/entity-service/components.js +18 -18
  86. package/dist/services/entity-service/components.js.map +1 -1
  87. package/dist/services/entity-service/params.js +2 -2
  88. package/dist/services/entity-service/params.js.map +1 -1
  89. package/dist/services/entity-validator/index.js +19 -19
  90. package/dist/services/entity-validator/index.js.map +1 -1
  91. package/dist/services/server/compose-endpoint.js +7 -7
  92. package/dist/services/server/compose-endpoint.js.map +1 -1
  93. package/dist/services/server/koa.js +3 -3
  94. package/dist/services/server/koa.js.map +1 -1
  95. package/dist/services/server/middleware.js +3 -3
  96. package/dist/services/server/middleware.js.map +1 -1
  97. package/dist/services/server/routing.js +2 -2
  98. package/dist/services/server/routing.js.map +1 -1
  99. package/dist/services/utils/dynamic-zones.js +5 -5
  100. package/dist/services/utils/dynamic-zones.js.map +1 -1
  101. package/dist/utils/cron.js +3 -3
  102. package/dist/utils/cron.js.map +1 -1
  103. package/dist/utils/is-initialized.js +3 -3
  104. package/dist/utils/is-initialized.js.map +1 -1
  105. package/dist/utils/startup-logger.js +4 -4
  106. package/dist/utils/startup-logger.js.map +1 -1
  107. package/dist/utils/startup-logger.mjs +3 -3
  108. package/dist/utils/startup-logger.mjs.map +1 -1
  109. package/package.json +21 -21
  110. package/dist/load/glob.d.ts +0 -7
  111. package/dist/load/glob.d.ts.map +0 -1
  112. package/dist/load/glob.js +0 -15
  113. package/dist/load/glob.js.map +0 -1
  114. package/dist/load/glob.mjs +0 -14
  115. package/dist/load/glob.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sources":["../../../src/services/entity-service/components.ts"],"sourcesContent":["import _ from 'lodash';\nimport { has, omit, pipe, assign } from 'lodash/fp';\nimport type { Attribute, Common, Schema, Utils, EntityService } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, mapAsync, errors } from '@strapi/utils';\n\ntype LoadedComponents<TUID extends Common.UID.Schema> = Attribute.GetValues<\n TUID,\n Attribute.GetKeysByType<TUID, 'component' | 'dynamiczone'>\n>;\n\ntype ComponentValue = Attribute.GetValue<\n Attribute.Component<Common.UID.Component, false> | Attribute.Component<Common.UID.Component, true>\n>;\n\ntype ComponentBody = {\n [key: string]: Attribute.GetValue<\n | Attribute.Component<Common.UID.Component, false>\n | Attribute.Component<Common.UID.Component, true>\n | Attribute.DynamicZone\n >;\n};\n\nconst isDialectMySQL = () => strapi.db?.dialect.client === 'mysql';\n\nfunction omitComponentData(\n contentType: Schema.ContentType,\n data: EntityService.Params.Data.Input<Schema.ContentType['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.ContentType['uid']>>;\nfunction omitComponentData(\n contentType: Schema.Component,\n data: EntityService.Params.Data.Input<Schema.Component['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.Component['uid']>>;\nfunction omitComponentData(\n contentType: Schema.ContentType | Schema.Component,\n data: EntityService.Params.Data.Input<Schema.ContentType['uid'] | Schema.Component['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.ContentType['uid'] | Schema.Component['uid']>> {\n const { attributes } = contentType;\n const componentAttributes = Object.keys(attributes).filter((attributeName) =>\n contentTypesUtils.isComponentAttribute(attributes[attributeName])\n );\n\n return omit(componentAttributes, data);\n}\n\n// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer\nconst createComponents = async <\n TUID extends Common.UID.Schema,\n TData extends EntityService.Params.Data.Input<TUID>\n>(\n uid: TUID,\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (!has(attributeName, data) || !contentTypesUtils.isComponentAttribute(attribute)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData];\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => createComponent(componentUID, value),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await createComponent(\n componentUID,\n componentValue as EntityService.Params.Data.Input<Common.UID.Component>\n );\n componentBody[attributeName] = {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as EntityService.Params.Attribute.GetValue<Attribute.DynamicZone>;\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const createDynamicZoneComponents = async (\n value: Utils.Array.Values<typeof dynamiczoneValues>\n ) => {\n const { id } = await createComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n };\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n createDynamicZoneComponents,\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst getComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entity: { id: EntityService.Params.Attribute.ID }\n): Promise<LoadedComponents<TUID>> => {\n const componentAttributes = contentTypesUtils.getComponentAttributes(strapi.getModel(uid));\n\n if (_.isEmpty(componentAttributes)) {\n return {} as LoadedComponents<TUID>;\n }\n\n return strapi.query(uid).load(entity, componentAttributes) as Promise<LoadedComponents<TUID>>;\n};\n\n/*\n delete old components\n create or update\n*/\nconst updateComponents = async <\n TUID extends Common.UID.Schema,\n TData extends Partial<EntityService.Params.Data.Input<TUID>>\n>(\n uid: TUID,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n if (!has(attributeName, data)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[\n attributeName as keyof TData\n ] as Attribute.GetValue<Attribute.Component>;\n\n await deleteOldComponents(uid, componentUID, entityToUpdate, attributeName, componentValue);\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => updateOrCreateComponent(componentUID, value),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await updateOrCreateComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as Attribute.GetValue<Attribute.DynamicZone>;\n\n await deleteOldDZComponents(uid, entityToUpdate, attributeName, dynamiczoneValues);\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n async (value: any) => {\n const { id } = await updateOrCreateComponent(value.__component, value);\n\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n },\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst pickStringifiedId = ({\n id,\n}: {\n id: EntityService.Params.Attribute.ID;\n}): EntityService.Params.Attribute.ID & string => {\n if (typeof id === 'string') {\n return id;\n }\n\n return `${id}`;\n};\n\nconst deleteOldComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n componentUID: Common.UID.Component,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n attributeName: string,\n componentValue: Attribute.GetValue<Attribute.Component>\n) => {\n const previousValue = (await strapi\n .query(uid)\n .load(entityToUpdate, attributeName)) as ComponentValue;\n\n const idsToKeep = _.castArray(componentValue).filter(has('id')).map(pickStringifiedId);\n const allIds = _.castArray(previousValue).filter(has('id')).map(pickStringifiedId);\n\n idsToKeep.forEach((id) => {\n if (!allIds.includes(id)) {\n throw new errors.ApplicationError(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n }\n });\n\n const idsToDelete = _.difference(allIds, idsToKeep);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n await deleteComponent(componentUID, { id: idToDelete });\n }\n }\n};\n\nconst deleteOldDZComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n attributeName: string,\n dynamiczoneValues: Attribute.GetValue<Attribute.DynamicZone>\n) => {\n const previousValue = (await strapi\n .query(uid)\n .load(entityToUpdate, attributeName)) as Attribute.GetValue<Attribute.DynamicZone>;\n\n const idsToKeep = _.castArray(dynamiczoneValues)\n .filter(has('id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n const allIds = _.castArray(previousValue)\n .filter(has('id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n idsToKeep.forEach(({ id, __component }) => {\n if (!allIds.find((el) => el.id === id && el.__component === __component)) {\n const err = new Error(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n\n Object.assign(err, { status: 400 });\n throw err;\n }\n });\n\n type IdsToDelete = Attribute.GetValue<Attribute.DynamicZone>;\n\n const idsToDelete = allIds.reduce((acc, { id, __component }) => {\n if (!idsToKeep.find((el) => el.id === id && el.__component === __component)) {\n acc.push({ id, __component });\n }\n\n return acc;\n }, [] as IdsToDelete);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n const { id, __component } = idToDelete;\n await deleteComponent(__component, { id });\n }\n }\n};\n\nconst deleteComponents = async <\n TUID extends Common.UID.Schema,\n TEntity extends Attribute.GetValues<TUID>\n>(\n uid: TUID,\n entityToDelete: TEntity,\n { loadComponents = true } = {}\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute.type === 'component' || attribute.type === 'dynamiczone') {\n let value;\n if (loadComponents) {\n value = await strapi.query(uid).load(entityToDelete, attributeName);\n } else {\n value = entityToDelete[attributeName as keyof TEntity];\n }\n\n if (!value) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID } = attribute;\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n await mapAsync(\n _.castArray(value),\n (subValue: any) => deleteComponent(componentUID, subValue),\n {\n concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity,\n }\n );\n } else {\n // delete dynamic zone components\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n await mapAsync(\n _.castArray(value),\n (subValue: any) => deleteComponent(subValue.__component, subValue),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n }\n\n continue;\n }\n }\n};\n\nconst cloneComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entityToClone: { id: EntityService.Params.Attribute.ID },\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n const componentData = await getComponents(uid, entityToClone);\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n // If the attribute is not set or on the component to clone, skip it\n if (!has(attributeName, data) && !has(attributeName, componentData)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = (\n attributeName in data\n ? data[attributeName as keyof typeof data]\n : componentData[attributeName as keyof typeof componentData]\n ) as ComponentValue;\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => cloneComponent(componentUID, value),\n { concurrency: isDialectMySQL() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await cloneComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = has(attributeName, data)\n ? data[attributeName as keyof typeof data]\n : componentData[attributeName as keyof typeof componentData];\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n async (value: any) => {\n const { id } = await cloneComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n },\n { concurrency: isDialectMySQL() ? 1 : Infinity }\n );\n continue;\n }\n }\n\n return componentBody;\n};\n/** *************************\n Component queries\n************************** */\n\n// components can have nested compos so this must be recursive\nconst createComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n const componentData = await createComponents(uid, data);\n const transform = pipe(\n // Make sure we don't save the component with a pre-defined ID\n omit('id'),\n // Remove the component data from the original data object ...\n (payload) => omitComponentData(model, payload),\n // ... and assign the newly created component instead\n assign(componentData)\n );\n\n return strapi.query(uid).create({ data: transform(data) });\n};\n\n// components can have nested compos so this must be recursive\nconst updateComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n componentToUpdate: { id: EntityService.Params.Attribute.ID },\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n const componentData = await updateComponents(uid, componentToUpdate, data);\n\n return strapi.query(uid).update({\n where: {\n id: componentToUpdate.id,\n },\n data: Object.assign(omitComponentData(model, data), componentData),\n });\n};\n\nconst updateOrCreateComponent = <TUID extends Common.UID.Component>(\n componentUID: TUID,\n value: EntityService.Params.Data.Input<TUID>\n) => {\n if (value === null) {\n return null;\n }\n\n // update\n if ('id' in value && typeof value.id !== 'undefined') {\n // TODO: verify the compo is associated with the entity\n return updateComponent(componentUID, { id: value.id }, value);\n }\n\n // create\n return createComponent(componentUID, value);\n};\n\nconst deleteComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n componentToDelete: Attribute.GetValues<TUID>\n) => {\n await deleteComponents(uid, componentToDelete);\n await strapi.query(uid).delete({ where: { id: componentToDelete.id } });\n};\n\nconst cloneComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n if (!('id' in data) || typeof data.id === 'undefined') {\n return createComponent(uid, data);\n }\n\n const componentData = await cloneComponents(uid, { id: data.id }, data);\n const transform = pipe(\n // Make sure we don't save the component with a pre-defined ID\n omit('id'),\n // Remove the component data from the original data object ...\n (payload) => omitComponentData(model, payload),\n // ... and assign the newly created component instead\n assign(componentData)\n );\n\n return strapi.query(uid).clone(data.id, { data: transform(data) });\n};\n\nexport {\n omitComponentData,\n getComponents,\n createComponents,\n updateComponents,\n deleteComponents,\n deleteComponent,\n cloneComponents,\n};\n"],"names":["contentTypesUtils","omit","has","mapAsync","_","errors","pipe","assign"],"mappings":"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"}
1
+ {"version":3,"file":"components.js","sources":["../../../src/services/entity-service/components.ts"],"sourcesContent":["import _ from 'lodash';\nimport { has, omit, pipe, assign } from 'lodash/fp';\nimport type { Attribute, Common, Schema, Utils, EntityService } from '@strapi/types';\nimport { contentTypes as contentTypesUtils, mapAsync, errors } from '@strapi/utils';\n\ntype LoadedComponents<TUID extends Common.UID.Schema> = Attribute.GetValues<\n TUID,\n Attribute.GetKeysByType<TUID, 'component' | 'dynamiczone'>\n>;\n\ntype ComponentValue = Attribute.GetValue<\n Attribute.Component<Common.UID.Component, false> | Attribute.Component<Common.UID.Component, true>\n>;\n\ntype ComponentBody = {\n [key: string]: Attribute.GetValue<\n | Attribute.Component<Common.UID.Component, false>\n | Attribute.Component<Common.UID.Component, true>\n | Attribute.DynamicZone\n >;\n};\n\nconst isDialectMySQL = () => strapi.db?.dialect.client === 'mysql';\n\nfunction omitComponentData(\n contentType: Schema.ContentType,\n data: EntityService.Params.Data.Input<Schema.ContentType['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.ContentType['uid']>>;\nfunction omitComponentData(\n contentType: Schema.Component,\n data: EntityService.Params.Data.Input<Schema.Component['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.Component['uid']>>;\nfunction omitComponentData(\n contentType: Schema.ContentType | Schema.Component,\n data: EntityService.Params.Data.Input<Schema.ContentType['uid'] | Schema.Component['uid']>\n): Partial<EntityService.Params.Data.Input<Schema.ContentType['uid'] | Schema.Component['uid']>> {\n const { attributes } = contentType;\n const componentAttributes = Object.keys(attributes).filter((attributeName) =>\n contentTypesUtils.isComponentAttribute(attributes[attributeName])\n );\n\n return omit(componentAttributes, data);\n}\n\n// NOTE: we could generalize the logic to allow CRUD of relation directly in the DB layer\nconst createComponents = async <\n TUID extends Common.UID.Schema,\n TData extends EntityService.Params.Data.Input<TUID>\n>(\n uid: TUID,\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (!has(attributeName, data) || !contentTypesUtils.isComponentAttribute(attribute)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[attributeName as keyof TData];\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => createComponent(componentUID, value),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await createComponent(\n componentUID,\n componentValue as EntityService.Params.Data.Input<Common.UID.Component>\n );\n componentBody[attributeName] = {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as EntityService.Params.Attribute.GetValue<Attribute.DynamicZone>;\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n const createDynamicZoneComponents = async (\n value: Utils.Array.Values<typeof dynamiczoneValues>\n ) => {\n const { id } = await createComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n };\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n createDynamicZoneComponents,\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst getComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entity: { id: EntityService.Params.Attribute.ID }\n): Promise<LoadedComponents<TUID>> => {\n const componentAttributes = contentTypesUtils.getComponentAttributes(strapi.getModel(uid));\n\n if (_.isEmpty(componentAttributes)) {\n return {} as LoadedComponents<TUID>;\n }\n\n return strapi.query(uid).load(entity, componentAttributes) as Promise<LoadedComponents<TUID>>;\n};\n\n/*\n delete old components\n create or update\n*/\nconst updateComponents = async <\n TUID extends Common.UID.Schema,\n TData extends Partial<EntityService.Params.Data.Input<TUID>>\n>(\n uid: TUID,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n data: TData\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n if (!has(attributeName, data)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = data[\n attributeName as keyof TData\n ] as Attribute.GetValue<Attribute.Component>;\n\n await deleteOldComponents(uid, componentUID, entityToUpdate, attributeName, componentValue);\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => updateOrCreateComponent(componentUID, value),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await updateOrCreateComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = data[\n attributeName as keyof TData\n ] as Attribute.GetValue<Attribute.DynamicZone>;\n\n await deleteOldDZComponents(uid, entityToUpdate, attributeName, dynamiczoneValues);\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n async (value: any) => {\n const { id } = await updateOrCreateComponent(value.__component, value);\n\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n },\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n\n continue;\n }\n }\n\n return componentBody;\n};\n\nconst pickStringifiedId = ({\n id,\n}: {\n id: EntityService.Params.Attribute.ID;\n}): EntityService.Params.Attribute.ID & string => {\n if (typeof id === 'string') {\n return id;\n }\n\n return `${id}`;\n};\n\nconst deleteOldComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n componentUID: Common.UID.Component,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n attributeName: string,\n componentValue: Attribute.GetValue<Attribute.Component>\n) => {\n const previousValue = (await strapi\n .query(uid)\n .load(entityToUpdate, attributeName)) as ComponentValue;\n\n const idsToKeep = _.castArray(componentValue).filter(has('id')).map(pickStringifiedId);\n const allIds = _.castArray(previousValue).filter(has('id')).map(pickStringifiedId);\n\n idsToKeep.forEach((id) => {\n if (!allIds.includes(id)) {\n throw new errors.ApplicationError(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n }\n });\n\n const idsToDelete = _.difference(allIds, idsToKeep);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n await deleteComponent(componentUID, { id: idToDelete });\n }\n }\n};\n\nconst deleteOldDZComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entityToUpdate: { id: EntityService.Params.Attribute.ID },\n attributeName: string,\n dynamiczoneValues: Attribute.GetValue<Attribute.DynamicZone>\n) => {\n const previousValue = (await strapi\n .query(uid)\n .load(entityToUpdate, attributeName)) as Attribute.GetValue<Attribute.DynamicZone>;\n\n const idsToKeep = _.castArray(dynamiczoneValues)\n .filter(has('id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n const allIds = _.castArray(previousValue)\n .filter(has('id'))\n .map((v) => ({\n id: pickStringifiedId(v),\n __component: v.__component,\n }));\n\n idsToKeep.forEach(({ id, __component }) => {\n if (!allIds.find((el) => el.id === id && el.__component === __component)) {\n const err = new Error(\n `Some of the provided components in ${attributeName} are not related to the entity`\n );\n\n Object.assign(err, { status: 400 });\n throw err;\n }\n });\n\n type IdsToDelete = Attribute.GetValue<Attribute.DynamicZone>;\n\n const idsToDelete = allIds.reduce((acc, { id, __component }) => {\n if (!idsToKeep.find((el) => el.id === id && el.__component === __component)) {\n acc.push({ id, __component });\n }\n\n return acc;\n }, [] as IdsToDelete);\n\n if (idsToDelete.length > 0) {\n for (const idToDelete of idsToDelete) {\n const { id, __component } = idToDelete;\n await deleteComponent(__component, { id });\n }\n }\n};\n\nconst deleteComponents = async <\n TUID extends Common.UID.Schema,\n TEntity extends Attribute.GetValues<TUID>\n>(\n uid: TUID,\n entityToDelete: TEntity,\n { loadComponents = true } = {}\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const attributeNames = Object.keys(attributes);\n\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute.type === 'component' || attribute.type === 'dynamiczone') {\n let value;\n if (loadComponents) {\n value = await strapi.query(uid).load(entityToDelete, attributeName);\n } else {\n value = entityToDelete[attributeName as keyof TEntity];\n }\n\n if (!value) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID } = attribute;\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n await mapAsync(\n _.castArray(value),\n (subValue: any) => deleteComponent(componentUID, subValue),\n {\n concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity,\n }\n );\n } else {\n // delete dynamic zone components\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n await mapAsync(\n _.castArray(value),\n (subValue: any) => deleteComponent(subValue.__component, subValue),\n { concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }\n );\n }\n\n continue;\n }\n }\n};\n\nconst cloneComponents = async <TUID extends Common.UID.Schema>(\n uid: TUID,\n entityToClone: { id: EntityService.Params.Attribute.ID },\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const { attributes = {} } = strapi.getModel(uid);\n\n const componentBody: ComponentBody = {};\n const componentData = await getComponents(uid, entityToClone);\n\n for (const attributeName of Object.keys(attributes)) {\n const attribute = attributes[attributeName];\n\n // If the attribute is not set or on the component to clone, skip it\n if (!has(attributeName, data) && !has(attributeName, componentData)) {\n continue;\n }\n\n if (attribute.type === 'component') {\n const { component: componentUID, repeatable = false } = attribute;\n\n const componentValue = (\n attributeName in data\n ? data[attributeName as keyof typeof data]\n : componentData[attributeName as keyof typeof componentData]\n ) as ComponentValue;\n\n if (componentValue === null) {\n continue;\n }\n\n if (repeatable === true) {\n if (!Array.isArray(componentValue)) {\n throw new Error('Expected an array to create repeatable component');\n }\n\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n const components = (await mapAsync(\n componentValue,\n (value: any) => cloneComponent(componentUID, value),\n { concurrency: isDialectMySQL() ? 1 : Infinity }\n )) as Attribute.GetValue<Attribute.Component<Common.UID.Component, true>>;\n\n componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {\n return {\n id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n });\n } else {\n const component = await cloneComponent(componentUID, componentValue);\n componentBody[attributeName] = component && {\n id: component.id,\n __pivot: {\n field: attributeName,\n component_type: componentUID,\n },\n };\n }\n\n continue;\n }\n\n if (attribute.type === 'dynamiczone') {\n const dynamiczoneValues = has(attributeName, data)\n ? data[attributeName as keyof typeof data]\n : componentData[attributeName as keyof typeof componentData];\n\n if (!Array.isArray(dynamiczoneValues)) {\n throw new Error('Expected an array to create repeatable component');\n }\n // MySQL/MariaDB can cause deadlocks here if concurrency higher than 1\n componentBody[attributeName] = await mapAsync(\n dynamiczoneValues,\n async (value: any) => {\n const { id } = await cloneComponent(value.__component, value);\n return {\n id,\n __component: value.__component,\n __pivot: {\n field: attributeName,\n },\n };\n },\n { concurrency: isDialectMySQL() ? 1 : Infinity }\n );\n continue;\n }\n }\n\n return componentBody;\n};\n/** *************************\n Component queries\n************************** */\n\n// components can have nested compos so this must be recursive\nconst createComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n const componentData = await createComponents(uid, data);\n const transform = pipe(\n // Make sure we don't save the component with a pre-defined ID\n omit('id'),\n // Remove the component data from the original data object ...\n (payload) => omitComponentData(model, payload),\n // ... and assign the newly created component instead\n assign(componentData)\n );\n\n return strapi.query(uid).create({ data: transform(data) });\n};\n\n// components can have nested compos so this must be recursive\nconst updateComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n componentToUpdate: { id: EntityService.Params.Attribute.ID },\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n const componentData = await updateComponents(uid, componentToUpdate, data);\n\n return strapi.query(uid).update({\n where: {\n id: componentToUpdate.id,\n },\n data: Object.assign(omitComponentData(model, data), componentData),\n });\n};\n\nconst updateOrCreateComponent = <TUID extends Common.UID.Component>(\n componentUID: TUID,\n value: EntityService.Params.Data.Input<TUID>\n) => {\n if (value === null) {\n return null;\n }\n\n // update\n if ('id' in value && typeof value.id !== 'undefined') {\n // TODO: verify the compo is associated with the entity\n return updateComponent(componentUID, { id: value.id }, value);\n }\n\n // create\n return createComponent(componentUID, value);\n};\n\nconst deleteComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n componentToDelete: Attribute.GetValues<TUID>\n) => {\n await deleteComponents(uid, componentToDelete);\n await strapi.query(uid).delete({ where: { id: componentToDelete.id } });\n};\n\nconst cloneComponent = async <TUID extends Common.UID.Component>(\n uid: TUID,\n data: EntityService.Params.Data.Input<TUID>\n) => {\n const model = strapi.getModel(uid);\n\n if (!('id' in data) || typeof data.id === 'undefined') {\n return createComponent(uid, data);\n }\n\n const componentData = await cloneComponents(uid, { id: data.id }, data);\n const transform = pipe(\n // Make sure we don't save the component with a pre-defined ID\n omit('id'),\n // Remove the component data from the original data object ...\n (payload) => omitComponentData(model, payload),\n // ... and assign the newly created component instead\n assign(componentData)\n );\n\n return strapi.query(uid).clone(data.id, { data: transform(data) });\n};\n\nexport {\n omitComponentData,\n getComponents,\n createComponents,\n updateComponents,\n deleteComponents,\n deleteComponent,\n cloneComponents,\n};\n"],"names":["contentTypesUtils","omit","has","mapAsync","_","errors","pipe","assign"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _ = require("lodash/fp");
3
+ const fp = require("lodash/fp");
4
4
  const pickSelectionParams = (data) => {
5
- return _.pick(["fields", "populate"], data);
5
+ return fp.pick(["fields", "populate"], data);
6
6
  };
7
7
  exports.pickSelectionParams = pickSelectionParams;
8
8
  //# sourceMappingURL=params.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"params.js","sources":["../../../src/services/entity-service/params.ts"],"sourcesContent":["import { pick } from 'lodash/fp';\nimport type { Common, EntityService } from '@strapi/types';\n\nconst pickSelectionParams = <TUID extends Common.UID.ContentType>(\n data: unknown\n): EntityService.Params.Pick<TUID, 'fields' | 'populate'> => {\n return pick(['fields', 'populate'], data);\n};\n\nexport { pickSelectionParams };\n"],"names":["pick"],"mappings":";;;AAGM,MAAA,sBAAsB,CAC1B,SAC2D;AAC3D,SAAOA,EAAK,KAAA,CAAC,UAAU,UAAU,GAAG,IAAI;AAC1C;;"}
1
+ {"version":3,"file":"params.js","sources":["../../../src/services/entity-service/params.ts"],"sourcesContent":["import { pick } from 'lodash/fp';\nimport type { Common, EntityService } from '@strapi/types';\n\nconst pickSelectionParams = <TUID extends Common.UID.ContentType>(\n data: unknown\n): EntityService.Params.Pick<TUID, 'fields' | 'populate'> => {\n return pick(['fields', 'populate'], data);\n};\n\nexport { pickSelectionParams };\n"],"names":["pick"],"mappings":";;;AAGM,MAAA,sBAAsB,CAC1B,SAC2D;AAC3D,SAAOA,GAAK,KAAA,CAAC,UAAU,UAAU,GAAG,IAAI;AAC1C;;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- const _$1 = require("lodash");
3
- const _ = require("lodash/fp");
2
+ const _ = require("lodash");
3
+ const fp = require("lodash/fp");
4
4
  const strapiUtils = require("@strapi/utils");
5
5
  const validators = require("./validators.js");
6
6
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -82,7 +82,7 @@ const createDzValidator = (createOrUpdate) => ({ attr, updatedAttribute }, { isD
82
82
  let validator;
83
83
  validator = yup.array().of(
84
84
  yup.lazy((item) => {
85
- const model = strapi.getModel(_.prop("__component", item));
85
+ const model = strapi.getModel(fp.prop("__component", item));
86
86
  const schema = yup.object().shape({
87
87
  __component: yup.string().required().oneOf(Object.keys(strapi.components))
88
88
  }).notNull();
@@ -112,7 +112,7 @@ const createRelationValidator = (createOrUpdate) => ({ attr, updatedAttribute },
112
112
  };
113
113
  const createScalarAttributeValidator = (createOrUpdate) => (metas, options) => {
114
114
  let validator;
115
- if (_.has(metas.attr.type, validators)) {
115
+ if (fp.has(metas.attr.type, validators)) {
116
116
  validator = validators[metas.attr.type](metas, options);
117
117
  } else {
118
118
  validator = yup.mixed();
@@ -156,7 +156,7 @@ const createModelValidator = (createOrUpdate) => ({ model, data, entity }, optio
156
156
  const schema = writableAttributes.reduce((validators2, attributeName) => {
157
157
  const metas = {
158
158
  attr: model.attributes[attributeName],
159
- updatedAttribute: { name: attributeName, value: _.prop(attributeName, data) },
159
+ updatedAttribute: { name: attributeName, value: fp.prop(attributeName, data) },
160
160
  model,
161
161
  entity
162
162
  };
@@ -168,7 +168,7 @@ const createModelValidator = (createOrUpdate) => ({ model, data, entity }, optio
168
168
  };
169
169
  const createValidateEntity = (createOrUpdate) => {
170
170
  return async (model, data, options, entity) => {
171
- if (!_.isObject(data)) {
171
+ if (!fp.isObject(data)) {
172
172
  const { displayName } = model.info;
173
173
  throw new ValidationError(
174
174
  `Invalid payload submitted for the ${createOrUpdate} of an entity of type ${displayName}. Expected an object, but got ${typeof data}`
@@ -201,14 +201,14 @@ const buildRelationsStore = ({
201
201
  if (!uid) {
202
202
  throw new ValidationError(`Cannot build relations store: "uid" is undefined`);
203
203
  }
204
- if (_.isEmpty(data)) {
204
+ if (fp.isEmpty(data)) {
205
205
  return {};
206
206
  }
207
207
  const currentModel = strapi.getModel(uid);
208
208
  return Object.keys(currentModel.attributes).reduce((result, attributeName) => {
209
209
  const attribute = currentModel.attributes[attributeName];
210
210
  const value = data[attributeName];
211
- if (_$1.isNil(value)) {
211
+ if (_.isNil(value)) {
212
212
  return result;
213
213
  }
214
214
  switch (attribute.type) {
@@ -224,16 +224,16 @@ const buildRelationsStore = ({
224
224
  let source;
225
225
  if (Array.isArray(value)) {
226
226
  source = value;
227
- } else if (_.isObject(value)) {
228
- if ("connect" in value && !_$1.isNil(value.connect)) {
227
+ } else if (fp.isObject(value)) {
228
+ if ("connect" in value && !_.isNil(value.connect)) {
229
229
  source = value.connect;
230
- } else if ("set" in value && !_$1.isNil(value.set)) {
230
+ } else if ("set" in value && !_.isNil(value.set)) {
231
231
  source = value.set;
232
232
  } else {
233
233
  source = [];
234
234
  }
235
235
  } else {
236
- source = _$1.castArray(value);
236
+ source = _.castArray(value);
237
237
  }
238
238
  const idArray = source.map((v) => ({
239
239
  id: typeof v === "object" ? v.id : v
@@ -243,20 +243,20 @@ const buildRelationsStore = ({
243
243
  break;
244
244
  }
245
245
  case "component": {
246
- return _$1.castArray(value).reduce((relationsStore, componentValue) => {
246
+ return _.castArray(value).reduce((relationsStore, componentValue) => {
247
247
  if (!attribute.component) {
248
248
  throw new ValidationError(
249
249
  `Cannot build relations store from component, component identifier is undefined`
250
250
  );
251
251
  }
252
- return _$1.mergeWith(
252
+ return _.mergeWith(
253
253
  relationsStore,
254
254
  buildRelationsStore({
255
255
  uid: attribute.component,
256
256
  data: componentValue
257
257
  }),
258
258
  (objValue, srcValue) => {
259
- if (_$1.isArray(objValue)) {
259
+ if (_.isArray(objValue)) {
260
260
  return objValue.concat(srcValue);
261
261
  }
262
262
  }
@@ -264,21 +264,21 @@ const buildRelationsStore = ({
264
264
  }, result);
265
265
  }
266
266
  case "dynamiczone": {
267
- return _$1.castArray(value).reduce((relationsStore, dzValue) => {
267
+ return _.castArray(value).reduce((relationsStore, dzValue) => {
268
268
  const value2 = dzValue;
269
269
  if (!value2.__component) {
270
270
  throw new ValidationError(
271
271
  `Cannot build relations store from dynamiczone, component identifier is undefined`
272
272
  );
273
273
  }
274
- return _$1.mergeWith(
274
+ return _.mergeWith(
275
275
  relationsStore,
276
276
  buildRelationsStore({
277
277
  uid: value2.__component,
278
278
  data: value2
279
279
  }),
280
280
  (objValue, srcValue) => {
281
- if (_$1.isArray(objValue)) {
281
+ if (_.isArray(objValue)) {
282
282
  return objValue.concat(srcValue);
283
283
  }
284
284
  }
@@ -293,7 +293,7 @@ const checkRelationsExist = async (relationsStore = {}) => {
293
293
  const promises = [];
294
294
  for (const [key, value] of Object.entries(relationsStore)) {
295
295
  const evaluate = async () => {
296
- const uniqueValues = _$1.uniqBy(value, `id`);
296
+ const uniqueValues = _.uniqBy(value, `id`);
297
297
  const count = await strapi.query(key).count({
298
298
  where: {
299
299
  id: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/services/entity-validator/index.ts"],"sourcesContent":["/**\n * Entity validator\n * Module that will validate input data for entity creation or edition\n */\n\nimport { uniqBy, castArray, isNil, isArray, mergeWith } from 'lodash';\nimport { has, prop, isObject, isEmpty } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { EntityValidator, Common, Schema, Attribute, Shared, EntityService } from '@strapi/types';\nimport validators from './validators';\n\ntype CreateOrUpdate = 'creation' | 'update';\n\nconst { yup, validateYupSchema } = strapiUtils;\nconst { isMediaAttribute, isScalarAttribute, getWritableAttributes } = strapiUtils.contentTypes;\nconst { ValidationError } = strapiUtils.errors;\n\ntype Entity = {\n id: ID;\n [key: string]: unknown;\n} | null;\n\ntype ID = { id: string | number };\n\ntype RelationSource = string | number | ID;\n\ninterface ValidatorMeta<TAttribute = Attribute.Any> {\n attr: TAttribute;\n updatedAttribute: { name: string; value: any };\n}\n\ninterface ValidatorContext {\n isDraft: boolean;\n}\n\ninterface AttributeValidatorMetas {\n attr: Attribute.Any;\n updatedAttribute: { name: string; value: unknown };\n model: Schema.ContentType | Schema.Component;\n entity?: Entity;\n}\n\ninterface ModelValidatorMetas {\n model: Schema.ContentType | Schema.Component;\n data: Record<string, unknown>;\n entity?: Entity;\n}\n\nconst isInteger = (value: unknown): value is number => Number.isInteger(value);\n\nconst addMinMax = <\n T extends {\n min(value: number): T;\n max(value: number): T;\n }\n>(\n validator: T,\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Any & Attribute.MinMaxOption<string | number>>\n): T => {\n let nextValidator: T = validator;\n\n if (\n isInteger(attr.min) &&\n (('required' in attr && attr.required) ||\n (Array.isArray(updatedAttribute.value) && updatedAttribute.value.length > 0))\n ) {\n nextValidator = nextValidator.min(attr.min);\n }\n if (isInteger(attr.max)) {\n nextValidator = nextValidator.max(attr.max);\n }\n return nextValidator;\n};\n\nconst addRequiredValidation = (createOrUpdate: CreateOrUpdate) => {\n return <T extends strapiUtils.yup.AnySchema>(\n validator: T,\n { attr: { required } }: ValidatorMeta<Partial<Attribute.Any & Attribute.RequiredOption>>\n ): T => {\n let nextValidator = validator;\n\n if (required) {\n if (createOrUpdate === 'creation') {\n nextValidator = nextValidator.notNil();\n } else if (createOrUpdate === 'update') {\n nextValidator = nextValidator.notNull();\n }\n } else {\n nextValidator = nextValidator.nullable();\n }\n return nextValidator;\n };\n};\n\nconst addDefault = (createOrUpdate: CreateOrUpdate) => {\n return (\n validator: strapiUtils.yup.BaseSchema,\n { attr }: ValidatorMeta<Attribute.Any & Attribute.DefaultOption<unknown>>\n ) => {\n let nextValidator = validator;\n\n if (createOrUpdate === 'creation') {\n if (\n ((attr.type === 'component' && attr.repeatable) || attr.type === 'dynamiczone') &&\n !attr.required\n ) {\n nextValidator = nextValidator.default([]);\n } else {\n nextValidator = nextValidator.default(attr.default);\n }\n } else {\n nextValidator = nextValidator.default(undefined);\n }\n\n return nextValidator;\n };\n};\n\nconst preventCast = (validator: strapiUtils.yup.AnySchema) =>\n validator.transform((val, originalVal) => originalVal);\n\nconst createComponentValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Component<Common.UID.Component, boolean>>,\n { isDraft }: ValidatorContext\n ) => {\n const model = strapi.getModel(attr.component);\n if (!model) {\n throw new Error('Validation failed: Model not found');\n }\n\n if (attr?.repeatable) {\n // FIXME: yup v1\n\n let validator = yup\n .array()\n .of(\n yup.lazy((item) =>\n createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }).notNull()\n ) as any\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: true },\n updatedAttribute,\n });\n\n validator = addMinMax(validator, { attr, updatedAttribute });\n\n return validator;\n }\n\n // FIXME: v4 was broken\n let validator = createModelValidator(createOrUpdate)(\n { model, data: updatedAttribute.value },\n { isDraft }\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !isDraft && attr.required },\n updatedAttribute,\n });\n\n return validator;\n };\n\nconst createDzValidator =\n (createOrUpdate: CreateOrUpdate) =>\n ({ attr, updatedAttribute }: ValidatorMeta, { isDraft }: ValidatorContext) => {\n let validator;\n\n validator = yup.array().of(\n yup.lazy((item) => {\n const model = strapi.getModel(prop('__component', item));\n const schema = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(strapi.components)),\n })\n .notNull();\n\n return model\n ? schema.concat(createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }))\n : schema;\n }) as any // FIXME: yup v1\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: true },\n updatedAttribute,\n });\n\n validator = addMinMax(validator, { attr, updatedAttribute });\n\n return validator;\n };\n\nconst createRelationValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Relation>,\n { isDraft }: ValidatorContext\n ) => {\n let validator;\n\n if (Array.isArray(updatedAttribute.value)) {\n validator = yup.array().of(yup.mixed());\n } else {\n validator = yup.mixed();\n }\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !isDraft && attr.required },\n updatedAttribute,\n });\n\n return validator;\n };\n\nconst createScalarAttributeValidator =\n (createOrUpdate: CreateOrUpdate) => (metas: ValidatorMeta, options: ValidatorContext) => {\n let validator;\n\n if (has(metas.attr.type, validators)) {\n validator = (validators as any)[metas.attr.type](metas, options);\n } else {\n // No validators specified - fall back to mixed\n validator = yup.mixed();\n }\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !options.isDraft && metas.attr.required },\n updatedAttribute: metas.updatedAttribute,\n });\n\n return validator;\n };\n\nconst createAttributeValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (metas: AttributeValidatorMetas, options: ValidatorContext) => {\n let validator = yup.mixed();\n\n if (isMediaAttribute(metas.attr)) {\n validator = yup.mixed();\n } else if (isScalarAttribute(metas.attr)) {\n validator = createScalarAttributeValidator(createOrUpdate)(metas, options);\n } else {\n if (metas.attr.type === 'component') {\n validator = createComponentValidator(createOrUpdate)(\n { attr: metas.attr, updatedAttribute: metas.updatedAttribute },\n options\n );\n } else if (metas.attr.type === 'dynamiczone') {\n validator = createDzValidator(createOrUpdate)(metas, options);\n } else if (metas.attr.type === 'relation') {\n validator = createRelationValidator(createOrUpdate)(\n {\n attr: metas.attr,\n updatedAttribute: metas.updatedAttribute,\n },\n options\n );\n }\n\n validator = preventCast(validator);\n }\n\n validator = addDefault(createOrUpdate)(validator, metas);\n\n return validator;\n };\n\nconst createModelValidator =\n (createOrUpdate: CreateOrUpdate) =>\n ({ model, data, entity }: ModelValidatorMetas, options: ValidatorContext) => {\n const writableAttributes = model ? getWritableAttributes(model as any) : [];\n\n const schema = writableAttributes.reduce((validators, attributeName) => {\n const metas = {\n attr: model.attributes[attributeName],\n updatedAttribute: { name: attributeName, value: prop(attributeName, data) },\n model,\n entity,\n };\n\n const validator = createAttributeValidator(createOrUpdate)(metas, options);\n\n validators[attributeName] = validator;\n\n return validators;\n }, {} as Record<string, strapiUtils.yup.BaseSchema>);\n\n return yup.object().shape(schema);\n };\n\nconst createValidateEntity = (createOrUpdate: CreateOrUpdate) => {\n return async <\n TUID extends Common.UID.ContentType,\n TData extends EntityService.Params.Data.Input<TUID>\n >(\n model: Shared.ContentTypes[TUID],\n data: TData | Partial<TData> | undefined,\n options?: { isDraft?: boolean },\n entity?: Entity\n ): Promise<TData> => {\n if (!isObject(data)) {\n const { displayName } = model.info;\n\n throw new ValidationError(\n `Invalid payload submitted for the ${createOrUpdate} of an entity of type ${displayName}. Expected an object, but got ${typeof data}`\n );\n }\n\n const validator = createModelValidator(createOrUpdate)(\n { model, data, entity },\n { isDraft: options?.isDraft ?? false }\n )\n .test('relations-test', 'check that all relations exist', async function (data) {\n try {\n await checkRelationsExist(buildRelationsStore({ uid: model.uid, data }));\n } catch (e) {\n return this.createError({\n path: this.path,\n message: (e instanceof ValidationError && e.message) || 'Invalid relations',\n });\n }\n return true;\n })\n .required();\n\n return validateYupSchema(validator, {\n strict: false,\n abortEarly: false,\n })(data);\n };\n};\n\n/**\n * Builds an object containing all the media and relations being associated with an entity\n */\nconst buildRelationsStore = <TUID extends Common.UID.ContentType | Common.UID.Component>({\n uid,\n data,\n}: {\n uid: TUID;\n data: Record<string, unknown> | null;\n}): Record<string, ID[]> => {\n if (!uid) {\n throw new ValidationError(`Cannot build relations store: \"uid\" is undefined`);\n }\n\n if (isEmpty(data)) {\n return {};\n }\n\n const currentModel = strapi.getModel(uid);\n\n return Object.keys(currentModel.attributes).reduce((result, attributeName: string) => {\n const attribute = currentModel.attributes[attributeName];\n const value = data[attributeName];\n\n if (isNil(value)) {\n return result;\n }\n\n switch (attribute.type) {\n case 'relation':\n case 'media': {\n if (\n attribute.type === 'relation' &&\n (attribute.relation === 'morphToMany' || attribute.relation === 'morphToOne')\n ) {\n // TODO: handle polymorphic relations\n break;\n }\n\n const target =\n // eslint-disable-next-line no-nested-ternary\n attribute.type === 'media' ? 'plugin::upload.file' : attribute.target;\n // As there are multiple formats supported for associating relations\n // with an entity, the value here can be an: array, object or number.\n let source: RelationSource[];\n if (Array.isArray(value)) {\n source = value;\n } else if (isObject(value)) {\n if ('connect' in value && !isNil(value.connect)) {\n source = value.connect as RelationSource[];\n } else if ('set' in value && !isNil(value.set)) {\n source = value.set as RelationSource[];\n } else {\n source = [];\n }\n } else {\n source = castArray(value as RelationSource);\n }\n const idArray = source.map((v) => ({\n id: typeof v === 'object' ? v.id : v,\n }));\n\n // Update the relationStore to keep track of all associations being made\n // with relations and media.\n result[target] = result[target] || [];\n result[target].push(...idArray);\n break;\n }\n case 'component': {\n return castArray(value).reduce((relationsStore, componentValue) => {\n if (!attribute.component) {\n throw new ValidationError(\n `Cannot build relations store from component, component identifier is undefined`\n );\n }\n\n return mergeWith(\n relationsStore,\n buildRelationsStore({\n uid: attribute.component,\n data: componentValue as Record<string, unknown>,\n }),\n (objValue, srcValue) => {\n if (isArray(objValue)) {\n return objValue.concat(srcValue);\n }\n }\n );\n }, result) as Record<string, ID[]>;\n }\n case 'dynamiczone': {\n return castArray(value).reduce((relationsStore, dzValue) => {\n const value = dzValue as Record<string, unknown>;\n if (!value.__component) {\n throw new ValidationError(\n `Cannot build relations store from dynamiczone, component identifier is undefined`\n );\n }\n\n return mergeWith(\n relationsStore,\n buildRelationsStore({\n uid: value.__component as Common.UID.Component,\n data: value,\n }),\n (objValue, srcValue) => {\n if (isArray(objValue)) {\n return objValue.concat(srcValue);\n }\n }\n );\n }, result) as Record<string, ID[]>;\n }\n default:\n break;\n }\n\n return result;\n }, {} as Record<string, ID[]>);\n};\n\n/**\n * Iterate through the relations store and validates that every relation or media\n * mentioned exists\n */\nconst checkRelationsExist = async (relationsStore: Record<string, ID[]> = {}) => {\n const promises = [];\n\n for (const [key, value] of Object.entries(relationsStore)) {\n const evaluate = async () => {\n const uniqueValues = uniqBy(value, `id`);\n const count = await strapi.query(key as Common.UID.Schema).count({\n where: {\n id: {\n $in: uniqueValues.map((v) => v.id),\n },\n },\n });\n\n if (count !== uniqueValues.length) {\n throw new ValidationError(\n `${\n uniqueValues.length - count\n } relation(s) of type ${key} associated with this entity do not exist`\n );\n }\n };\n promises.push(evaluate());\n }\n\n return Promise.all(promises);\n};\n\nconst entityValidator: EntityValidator = {\n validateEntityCreation: createValidateEntity('creation'),\n validateEntityUpdate: createValidateEntity('update'),\n};\n\nexport default entityValidator;\n"],"names":["strapiUtils","validator","prop","has","validators","isObject","data","isEmpty","isNil","castArray","mergeWith","isArray","value","uniqBy"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/services/entity-validator/index.ts"],"sourcesContent":["/**\n * Entity validator\n * Module that will validate input data for entity creation or edition\n */\n\nimport { uniqBy, castArray, isNil, isArray, mergeWith } from 'lodash';\nimport { has, prop, isObject, isEmpty } from 'lodash/fp';\nimport strapiUtils from '@strapi/utils';\nimport { EntityValidator, Common, Schema, Attribute, Shared, EntityService } from '@strapi/types';\nimport validators from './validators';\n\ntype CreateOrUpdate = 'creation' | 'update';\n\nconst { yup, validateYupSchema } = strapiUtils;\nconst { isMediaAttribute, isScalarAttribute, getWritableAttributes } = strapiUtils.contentTypes;\nconst { ValidationError } = strapiUtils.errors;\n\ntype Entity = {\n id: ID;\n [key: string]: unknown;\n} | null;\n\ntype ID = { id: string | number };\n\ntype RelationSource = string | number | ID;\n\ninterface ValidatorMeta<TAttribute = Attribute.Any> {\n attr: TAttribute;\n updatedAttribute: { name: string; value: any };\n}\n\ninterface ValidatorContext {\n isDraft: boolean;\n}\n\ninterface AttributeValidatorMetas {\n attr: Attribute.Any;\n updatedAttribute: { name: string; value: unknown };\n model: Schema.ContentType | Schema.Component;\n entity?: Entity;\n}\n\ninterface ModelValidatorMetas {\n model: Schema.ContentType | Schema.Component;\n data: Record<string, unknown>;\n entity?: Entity;\n}\n\nconst isInteger = (value: unknown): value is number => Number.isInteger(value);\n\nconst addMinMax = <\n T extends {\n min(value: number): T;\n max(value: number): T;\n }\n>(\n validator: T,\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Any & Attribute.MinMaxOption<string | number>>\n): T => {\n let nextValidator: T = validator;\n\n if (\n isInteger(attr.min) &&\n (('required' in attr && attr.required) ||\n (Array.isArray(updatedAttribute.value) && updatedAttribute.value.length > 0))\n ) {\n nextValidator = nextValidator.min(attr.min);\n }\n if (isInteger(attr.max)) {\n nextValidator = nextValidator.max(attr.max);\n }\n return nextValidator;\n};\n\nconst addRequiredValidation = (createOrUpdate: CreateOrUpdate) => {\n return <T extends strapiUtils.yup.AnySchema>(\n validator: T,\n { attr: { required } }: ValidatorMeta<Partial<Attribute.Any & Attribute.RequiredOption>>\n ): T => {\n let nextValidator = validator;\n\n if (required) {\n if (createOrUpdate === 'creation') {\n nextValidator = nextValidator.notNil();\n } else if (createOrUpdate === 'update') {\n nextValidator = nextValidator.notNull();\n }\n } else {\n nextValidator = nextValidator.nullable();\n }\n return nextValidator;\n };\n};\n\nconst addDefault = (createOrUpdate: CreateOrUpdate) => {\n return (\n validator: strapiUtils.yup.BaseSchema,\n { attr }: ValidatorMeta<Attribute.Any & Attribute.DefaultOption<unknown>>\n ) => {\n let nextValidator = validator;\n\n if (createOrUpdate === 'creation') {\n if (\n ((attr.type === 'component' && attr.repeatable) || attr.type === 'dynamiczone') &&\n !attr.required\n ) {\n nextValidator = nextValidator.default([]);\n } else {\n nextValidator = nextValidator.default(attr.default);\n }\n } else {\n nextValidator = nextValidator.default(undefined);\n }\n\n return nextValidator;\n };\n};\n\nconst preventCast = (validator: strapiUtils.yup.AnySchema) =>\n validator.transform((val, originalVal) => originalVal);\n\nconst createComponentValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Component<Common.UID.Component, boolean>>,\n { isDraft }: ValidatorContext\n ) => {\n const model = strapi.getModel(attr.component);\n if (!model) {\n throw new Error('Validation failed: Model not found');\n }\n\n if (attr?.repeatable) {\n // FIXME: yup v1\n\n let validator = yup\n .array()\n .of(\n yup.lazy((item) =>\n createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }).notNull()\n ) as any\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: true },\n updatedAttribute,\n });\n\n validator = addMinMax(validator, { attr, updatedAttribute });\n\n return validator;\n }\n\n // FIXME: v4 was broken\n let validator = createModelValidator(createOrUpdate)(\n { model, data: updatedAttribute.value },\n { isDraft }\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !isDraft && attr.required },\n updatedAttribute,\n });\n\n return validator;\n };\n\nconst createDzValidator =\n (createOrUpdate: CreateOrUpdate) =>\n ({ attr, updatedAttribute }: ValidatorMeta, { isDraft }: ValidatorContext) => {\n let validator;\n\n validator = yup.array().of(\n yup.lazy((item) => {\n const model = strapi.getModel(prop('__component', item));\n const schema = yup\n .object()\n .shape({\n __component: yup.string().required().oneOf(Object.keys(strapi.components)),\n })\n .notNull();\n\n return model\n ? schema.concat(createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }))\n : schema;\n }) as any // FIXME: yup v1\n );\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: true },\n updatedAttribute,\n });\n\n validator = addMinMax(validator, { attr, updatedAttribute });\n\n return validator;\n };\n\nconst createRelationValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (\n { attr, updatedAttribute }: ValidatorMeta<Attribute.Relation>,\n { isDraft }: ValidatorContext\n ) => {\n let validator;\n\n if (Array.isArray(updatedAttribute.value)) {\n validator = yup.array().of(yup.mixed());\n } else {\n validator = yup.mixed();\n }\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !isDraft && attr.required },\n updatedAttribute,\n });\n\n return validator;\n };\n\nconst createScalarAttributeValidator =\n (createOrUpdate: CreateOrUpdate) => (metas: ValidatorMeta, options: ValidatorContext) => {\n let validator;\n\n if (has(metas.attr.type, validators)) {\n validator = (validators as any)[metas.attr.type](metas, options);\n } else {\n // No validators specified - fall back to mixed\n validator = yup.mixed();\n }\n\n validator = addRequiredValidation(createOrUpdate)(validator, {\n attr: { required: !options.isDraft && metas.attr.required },\n updatedAttribute: metas.updatedAttribute,\n });\n\n return validator;\n };\n\nconst createAttributeValidator =\n (createOrUpdate: CreateOrUpdate) =>\n (metas: AttributeValidatorMetas, options: ValidatorContext) => {\n let validator = yup.mixed();\n\n if (isMediaAttribute(metas.attr)) {\n validator = yup.mixed();\n } else if (isScalarAttribute(metas.attr)) {\n validator = createScalarAttributeValidator(createOrUpdate)(metas, options);\n } else {\n if (metas.attr.type === 'component') {\n validator = createComponentValidator(createOrUpdate)(\n { attr: metas.attr, updatedAttribute: metas.updatedAttribute },\n options\n );\n } else if (metas.attr.type === 'dynamiczone') {\n validator = createDzValidator(createOrUpdate)(metas, options);\n } else if (metas.attr.type === 'relation') {\n validator = createRelationValidator(createOrUpdate)(\n {\n attr: metas.attr,\n updatedAttribute: metas.updatedAttribute,\n },\n options\n );\n }\n\n validator = preventCast(validator);\n }\n\n validator = addDefault(createOrUpdate)(validator, metas);\n\n return validator;\n };\n\nconst createModelValidator =\n (createOrUpdate: CreateOrUpdate) =>\n ({ model, data, entity }: ModelValidatorMetas, options: ValidatorContext) => {\n const writableAttributes = model ? getWritableAttributes(model as any) : [];\n\n const schema = writableAttributes.reduce((validators, attributeName) => {\n const metas = {\n attr: model.attributes[attributeName],\n updatedAttribute: { name: attributeName, value: prop(attributeName, data) },\n model,\n entity,\n };\n\n const validator = createAttributeValidator(createOrUpdate)(metas, options);\n\n validators[attributeName] = validator;\n\n return validators;\n }, {} as Record<string, strapiUtils.yup.BaseSchema>);\n\n return yup.object().shape(schema);\n };\n\nconst createValidateEntity = (createOrUpdate: CreateOrUpdate) => {\n return async <\n TUID extends Common.UID.ContentType,\n TData extends EntityService.Params.Data.Input<TUID>\n >(\n model: Shared.ContentTypes[TUID],\n data: TData | Partial<TData> | undefined,\n options?: { isDraft?: boolean },\n entity?: Entity\n ): Promise<TData> => {\n if (!isObject(data)) {\n const { displayName } = model.info;\n\n throw new ValidationError(\n `Invalid payload submitted for the ${createOrUpdate} of an entity of type ${displayName}. Expected an object, but got ${typeof data}`\n );\n }\n\n const validator = createModelValidator(createOrUpdate)(\n { model, data, entity },\n { isDraft: options?.isDraft ?? false }\n )\n .test('relations-test', 'check that all relations exist', async function (data) {\n try {\n await checkRelationsExist(buildRelationsStore({ uid: model.uid, data }));\n } catch (e) {\n return this.createError({\n path: this.path,\n message: (e instanceof ValidationError && e.message) || 'Invalid relations',\n });\n }\n return true;\n })\n .required();\n\n return validateYupSchema(validator, {\n strict: false,\n abortEarly: false,\n })(data);\n };\n};\n\n/**\n * Builds an object containing all the media and relations being associated with an entity\n */\nconst buildRelationsStore = <TUID extends Common.UID.ContentType | Common.UID.Component>({\n uid,\n data,\n}: {\n uid: TUID;\n data: Record<string, unknown> | null;\n}): Record<string, ID[]> => {\n if (!uid) {\n throw new ValidationError(`Cannot build relations store: \"uid\" is undefined`);\n }\n\n if (isEmpty(data)) {\n return {};\n }\n\n const currentModel = strapi.getModel(uid);\n\n return Object.keys(currentModel.attributes).reduce((result, attributeName: string) => {\n const attribute = currentModel.attributes[attributeName];\n const value = data[attributeName];\n\n if (isNil(value)) {\n return result;\n }\n\n switch (attribute.type) {\n case 'relation':\n case 'media': {\n if (\n attribute.type === 'relation' &&\n (attribute.relation === 'morphToMany' || attribute.relation === 'morphToOne')\n ) {\n // TODO: handle polymorphic relations\n break;\n }\n\n const target =\n // eslint-disable-next-line no-nested-ternary\n attribute.type === 'media' ? 'plugin::upload.file' : attribute.target;\n // As there are multiple formats supported for associating relations\n // with an entity, the value here can be an: array, object or number.\n let source: RelationSource[];\n if (Array.isArray(value)) {\n source = value;\n } else if (isObject(value)) {\n if ('connect' in value && !isNil(value.connect)) {\n source = value.connect as RelationSource[];\n } else if ('set' in value && !isNil(value.set)) {\n source = value.set as RelationSource[];\n } else {\n source = [];\n }\n } else {\n source = castArray(value as RelationSource);\n }\n const idArray = source.map((v) => ({\n id: typeof v === 'object' ? v.id : v,\n }));\n\n // Update the relationStore to keep track of all associations being made\n // with relations and media.\n result[target] = result[target] || [];\n result[target].push(...idArray);\n break;\n }\n case 'component': {\n return castArray(value).reduce((relationsStore, componentValue) => {\n if (!attribute.component) {\n throw new ValidationError(\n `Cannot build relations store from component, component identifier is undefined`\n );\n }\n\n return mergeWith(\n relationsStore,\n buildRelationsStore({\n uid: attribute.component,\n data: componentValue as Record<string, unknown>,\n }),\n (objValue, srcValue) => {\n if (isArray(objValue)) {\n return objValue.concat(srcValue);\n }\n }\n );\n }, result) as Record<string, ID[]>;\n }\n case 'dynamiczone': {\n return castArray(value).reduce((relationsStore, dzValue) => {\n const value = dzValue as Record<string, unknown>;\n if (!value.__component) {\n throw new ValidationError(\n `Cannot build relations store from dynamiczone, component identifier is undefined`\n );\n }\n\n return mergeWith(\n relationsStore,\n buildRelationsStore({\n uid: value.__component as Common.UID.Component,\n data: value,\n }),\n (objValue, srcValue) => {\n if (isArray(objValue)) {\n return objValue.concat(srcValue);\n }\n }\n );\n }, result) as Record<string, ID[]>;\n }\n default:\n break;\n }\n\n return result;\n }, {} as Record<string, ID[]>);\n};\n\n/**\n * Iterate through the relations store and validates that every relation or media\n * mentioned exists\n */\nconst checkRelationsExist = async (relationsStore: Record<string, ID[]> = {}) => {\n const promises = [];\n\n for (const [key, value] of Object.entries(relationsStore)) {\n const evaluate = async () => {\n const uniqueValues = uniqBy(value, `id`);\n const count = await strapi.query(key as Common.UID.Schema).count({\n where: {\n id: {\n $in: uniqueValues.map((v) => v.id),\n },\n },\n });\n\n if (count !== uniqueValues.length) {\n throw new ValidationError(\n `${\n uniqueValues.length - count\n } relation(s) of type ${key} associated with this entity do not exist`\n );\n }\n };\n promises.push(evaluate());\n }\n\n return Promise.all(promises);\n};\n\nconst entityValidator: EntityValidator = {\n validateEntityCreation: createValidateEntity('creation'),\n validateEntityUpdate: createValidateEntity('update'),\n};\n\nexport default entityValidator;\n"],"names":["strapiUtils","validator","prop","has","validators","isObject","data","isEmpty","isNil","castArray","mergeWith","isArray","value","uniqBy"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const _ = require("lodash/fp");
2
+ const fp = require("lodash/fp");
3
3
  const strapiUtils = require("@strapi/utils");
4
4
  const compose = require("koa-compose");
5
5
  const middleware = require("./middleware.js");
@@ -7,9 +7,9 @@ const policy = require("./policy.js");
7
7
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
8
8
  const compose__default = /* @__PURE__ */ _interopDefault(compose);
9
9
  const getMethod = (route) => {
10
- return _.trim(_.toLower(route.method));
10
+ return fp.trim(fp.toLower(route.method));
11
11
  };
12
- const getPath = (route) => _.trim(route.path);
12
+ const getPath = (route) => fp.trim(route.path);
13
13
  const createRouteInfoMiddleware = (routeInfo) => (ctx, next) => {
14
14
  const route = {
15
15
  ...routeInfo,
@@ -18,7 +18,7 @@ const createRouteInfoMiddleware = (routeInfo) => (ctx, next) => {
18
18
  ctx.state.route = route;
19
19
  return next();
20
20
  };
21
- const getAuthConfig = _.prop("config.auth");
21
+ const getAuthConfig = fp.prop("config.auth");
22
22
  const createAuthorizeMiddleware = (strapi) => async (ctx, next) => {
23
23
  const { auth, route } = ctx.state;
24
24
  const authService = strapi.container.get("auth");
@@ -40,7 +40,7 @@ const createAuthenticateMiddleware = (strapi) => async (ctx, next) => {
40
40
  };
41
41
  const returnBodyMiddleware = async (ctx, next) => {
42
42
  const values = await next();
43
- if (_.isNil(ctx.body) && !_.isNil(values)) {
43
+ if (fp.isNil(ctx.body) && !fp.isNil(values)) {
44
44
  ctx.body = values;
45
45
  }
46
46
  };
@@ -61,7 +61,7 @@ const createEndpointComposer = (strapi) => {
61
61
  ...policies,
62
62
  ...middlewares,
63
63
  returnBodyMiddleware,
64
- ..._.castArray(action)
64
+ ...fp.castArray(action)
65
65
  ]);
66
66
  router[method](path, routeHandler);
67
67
  } catch (error) {
@@ -99,7 +99,7 @@ const getAction = (route, strapi) => {
99
99
  if (Array.isArray(handler) || typeof handler === "function") {
100
100
  return handler;
101
101
  }
102
- const { controllerName, actionName } = extractHandlerParts(_.trim(handler));
102
+ const { controllerName, actionName } = extractHandlerParts(fp.trim(handler));
103
103
  const controller = getController(controllerName, { pluginName, apiName, type }, strapi);
104
104
  if (typeof controller[actionName] !== "function") {
105
105
  throw new Error(`Handler not found "${handler}"`);
@@ -1 +1 @@
1
- {"version":3,"file":"compose-endpoint.js","sources":["../../../src/services/server/compose-endpoint.ts"],"sourcesContent":["import { toLower, castArray, trim, prop, isNil } from 'lodash/fp';\nimport type { Strapi, Common } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport Router from '@koa/router';\n\nimport compose from 'koa-compose';\nimport { resolveRouteMiddlewares } from './middleware';\nimport { resolvePolicies } from './policy';\n\nconst getMethod = (route: Common.Route) => {\n return trim(toLower(route.method)) as Lowercase<Common.Route['method']>;\n};\n\nconst getPath = (route: Common.Route) => trim(route.path);\n\nconst createRouteInfoMiddleware =\n (routeInfo: Common.Route): Common.MiddlewareHandler =>\n (ctx, next) => {\n const route = {\n ...routeInfo,\n config: routeInfo.config || {},\n };\n\n ctx.state.route = route;\n return next();\n };\n\nconst getAuthConfig = prop('config.auth');\n\nconst createAuthorizeMiddleware =\n (strapi: Strapi): Common.MiddlewareHandler =>\n async (ctx, next) => {\n const { auth, route } = ctx.state;\n\n const authService = strapi.container.get('auth');\n\n try {\n await authService.verify(auth, getAuthConfig(route));\n\n return await next();\n } catch (error) {\n if (error instanceof errors.UnauthorizedError) {\n return ctx.unauthorized();\n }\n\n if (error instanceof errors.ForbiddenError) {\n return ctx.forbidden();\n }\n\n throw error;\n }\n };\n\nconst createAuthenticateMiddleware =\n (strapi: Strapi): Common.MiddlewareHandler =>\n async (ctx, next) => {\n return strapi.container.get('auth').authenticate(ctx, next);\n };\n\nconst returnBodyMiddleware: Common.MiddlewareHandler = async (ctx, next) => {\n const values = await next();\n\n if (isNil(ctx.body) && !isNil(values)) {\n ctx.body = values;\n }\n};\n\nexport default (strapi: Strapi) => {\n const authenticate = createAuthenticateMiddleware(strapi);\n const authorize = createAuthorizeMiddleware(strapi);\n\n return (route: Common.Route, { router }: { router: Router }) => {\n try {\n const method = getMethod(route);\n const path = getPath(route);\n\n const middlewares = resolveRouteMiddlewares(route, strapi);\n const policies = resolvePolicies(route);\n\n const action = getAction(route, strapi);\n\n const routeHandler = compose([\n createRouteInfoMiddleware(route),\n authenticate,\n authorize,\n ...policies,\n ...middlewares,\n returnBodyMiddleware,\n ...castArray(action),\n ]);\n\n router[method](path, routeHandler);\n } catch (error) {\n if (error instanceof Error) {\n error.message = `Error creating endpoint ${route.method} ${route.path}: ${error.message}`;\n }\n\n throw error;\n }\n };\n};\n\nconst getController = (name: string, { pluginName, apiName }: Common.RouteInfo, strapi: Strapi) => {\n let ctrl: Common.Controller | undefined;\n\n if (pluginName) {\n if (pluginName === 'admin') {\n ctrl = strapi.controller(`admin::${name}`);\n } else {\n ctrl = strapi.plugin(pluginName).controller(name);\n }\n } else if (apiName) {\n ctrl = strapi.controller(`api::${apiName}.${name}`);\n }\n\n if (!ctrl) {\n return strapi.controller(name as Common.UID.Controller);\n }\n\n return ctrl;\n};\n\nconst extractHandlerParts = (name: string) => {\n const controllerName = name.slice(0, name.lastIndexOf('.'));\n const actionName = name.slice(name.lastIndexOf('.') + 1);\n\n return { controllerName, actionName };\n};\n\nconst getAction = (route: Common.Route, strapi: Strapi) => {\n const { handler, info } = route;\n const { pluginName, apiName, type } = info ?? {};\n\n if (Array.isArray(handler) || typeof handler === 'function') {\n return handler;\n }\n\n const { controllerName, actionName } = extractHandlerParts(trim(handler));\n\n const controller = getController(controllerName, { pluginName, apiName, type }, strapi);\n\n if (typeof controller[actionName] !== 'function') {\n throw new Error(`Handler not found \"${handler}\"`);\n }\n\n if (Symbol.for('__type__') in controller[actionName]) {\n (controller[actionName] as any)[Symbol.for('__type__')].push(type);\n } else {\n (controller[actionName] as any)[Symbol.for('__type__')] = [type];\n }\n\n return controller[actionName].bind(controller);\n};\n"],"names":["trim","toLower","prop","errors","isNil","resolveRouteMiddlewares","resolvePolicies","compose","castArray"],"mappings":"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"}
1
+ {"version":3,"file":"compose-endpoint.js","sources":["../../../src/services/server/compose-endpoint.ts"],"sourcesContent":["import { toLower, castArray, trim, prop, isNil } from 'lodash/fp';\nimport type { Strapi, Common } from '@strapi/types';\nimport { errors } from '@strapi/utils';\nimport Router from '@koa/router';\n\nimport compose from 'koa-compose';\nimport { resolveRouteMiddlewares } from './middleware';\nimport { resolvePolicies } from './policy';\n\nconst getMethod = (route: Common.Route) => {\n return trim(toLower(route.method)) as Lowercase<Common.Route['method']>;\n};\n\nconst getPath = (route: Common.Route) => trim(route.path);\n\nconst createRouteInfoMiddleware =\n (routeInfo: Common.Route): Common.MiddlewareHandler =>\n (ctx, next) => {\n const route = {\n ...routeInfo,\n config: routeInfo.config || {},\n };\n\n ctx.state.route = route;\n return next();\n };\n\nconst getAuthConfig = prop('config.auth');\n\nconst createAuthorizeMiddleware =\n (strapi: Strapi): Common.MiddlewareHandler =>\n async (ctx, next) => {\n const { auth, route } = ctx.state;\n\n const authService = strapi.container.get('auth');\n\n try {\n await authService.verify(auth, getAuthConfig(route));\n\n return await next();\n } catch (error) {\n if (error instanceof errors.UnauthorizedError) {\n return ctx.unauthorized();\n }\n\n if (error instanceof errors.ForbiddenError) {\n return ctx.forbidden();\n }\n\n throw error;\n }\n };\n\nconst createAuthenticateMiddleware =\n (strapi: Strapi): Common.MiddlewareHandler =>\n async (ctx, next) => {\n return strapi.container.get('auth').authenticate(ctx, next);\n };\n\nconst returnBodyMiddleware: Common.MiddlewareHandler = async (ctx, next) => {\n const values = await next();\n\n if (isNil(ctx.body) && !isNil(values)) {\n ctx.body = values;\n }\n};\n\nexport default (strapi: Strapi) => {\n const authenticate = createAuthenticateMiddleware(strapi);\n const authorize = createAuthorizeMiddleware(strapi);\n\n return (route: Common.Route, { router }: { router: Router }) => {\n try {\n const method = getMethod(route);\n const path = getPath(route);\n\n const middlewares = resolveRouteMiddlewares(route, strapi);\n const policies = resolvePolicies(route);\n\n const action = getAction(route, strapi);\n\n const routeHandler = compose([\n createRouteInfoMiddleware(route),\n authenticate,\n authorize,\n ...policies,\n ...middlewares,\n returnBodyMiddleware,\n ...castArray(action),\n ]);\n\n router[method](path, routeHandler);\n } catch (error) {\n if (error instanceof Error) {\n error.message = `Error creating endpoint ${route.method} ${route.path}: ${error.message}`;\n }\n\n throw error;\n }\n };\n};\n\nconst getController = (name: string, { pluginName, apiName }: Common.RouteInfo, strapi: Strapi) => {\n let ctrl: Common.Controller | undefined;\n\n if (pluginName) {\n if (pluginName === 'admin') {\n ctrl = strapi.controller(`admin::${name}`);\n } else {\n ctrl = strapi.plugin(pluginName).controller(name);\n }\n } else if (apiName) {\n ctrl = strapi.controller(`api::${apiName}.${name}`);\n }\n\n if (!ctrl) {\n return strapi.controller(name as Common.UID.Controller);\n }\n\n return ctrl;\n};\n\nconst extractHandlerParts = (name: string) => {\n const controllerName = name.slice(0, name.lastIndexOf('.'));\n const actionName = name.slice(name.lastIndexOf('.') + 1);\n\n return { controllerName, actionName };\n};\n\nconst getAction = (route: Common.Route, strapi: Strapi) => {\n const { handler, info } = route;\n const { pluginName, apiName, type } = info ?? {};\n\n if (Array.isArray(handler) || typeof handler === 'function') {\n return handler;\n }\n\n const { controllerName, actionName } = extractHandlerParts(trim(handler));\n\n const controller = getController(controllerName, { pluginName, apiName, type }, strapi);\n\n if (typeof controller[actionName] !== 'function') {\n throw new Error(`Handler not found \"${handler}\"`);\n }\n\n if (Symbol.for('__type__') in controller[actionName]) {\n (controller[actionName] as any)[Symbol.for('__type__')].push(type);\n } else {\n (controller[actionName] as any)[Symbol.for('__type__')] = [type];\n }\n\n return controller[actionName].bind(controller);\n};\n"],"names":["trim","toLower","prop","errors","isNil","resolveRouteMiddlewares","resolvePolicies","compose","castArray"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const _ = require("lodash/fp");
2
+ const fp = require("lodash/fp");
3
3
  const Koa = require("koa");
4
4
  const createError = require("http-errors");
5
5
  const delegate = require("delegates");
@@ -14,7 +14,7 @@ const addCustomMethods = (app) => {
14
14
  const delegator = delegate__default.default(app.context, "response");
15
15
  statuses__default.default.codes.filter((code) => code >= 400 && code < 600).forEach((code) => {
16
16
  const name = statuses__default.default(code);
17
- const camelCasedName = _.camelCase(name);
17
+ const camelCasedName = fp.camelCase(name);
18
18
  app.response[camelCasedName] = function responseCode(message, details = {}) {
19
19
  const httpError = createError__default.default(code, message, { details });
20
20
  const { status, body } = errors.formatHttpError(httpError);
@@ -32,7 +32,7 @@ const addCustomMethods = (app) => {
32
32
  this.body = data;
33
33
  };
34
34
  app.response.deleted = function deleted(data) {
35
- if (_.isNil(data)) {
35
+ if (fp.isNil(data)) {
36
36
  this.status = 204;
37
37
  } else {
38
38
  this.status = 200;
@@ -1 +1 @@
1
- {"version":3,"file":"koa.js","sources":["../../../src/services/server/koa.ts"],"sourcesContent":["import { isNil, camelCase } from 'lodash/fp';\nimport Koa from 'koa';\nimport createError from 'http-errors';\nimport delegate from 'delegates';\nimport statuses from 'statuses';\nimport { formatHttpError } from '../errors';\n\ndeclare module 'koa' {\n interface BaseResponse {\n send: (data: any, status?: number) => void;\n created: (data: any) => void;\n deleted: (data: any) => void;\n _explicitStatus: boolean;\n [key: string]: (message: string, details?: unknown) => void;\n }\n}\n\nconst addCustomMethods = (app: Koa) => {\n const delegator = delegate(app.context, 'response');\n\n /* errors */\n statuses.codes\n .filter((code) => code >= 400 && code < 600)\n .forEach((code) => {\n const name = statuses(code);\n const camelCasedName = camelCase(name);\n app.response[camelCasedName] = function responseCode(message, details = {}) {\n const httpError = createError(code, message, { details });\n const { status, body } = formatHttpError(httpError);\n this.status = status;\n this.body = body;\n };\n delegator.method(camelCasedName);\n });\n\n /* send, created, deleted */\n app.response.send = function send(data, status = 200) {\n this.status = status;\n this.body = data;\n };\n\n app.response.created = function created(data) {\n this.status = 201;\n this.body = data;\n };\n\n app.response.deleted = function deleted(data) {\n if (isNil(data)) {\n this.status = 204;\n } else {\n this.status = 200;\n this.body = data;\n }\n };\n\n delegator.method('send').method('created').method('deleted');\n\n return app;\n};\n\nconst createKoaApp = ({ proxy, keys }: { proxy: boolean; keys: string[] }) => {\n const app = new Koa({ proxy });\n app.keys = keys;\n\n addCustomMethods(app);\n\n return app;\n};\n\nexport default createKoaApp;\n"],"names":["delegate","statuses","camelCase","createError","formatHttpError","isNil","Koa"],"mappings":";;;;;;;;;;;;AAiBA,MAAM,mBAAmB,CAAC,QAAa;AACrC,QAAM,YAAYA,kBAAA,QAAS,IAAI,SAAS,UAAU;AAGzCC,oBAAAA,QAAA,MACN,OAAO,CAAC,SAAS,QAAQ,OAAO,OAAO,GAAG,EAC1C,QAAQ,CAAC,SAAS;AACX,UAAA,OAAOA,0BAAS,IAAI;AACpB,UAAA,iBAAiBC,YAAU,IAAI;AACjC,QAAA,SAAS,cAAc,IAAI,SAAS,aAAa,SAAS,UAAU,IAAI;AAC1E,YAAM,YAAYC,qBAAAA,QAAY,MAAM,SAAS,EAAE,SAAS;AACxD,YAAM,EAAE,QAAQ,KAAK,IAAIC,uBAAgB,SAAS;AAClD,WAAK,SAAS;AACd,WAAK,OAAO;AAAA,IAAA;AAEd,cAAU,OAAO,cAAc;AAAA,EAAA,CAChC;AAGH,MAAI,SAAS,OAAO,SAAS,KAAK,MAAM,SAAS,KAAK;AACpD,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAAA;AAGd,MAAI,SAAS,UAAU,SAAS,QAAQ,MAAM;AAC5C,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAAA;AAGd,MAAI,SAAS,UAAU,SAAS,QAAQ,MAAM;AACxC,QAAAC,EAAAA,MAAM,IAAI,GAAG;AACf,WAAK,SAAS;AAAA,IAAA,OACT;AACL,WAAK,SAAS;AACd,WAAK,OAAO;AAAA,IACd;AAAA,EAAA;AAGF,YAAU,OAAO,MAAM,EAAE,OAAO,SAAS,EAAE,OAAO,SAAS;AAEpD,SAAA;AACT;AAEA,MAAM,eAAe,CAAC,EAAE,OAAO,WAA+C;AAC5E,QAAM,MAAM,IAAIC,aAAAA,QAAI,EAAE,MAAO,CAAA;AAC7B,MAAI,OAAO;AAEX,mBAAiB,GAAG;AAEb,SAAA;AACT;;"}
1
+ {"version":3,"file":"koa.js","sources":["../../../src/services/server/koa.ts"],"sourcesContent":["import { isNil, camelCase } from 'lodash/fp';\nimport Koa from 'koa';\nimport createError from 'http-errors';\nimport delegate from 'delegates';\nimport statuses from 'statuses';\nimport { formatHttpError } from '../errors';\n\ndeclare module 'koa' {\n interface BaseResponse {\n send: (data: any, status?: number) => void;\n created: (data: any) => void;\n deleted: (data: any) => void;\n _explicitStatus: boolean;\n [key: string]: (message: string, details?: unknown) => void;\n }\n}\n\nconst addCustomMethods = (app: Koa) => {\n const delegator = delegate(app.context, 'response');\n\n /* errors */\n statuses.codes\n .filter((code) => code >= 400 && code < 600)\n .forEach((code) => {\n const name = statuses(code);\n const camelCasedName = camelCase(name);\n app.response[camelCasedName] = function responseCode(message, details = {}) {\n const httpError = createError(code, message, { details });\n const { status, body } = formatHttpError(httpError);\n this.status = status;\n this.body = body;\n };\n delegator.method(camelCasedName);\n });\n\n /* send, created, deleted */\n app.response.send = function send(data, status = 200) {\n this.status = status;\n this.body = data;\n };\n\n app.response.created = function created(data) {\n this.status = 201;\n this.body = data;\n };\n\n app.response.deleted = function deleted(data) {\n if (isNil(data)) {\n this.status = 204;\n } else {\n this.status = 200;\n this.body = data;\n }\n };\n\n delegator.method('send').method('created').method('deleted');\n\n return app;\n};\n\nconst createKoaApp = ({ proxy, keys }: { proxy: boolean; keys: string[] }) => {\n const app = new Koa({ proxy });\n app.keys = keys;\n\n addCustomMethods(app);\n\n return app;\n};\n\nexport default createKoaApp;\n"],"names":["delegate","statuses","camelCase","createError","formatHttpError","isNil","Koa"],"mappings":";;;;;;;;;;;;AAiBA,MAAM,mBAAmB,CAAC,QAAa;AACrC,QAAM,YAAYA,kBAAA,QAAS,IAAI,SAAS,UAAU;AAGzCC,oBAAAA,QAAA,MACN,OAAO,CAAC,SAAS,QAAQ,OAAO,OAAO,GAAG,EAC1C,QAAQ,CAAC,SAAS;AACX,UAAA,OAAOA,0BAAS,IAAI;AACpB,UAAA,iBAAiBC,aAAU,IAAI;AACjC,QAAA,SAAS,cAAc,IAAI,SAAS,aAAa,SAAS,UAAU,IAAI;AAC1E,YAAM,YAAYC,qBAAAA,QAAY,MAAM,SAAS,EAAE,SAAS;AACxD,YAAM,EAAE,QAAQ,KAAK,IAAIC,uBAAgB,SAAS;AAClD,WAAK,SAAS;AACd,WAAK,OAAO;AAAA,IAAA;AAEd,cAAU,OAAO,cAAc;AAAA,EAAA,CAChC;AAGH,MAAI,SAAS,OAAO,SAAS,KAAK,MAAM,SAAS,KAAK;AACpD,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAAA;AAGd,MAAI,SAAS,UAAU,SAAS,QAAQ,MAAM;AAC5C,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EAAA;AAGd,MAAI,SAAS,UAAU,SAAS,QAAQ,MAAM;AACxC,QAAAC,GAAAA,MAAM,IAAI,GAAG;AACf,WAAK,SAAS;AAAA,IAAA,OACT;AACL,WAAK,SAAS;AACd,WAAK,OAAO;AAAA,IACd;AAAA,EAAA;AAGF,YAAU,OAAO,MAAM,EAAE,OAAO,SAAS,EAAE,OAAO,SAAS;AAEpD,SAAA;AACT;AAEA,MAAM,eAAe,CAAC,EAAE,OAAO,WAA+C;AAC5E,QAAM,MAAM,IAAIC,aAAAA,QAAI,EAAE,MAAO,CAAA;AAC7B,MAAI,OAAO;AAEX,mBAAiB,GAAG;AAEb,SAAA;AACT;;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const path = require("path");
4
- const _ = require("lodash/fp");
4
+ const fp = require("lodash/fp");
5
5
  const strapiUtils = require("@strapi/utils");
6
6
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
7
7
  const path__default = /* @__PURE__ */ _interopDefault(path);
@@ -16,13 +16,13 @@ const instantiateMiddleware = (middlewareFactory, name, config, strapi) => {
16
16
  };
17
17
  const resolveRouteMiddlewares = (route, strapi) => {
18
18
  const middlewaresConfig = route?.config?.middlewares ?? [];
19
- if (!_.isArray(middlewaresConfig)) {
19
+ if (!fp.isArray(middlewaresConfig)) {
20
20
  throw new Error("Route middlewares config must be an array");
21
21
  }
22
22
  const middlewares = resolveMiddlewares(middlewaresConfig, strapi);
23
23
  return middlewares.map(({ handler }) => handler);
24
24
  };
25
- const dummyMiddleware = (_2, next) => next();
25
+ const dummyMiddleware = (_, next) => next();
26
26
  const resolveMiddlewares = (config, strapi) => {
27
27
  const middlewares = [];
28
28
  for (const item of config) {
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sources":["../../../src/services/server/middleware.ts"],"sourcesContent":["import path from 'path';\nimport { isArray } from 'lodash/fp';\nimport { importDefault } from '@strapi/utils';\nimport type { Strapi, Common } from '@strapi/types';\n\nconst instantiateMiddleware = (\n middlewareFactory: Common.MiddlewareFactory,\n name: string,\n config: unknown,\n strapi: Strapi\n) => {\n try {\n return middlewareFactory(config, { strapi });\n } catch (e) {\n if (e instanceof Error) {\n throw new Error(`Middleware \"${name}\": ${e.message}`);\n }\n }\n};\n\nconst resolveRouteMiddlewares = (route: Common.Route, strapi: Strapi) => {\n const middlewaresConfig = route?.config?.middlewares ?? [];\n\n if (!isArray(middlewaresConfig)) {\n throw new Error('Route middlewares config must be an array');\n }\n\n const middlewares = resolveMiddlewares(middlewaresConfig, strapi);\n\n return middlewares.map(({ handler }) => handler);\n};\n\nconst dummyMiddleware: Common.MiddlewareHandler = (_, next) => next();\n\n/**\n * Initialize every configured middlewares\n */\nconst resolveMiddlewares = (\n config: Array<\n | string\n | {\n name?: string;\n resolve?: string;\n config?: unknown;\n }\n | Common.MiddlewareHandler\n >,\n strapi: Strapi\n) => {\n const middlewares: {\n name: string | null;\n handler: Common.MiddlewareHandler;\n }[] = [];\n\n for (const item of config) {\n if (typeof item === 'function') {\n middlewares.push({\n name: null,\n handler: item,\n });\n\n continue;\n }\n\n if (typeof item === 'string') {\n const middlewareFactory = strapi.middleware(item);\n\n if (!middlewareFactory) {\n throw new Error(`Middleware ${item} not found.`);\n }\n\n middlewares.push({\n name: item,\n handler: instantiateMiddleware(middlewareFactory, item, {}, strapi) ?? dummyMiddleware,\n });\n\n continue;\n }\n\n if (typeof item === 'object' && item !== null) {\n const { name, resolve, config = {} } = item;\n\n if (name) {\n const middlewareFactory = strapi.middleware(name);\n middlewares.push({\n name,\n handler:\n instantiateMiddleware(middlewareFactory, name, config, strapi) ?? dummyMiddleware,\n });\n\n continue;\n }\n\n if (resolve) {\n const resolvedMiddlewareFactory = resolveCustomMiddleware(resolve, strapi);\n middlewares.push({\n name: resolve,\n handler:\n instantiateMiddleware(resolvedMiddlewareFactory, resolve, config, strapi) ??\n dummyMiddleware,\n });\n\n continue;\n }\n\n throw new Error('Invalid middleware configuration. Missing name or resolve properties.');\n }\n\n throw new Error(\n 'Middleware config must either be a string or an object {name?: string, resolve?: string, config: any}.'\n );\n }\n\n return middlewares;\n};\n\n/**\n * Resolve middleware from package name or path\n */\nconst resolveCustomMiddleware = (resolve: string, strapi: Strapi) => {\n let modulePath;\n\n try {\n modulePath = require.resolve(resolve);\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'MODULE_NOT_FOUND') {\n modulePath = path.resolve(strapi.dirs.dist.root, resolve);\n } else {\n throw error;\n }\n }\n\n try {\n return importDefault(modulePath);\n } catch (err) {\n throw new Error(`Could not load middleware \"${modulePath}\".`);\n }\n};\n\nexport { resolveRouteMiddlewares, resolveMiddlewares };\n"],"names":["isArray","_","config","path","importDefault"],"mappings":";;;;;;;AAKA,MAAM,wBAAwB,CAC5B,mBACA,MACA,QACA,WACG;AACC,MAAA;AACF,WAAO,kBAAkB,QAAQ,EAAE,OAAQ,CAAA;AAAA,WACpC,GAAG;AACV,QAAI,aAAa,OAAO;AACtB,YAAM,IAAI,MAAM,eAAe,IAAI,MAAM,EAAE,OAAO,EAAE;AAAA,IACtD;AAAA,EACF;AACF;AAEM,MAAA,0BAA0B,CAAC,OAAqB,WAAmB;AACvE,QAAM,oBAAoB,OAAO,QAAQ,eAAe,CAAA;AAEpD,MAAA,CAACA,EAAAA,QAAQ,iBAAiB,GAAG;AACzB,UAAA,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEM,QAAA,cAAc,mBAAmB,mBAAmB,MAAM;AAEhE,SAAO,YAAY,IAAI,CAAC,EAAE,cAAc,OAAO;AACjD;AAEA,MAAM,kBAA4C,CAACC,IAAG,SAAS,KAAK;AAK9D,MAAA,qBAAqB,CACzB,QASA,WACG;AACH,QAAM,cAGA,CAAA;AAEN,aAAW,QAAQ,QAAQ;AACrB,QAAA,OAAO,SAAS,YAAY;AAC9B,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAED;AAAA,IACF;AAEI,QAAA,OAAO,SAAS,UAAU;AACtB,YAAA,oBAAoB,OAAO,WAAW,IAAI;AAEhD,UAAI,CAAC,mBAAmB;AACtB,cAAM,IAAI,MAAM,cAAc,IAAI,aAAa;AAAA,MACjD;AAEA,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS,sBAAsB,mBAAmB,MAAM,CAAC,GAAG,MAAM,KAAK;AAAA,MAAA,CACxE;AAED;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,YAAM,EAAE,MAAM,SAAS,QAAAC,UAAS,CAAA,EAAO,IAAA;AAEvC,UAAI,MAAM;AACF,cAAA,oBAAoB,OAAO,WAAW,IAAI;AAChD,oBAAY,KAAK;AAAA,UACf;AAAA,UACA,SACE,sBAAsB,mBAAmB,MAAMA,SAAQ,MAAM,KAAK;AAAA,QAAA,CACrE;AAED;AAAA,MACF;AAEA,UAAI,SAAS;AACL,cAAA,4BAA4B,wBAAwB,SAAS,MAAM;AACzE,oBAAY,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SACE,sBAAsB,2BAA2B,SAASA,SAAQ,MAAM,KACxE;AAAA,QAAA,CACH;AAED;AAAA,MACF;AAEM,YAAA,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEO,SAAA;AACT;AAKA,MAAM,0BAA0B,CAAC,SAAiB,WAAmB;AAC/D,MAAA;AAEA,MAAA;AACW,iBAAA,QAAQ,QAAQ,OAAO;AAAA,WAC7B,OAAO;AACd,QAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,oBAAoB;AAClF,mBAAaC,cAAAA,QAAK,QAAQ,OAAO,KAAK,KAAK,MAAM,OAAO;AAAA,IAAA,OACnD;AACC,YAAA;AAAA,IACR;AAAA,EACF;AAEI,MAAA;AACF,WAAOC,YAAAA,cAAc,UAAU;AAAA,WACxB,KAAK;AACZ,UAAM,IAAI,MAAM,8BAA8B,UAAU,IAAI;AAAA,EAC9D;AACF;;;"}
1
+ {"version":3,"file":"middleware.js","sources":["../../../src/services/server/middleware.ts"],"sourcesContent":["import path from 'path';\nimport { isArray } from 'lodash/fp';\nimport { importDefault } from '@strapi/utils';\nimport type { Strapi, Common } from '@strapi/types';\n\nconst instantiateMiddleware = (\n middlewareFactory: Common.MiddlewareFactory,\n name: string,\n config: unknown,\n strapi: Strapi\n) => {\n try {\n return middlewareFactory(config, { strapi });\n } catch (e) {\n if (e instanceof Error) {\n throw new Error(`Middleware \"${name}\": ${e.message}`);\n }\n }\n};\n\nconst resolveRouteMiddlewares = (route: Common.Route, strapi: Strapi) => {\n const middlewaresConfig = route?.config?.middlewares ?? [];\n\n if (!isArray(middlewaresConfig)) {\n throw new Error('Route middlewares config must be an array');\n }\n\n const middlewares = resolveMiddlewares(middlewaresConfig, strapi);\n\n return middlewares.map(({ handler }) => handler);\n};\n\nconst dummyMiddleware: Common.MiddlewareHandler = (_, next) => next();\n\n/**\n * Initialize every configured middlewares\n */\nconst resolveMiddlewares = (\n config: Array<\n | string\n | {\n name?: string;\n resolve?: string;\n config?: unknown;\n }\n | Common.MiddlewareHandler\n >,\n strapi: Strapi\n) => {\n const middlewares: {\n name: string | null;\n handler: Common.MiddlewareHandler;\n }[] = [];\n\n for (const item of config) {\n if (typeof item === 'function') {\n middlewares.push({\n name: null,\n handler: item,\n });\n\n continue;\n }\n\n if (typeof item === 'string') {\n const middlewareFactory = strapi.middleware(item);\n\n if (!middlewareFactory) {\n throw new Error(`Middleware ${item} not found.`);\n }\n\n middlewares.push({\n name: item,\n handler: instantiateMiddleware(middlewareFactory, item, {}, strapi) ?? dummyMiddleware,\n });\n\n continue;\n }\n\n if (typeof item === 'object' && item !== null) {\n const { name, resolve, config = {} } = item;\n\n if (name) {\n const middlewareFactory = strapi.middleware(name);\n middlewares.push({\n name,\n handler:\n instantiateMiddleware(middlewareFactory, name, config, strapi) ?? dummyMiddleware,\n });\n\n continue;\n }\n\n if (resolve) {\n const resolvedMiddlewareFactory = resolveCustomMiddleware(resolve, strapi);\n middlewares.push({\n name: resolve,\n handler:\n instantiateMiddleware(resolvedMiddlewareFactory, resolve, config, strapi) ??\n dummyMiddleware,\n });\n\n continue;\n }\n\n throw new Error('Invalid middleware configuration. Missing name or resolve properties.');\n }\n\n throw new Error(\n 'Middleware config must either be a string or an object {name?: string, resolve?: string, config: any}.'\n );\n }\n\n return middlewares;\n};\n\n/**\n * Resolve middleware from package name or path\n */\nconst resolveCustomMiddleware = (resolve: string, strapi: Strapi) => {\n let modulePath;\n\n try {\n modulePath = require.resolve(resolve);\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'MODULE_NOT_FOUND') {\n modulePath = path.resolve(strapi.dirs.dist.root, resolve);\n } else {\n throw error;\n }\n }\n\n try {\n return importDefault(modulePath);\n } catch (err) {\n throw new Error(`Could not load middleware \"${modulePath}\".`);\n }\n};\n\nexport { resolveRouteMiddlewares, resolveMiddlewares };\n"],"names":["isArray","config","path","importDefault"],"mappings":";;;;;;;AAKA,MAAM,wBAAwB,CAC5B,mBACA,MACA,QACA,WACG;AACC,MAAA;AACF,WAAO,kBAAkB,QAAQ,EAAE,OAAQ,CAAA;AAAA,WACpC,GAAG;AACV,QAAI,aAAa,OAAO;AACtB,YAAM,IAAI,MAAM,eAAe,IAAI,MAAM,EAAE,OAAO,EAAE;AAAA,IACtD;AAAA,EACF;AACF;AAEM,MAAA,0BAA0B,CAAC,OAAqB,WAAmB;AACvE,QAAM,oBAAoB,OAAO,QAAQ,eAAe,CAAA;AAEpD,MAAA,CAACA,GAAAA,QAAQ,iBAAiB,GAAG;AACzB,UAAA,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAEM,QAAA,cAAc,mBAAmB,mBAAmB,MAAM;AAEhE,SAAO,YAAY,IAAI,CAAC,EAAE,cAAc,OAAO;AACjD;AAEA,MAAM,kBAA4C,CAAC,GAAG,SAAS,KAAK;AAK9D,MAAA,qBAAqB,CACzB,QASA,WACG;AACH,QAAM,cAGA,CAAA;AAEN,aAAW,QAAQ,QAAQ;AACrB,QAAA,OAAO,SAAS,YAAY;AAC9B,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,MAAA,CACV;AAED;AAAA,IACF;AAEI,QAAA,OAAO,SAAS,UAAU;AACtB,YAAA,oBAAoB,OAAO,WAAW,IAAI;AAEhD,UAAI,CAAC,mBAAmB;AACtB,cAAM,IAAI,MAAM,cAAc,IAAI,aAAa;AAAA,MACjD;AAEA,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS,sBAAsB,mBAAmB,MAAM,CAAC,GAAG,MAAM,KAAK;AAAA,MAAA,CACxE;AAED;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,YAAM,EAAE,MAAM,SAAS,QAAAC,UAAS,CAAA,EAAO,IAAA;AAEvC,UAAI,MAAM;AACF,cAAA,oBAAoB,OAAO,WAAW,IAAI;AAChD,oBAAY,KAAK;AAAA,UACf;AAAA,UACA,SACE,sBAAsB,mBAAmB,MAAMA,SAAQ,MAAM,KAAK;AAAA,QAAA,CACrE;AAED;AAAA,MACF;AAEA,UAAI,SAAS;AACL,cAAA,4BAA4B,wBAAwB,SAAS,MAAM;AACzE,oBAAY,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SACE,sBAAsB,2BAA2B,SAASA,SAAQ,MAAM,KACxE;AAAA,QAAA,CACH;AAED;AAAA,MACF;AAEM,YAAA,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEO,SAAA;AACT;AAKA,MAAM,0BAA0B,CAAC,SAAiB,WAAmB;AAC/D,MAAA;AAEA,MAAA;AACW,iBAAA,QAAQ,QAAQ,OAAO;AAAA,WAC7B,OAAO;AACd,QAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,oBAAoB;AAClF,mBAAaC,cAAAA,QAAK,QAAQ,OAAO,KAAK,KAAK,MAAM,OAAO;AAAA,IAAA,OACnD;AACC,YAAA;AAAA,IACR;AAAA,EACF;AAEI,MAAA;AACF,WAAOC,YAAAA,cAAc,UAAU;AAAA,WACxB,KAAK;AACZ,UAAM,IAAI,MAAM,8BAA8B,UAAU,IAAI;AAAA,EAC9D;AACF;;;"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const Router = require("@koa/router");
4
- const _ = require("lodash/fp");
4
+ const fp = require("lodash/fp");
5
5
  const strapiUtils = require("@strapi/utils");
6
6
  const composeEndpoint = require("./compose-endpoint.js");
7
7
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
@@ -76,7 +76,7 @@ const createRouteManager = (strapi, opts = {}) => {
76
76
  } else if (routes.routes) {
77
77
  const subRouter = new Router__default.default({ prefix: routes.prefix });
78
78
  routes.routes.forEach((route) => {
79
- const hasPrefix = _.has("prefix", route.config);
79
+ const hasPrefix = fp.has("prefix", route.config);
80
80
  createRoute(route, hasPrefix ? router : subRouter);
81
81
  });
82
82
  return router.use(subRouter.routes(), subRouter.allowedMethods());