@strapi/content-manager 5.59.0 → 5.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/dist/admin/constants/customOrder.js +14 -0
  2. package/dist/admin/constants/customOrder.js.map +1 -0
  3. package/dist/admin/constants/customOrder.mjs +10 -0
  4. package/dist/admin/constants/customOrder.mjs.map +1 -0
  5. package/dist/admin/history/components/VersionInputRenderer.js +2 -1
  6. package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
  7. package/dist/admin/history/components/VersionInputRenderer.mjs +2 -1
  8. package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
  9. package/dist/admin/hooks/useDocument.js +22 -11
  10. package/dist/admin/hooks/useDocument.js.map +1 -1
  11. package/dist/admin/hooks/useDocument.mjs +22 -11
  12. package/dist/admin/hooks/useDocument.mjs.map +1 -1
  13. package/dist/admin/hooks/useDocumentLayout.js.map +1 -1
  14. package/dist/admin/hooks/useDocumentLayout.mjs.map +1 -1
  15. package/dist/admin/hooks/useHasBeenNearViewport.js +70 -0
  16. package/dist/admin/hooks/useHasBeenNearViewport.js.map +1 -0
  17. package/dist/admin/hooks/useHasBeenNearViewport.mjs +46 -0
  18. package/dist/admin/hooks/useHasBeenNearViewport.mjs.map +1 -0
  19. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js +102 -32
  20. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.js.map +1 -1
  21. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs +104 -35
  22. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.mjs.map +1 -1
  23. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js +20 -17
  24. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.js.map +1 -1
  25. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs +20 -17
  26. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/Blocks/List.mjs.map +1 -1
  27. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +15 -1
  28. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
  29. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +17 -3
  30. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
  31. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js +21 -0
  32. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.js.map +1 -1
  33. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs +22 -1
  34. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/plugins/withStrapiSchema.mjs.map +1 -1
  35. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +1 -0
  36. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  37. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +1 -0
  38. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  39. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +1 -0
  40. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +1 -0
  42. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  43. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +2 -0
  44. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +2 -0
  46. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +4 -7
  48. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +4 -7
  50. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  51. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +46 -10
  52. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  53. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +47 -11
  54. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  55. package/dist/admin/pages/EditView/components/FormLayout.js +201 -50
  56. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  57. package/dist/admin/pages/EditView/components/FormLayout.mjs +202 -52
  58. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  59. package/dist/admin/pages/EditView/components/InputRenderer.js +3 -1
  60. package/dist/admin/pages/EditView/components/InputRenderer.js.map +1 -1
  61. package/dist/admin/pages/EditView/components/InputRenderer.mjs +3 -1
  62. package/dist/admin/pages/EditView/components/InputRenderer.mjs.map +1 -1
  63. package/dist/admin/pages/ListConfiguration/components/Settings.js +31 -2
  64. package/dist/admin/pages/ListConfiguration/components/Settings.js.map +1 -1
  65. package/dist/admin/pages/ListConfiguration/components/Settings.mjs +31 -2
  66. package/dist/admin/pages/ListConfiguration/components/Settings.mjs.map +1 -1
  67. package/dist/admin/pages/ListView/ListViewPage.js +196 -132
  68. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  69. package/dist/admin/pages/ListView/ListViewPage.mjs +196 -132
  70. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  71. package/dist/admin/pages/ListView/components/CustomOrder.js +571 -0
  72. package/dist/admin/pages/ListView/components/CustomOrder.js.map +1 -0
  73. package/dist/admin/pages/ListView/components/CustomOrder.mjs +546 -0
  74. package/dist/admin/pages/ListView/components/CustomOrder.mjs.map +1 -0
  75. package/dist/admin/pages/ListView/components/TableActions.js +4 -1
  76. package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
  77. package/dist/admin/pages/ListView/components/TableActions.mjs +4 -1
  78. package/dist/admin/pages/ListView/components/TableActions.mjs.map +1 -1
  79. package/dist/admin/preview/components/PreviewSidePanel.js +2 -1
  80. package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
  81. package/dist/admin/preview/components/PreviewSidePanel.mjs +2 -1
  82. package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
  83. package/dist/admin/preview/utils/getPreviewUrlStatus.js +17 -0
  84. package/dist/admin/preview/utils/getPreviewUrlStatus.js.map +1 -0
  85. package/dist/admin/preview/utils/getPreviewUrlStatus.mjs +15 -0
  86. package/dist/admin/preview/utils/getPreviewUrlStatus.mjs.map +1 -0
  87. package/dist/admin/services/documents.js +22 -1
  88. package/dist/admin/services/documents.js.map +1 -1
  89. package/dist/admin/services/documents.mjs +21 -2
  90. package/dist/admin/services/documents.mjs.map +1 -1
  91. package/dist/admin/src/constants/customOrder.d.ts +8 -0
  92. package/dist/admin/src/exports.d.ts +1 -1
  93. package/dist/admin/src/history/components/VersionInputRenderer.d.ts +3 -1
  94. package/dist/admin/src/hooks/useDocument.d.ts +4 -0
  95. package/dist/admin/src/hooks/useDocumentLayout.d.ts +6 -2
  96. package/dist/admin/src/hooks/useHasBeenNearViewport.d.ts +13 -0
  97. package/dist/admin/src/pages/EditView/components/FormInputs/BlocksInput/Blocks/Image.d.ts +13 -1
  98. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +11 -1
  99. package/dist/admin/src/pages/EditView/components/InputRenderer.d.ts +2 -0
  100. package/dist/admin/src/pages/ListView/components/CustomOrder.d.ts +72 -0
  101. package/dist/admin/src/preview/utils/getPreviewUrlStatus.d.ts +6 -0
  102. package/dist/admin/src/services/documents.d.ts +10 -2
  103. package/dist/admin/translations/en.json.js +9 -0
  104. package/dist/admin/translations/en.json.js.map +1 -1
  105. package/dist/admin/translations/en.json.mjs +9 -0
  106. package/dist/admin/translations/en.json.mjs.map +1 -1
  107. package/dist/server/audit-logs.js +36 -0
  108. package/dist/server/audit-logs.js.map +1 -0
  109. package/dist/server/audit-logs.mjs +33 -0
  110. package/dist/server/audit-logs.mjs.map +1 -0
  111. package/dist/server/bootstrap.js +8 -0
  112. package/dist/server/bootstrap.js.map +1 -1
  113. package/dist/server/bootstrap.mjs +8 -0
  114. package/dist/server/bootstrap.mjs.map +1 -1
  115. package/dist/server/controllers/collection-types.js +8 -0
  116. package/dist/server/controllers/collection-types.js.map +1 -1
  117. package/dist/server/controllers/collection-types.mjs +8 -0
  118. package/dist/server/controllers/collection-types.mjs.map +1 -1
  119. package/dist/server/controllers/content-types.js +15 -0
  120. package/dist/server/controllers/content-types.js.map +1 -1
  121. package/dist/server/controllers/content-types.mjs +16 -1
  122. package/dist/server/controllers/content-types.mjs.map +1 -1
  123. package/dist/server/controllers/index.js +3 -1
  124. package/dist/server/controllers/index.js.map +1 -1
  125. package/dist/server/controllers/index.mjs +2 -0
  126. package/dist/server/controllers/index.mjs.map +1 -1
  127. package/dist/server/controllers/relations.js +53 -17
  128. package/dist/server/controllers/relations.js.map +1 -1
  129. package/dist/server/controllers/relations.mjs +54 -18
  130. package/dist/server/controllers/relations.mjs.map +1 -1
  131. package/dist/server/controllers/single-types.js +10 -1
  132. package/dist/server/controllers/single-types.js.map +1 -1
  133. package/dist/server/controllers/single-types.mjs +10 -1
  134. package/dist/server/controllers/single-types.mjs.map +1 -1
  135. package/dist/server/controllers/validation/model-configuration.js +2 -1
  136. package/dist/server/controllers/validation/model-configuration.js.map +1 -1
  137. package/dist/server/controllers/validation/model-configuration.mjs +2 -1
  138. package/dist/server/controllers/validation/model-configuration.mjs.map +1 -1
  139. package/dist/server/custom-order/constants.js +21 -0
  140. package/dist/server/custom-order/constants.js.map +1 -0
  141. package/dist/server/custom-order/constants.mjs +17 -0
  142. package/dist/server/custom-order/constants.mjs.map +1 -0
  143. package/dist/server/custom-order/controllers/custom-order.js +77 -0
  144. package/dist/server/custom-order/controllers/custom-order.js.map +1 -0
  145. package/dist/server/custom-order/controllers/custom-order.mjs +75 -0
  146. package/dist/server/custom-order/controllers/custom-order.mjs.map +1 -0
  147. package/dist/server/custom-order/controllers/index.js +10 -0
  148. package/dist/server/custom-order/controllers/index.js.map +1 -0
  149. package/dist/server/custom-order/controllers/index.mjs +8 -0
  150. package/dist/server/custom-order/controllers/index.mjs.map +1 -0
  151. package/dist/server/custom-order/index.js +71 -0
  152. package/dist/server/custom-order/index.js.map +1 -0
  153. package/dist/server/custom-order/index.mjs +69 -0
  154. package/dist/server/custom-order/index.mjs.map +1 -0
  155. package/dist/server/custom-order/routes/custom-order.js +38 -0
  156. package/dist/server/custom-order/routes/custom-order.js.map +1 -0
  157. package/dist/server/custom-order/routes/custom-order.mjs +36 -0
  158. package/dist/server/custom-order/routes/custom-order.mjs.map +1 -0
  159. package/dist/server/custom-order/routes/index.js +13 -0
  160. package/dist/server/custom-order/routes/index.js.map +1 -0
  161. package/dist/server/custom-order/routes/index.mjs +11 -0
  162. package/dist/server/custom-order/routes/index.mjs.map +1 -0
  163. package/dist/server/custom-order/services/custom-order.js +286 -0
  164. package/dist/server/custom-order/services/custom-order.js.map +1 -0
  165. package/dist/server/custom-order/services/custom-order.mjs +284 -0
  166. package/dist/server/custom-order/services/custom-order.mjs.map +1 -0
  167. package/dist/server/custom-order/services/document-middleware.js +83 -0
  168. package/dist/server/custom-order/services/document-middleware.js.map +1 -0
  169. package/dist/server/custom-order/services/document-middleware.mjs +81 -0
  170. package/dist/server/custom-order/services/document-middleware.mjs.map +1 -0
  171. package/dist/server/custom-order/services/index.js +10 -0
  172. package/dist/server/custom-order/services/index.js.map +1 -0
  173. package/dist/server/custom-order/services/index.mjs +8 -0
  174. package/dist/server/custom-order/services/index.mjs.map +1 -0
  175. package/dist/server/custom-order/services/utils.js +152 -0
  176. package/dist/server/custom-order/services/utils.js.map +1 -0
  177. package/dist/server/custom-order/services/utils.mjs +148 -0
  178. package/dist/server/custom-order/services/utils.mjs.map +1 -0
  179. package/dist/server/custom-order/utils.js +13 -0
  180. package/dist/server/custom-order/utils.js.map +1 -0
  181. package/dist/server/custom-order/utils.mjs +10 -0
  182. package/dist/server/custom-order/utils.mjs.map +1 -0
  183. package/dist/server/history/constants.js +2 -1
  184. package/dist/server/history/constants.js.map +1 -1
  185. package/dist/server/history/constants.mjs +2 -1
  186. package/dist/server/history/constants.mjs.map +1 -1
  187. package/dist/server/history/controllers/history-version.js +6 -2
  188. package/dist/server/history/controllers/history-version.js.map +1 -1
  189. package/dist/server/history/controllers/history-version.mjs +6 -2
  190. package/dist/server/history/controllers/history-version.mjs.map +1 -1
  191. package/dist/server/history/services/history.js +24 -7
  192. package/dist/server/history/services/history.js.map +1 -1
  193. package/dist/server/history/services/history.mjs +25 -8
  194. package/dist/server/history/services/history.mjs.map +1 -1
  195. package/dist/server/history/services/lifecycles.js +2 -16
  196. package/dist/server/history/services/lifecycles.js.map +1 -1
  197. package/dist/server/history/services/lifecycles.mjs +2 -16
  198. package/dist/server/history/services/lifecycles.mjs.map +1 -1
  199. package/dist/server/mcp/schemas/filters-schema.js +10 -2
  200. package/dist/server/mcp/schemas/filters-schema.js.map +1 -1
  201. package/dist/server/mcp/schemas/filters-schema.mjs +10 -2
  202. package/dist/server/mcp/schemas/filters-schema.mjs.map +1 -1
  203. package/dist/server/preview/controllers/validation/preview.js +1 -1
  204. package/dist/server/preview/controllers/validation/preview.js.map +1 -1
  205. package/dist/server/preview/controllers/validation/preview.mjs +2 -2
  206. package/dist/server/preview/controllers/validation/preview.mjs.map +1 -1
  207. package/dist/server/register.js +4 -0
  208. package/dist/server/register.js.map +1 -1
  209. package/dist/server/register.mjs +4 -0
  210. package/dist/server/register.mjs.map +1 -1
  211. package/dist/server/routes/index.js +3 -1
  212. package/dist/server/routes/index.js.map +1 -1
  213. package/dist/server/routes/index.mjs +2 -0
  214. package/dist/server/routes/index.mjs.map +1 -1
  215. package/dist/server/services/content-types.js +2 -2
  216. package/dist/server/services/content-types.js.map +1 -1
  217. package/dist/server/services/content-types.mjs +2 -2
  218. package/dist/server/services/content-types.mjs.map +1 -1
  219. package/dist/server/services/document-manager.js +13 -0
  220. package/dist/server/services/document-manager.js.map +1 -1
  221. package/dist/server/services/document-manager.mjs +14 -1
  222. package/dist/server/services/document-manager.mjs.map +1 -1
  223. package/dist/server/services/document-metadata.js +1 -1
  224. package/dist/server/services/document-metadata.js.map +1 -1
  225. package/dist/server/services/document-metadata.mjs +1 -1
  226. package/dist/server/services/document-metadata.mjs.map +1 -1
  227. package/dist/server/services/index.js +3 -1
  228. package/dist/server/services/index.js.map +1 -1
  229. package/dist/server/services/index.mjs +2 -0
  230. package/dist/server/services/index.mjs.map +1 -1
  231. package/dist/server/services/utils/configuration/settings.js +2 -1
  232. package/dist/server/services/utils/configuration/settings.js.map +1 -1
  233. package/dist/server/services/utils/configuration/settings.mjs +2 -1
  234. package/dist/server/services/utils/configuration/settings.mjs.map +1 -1
  235. package/dist/server/src/audit-logs.d.ts +40 -0
  236. package/dist/server/src/audit-logs.d.ts.map +1 -0
  237. package/dist/server/src/bootstrap.d.ts.map +1 -1
  238. package/dist/server/src/controllers/collection-types.d.ts +1 -1
  239. package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
  240. package/dist/server/src/controllers/content-types.d.ts.map +1 -1
  241. package/dist/server/src/controllers/index.d.ts +21 -3
  242. package/dist/server/src/controllers/index.d.ts.map +1 -1
  243. package/dist/server/src/controllers/relations.d.ts +19 -1
  244. package/dist/server/src/controllers/relations.d.ts.map +1 -1
  245. package/dist/server/src/controllers/single-types.d.ts +1 -1
  246. package/dist/server/src/controllers/single-types.d.ts.map +1 -1
  247. package/dist/server/src/custom-order/constants.d.ts +18 -0
  248. package/dist/server/src/custom-order/constants.d.ts.map +1 -0
  249. package/dist/server/src/custom-order/controllers/custom-order.d.ts +8 -0
  250. package/dist/server/src/custom-order/controllers/custom-order.d.ts.map +1 -0
  251. package/dist/server/src/custom-order/controllers/index.d.ts +3 -0
  252. package/dist/server/src/custom-order/controllers/index.d.ts.map +1 -0
  253. package/dist/server/src/custom-order/index.d.ts +8 -0
  254. package/dist/server/src/custom-order/index.d.ts.map +1 -0
  255. package/dist/server/src/custom-order/routes/custom-order.d.ts +4 -0
  256. package/dist/server/src/custom-order/routes/custom-order.d.ts.map +1 -0
  257. package/dist/server/src/custom-order/routes/index.d.ts +10 -0
  258. package/dist/server/src/custom-order/routes/index.d.ts.map +1 -0
  259. package/dist/server/src/custom-order/services/custom-order.d.ts +43 -0
  260. package/dist/server/src/custom-order/services/custom-order.d.ts.map +1 -0
  261. package/dist/server/src/custom-order/services/document-middleware.d.ts +16 -0
  262. package/dist/server/src/custom-order/services/document-middleware.d.ts.map +1 -0
  263. package/dist/server/src/custom-order/services/index.d.ts +24 -0
  264. package/dist/server/src/custom-order/services/index.d.ts.map +1 -0
  265. package/dist/server/src/custom-order/services/utils.d.ts +34 -0
  266. package/dist/server/src/custom-order/services/utils.d.ts.map +1 -0
  267. package/dist/server/src/custom-order/utils.d.ts +6 -0
  268. package/dist/server/src/custom-order/utils.d.ts.map +1 -0
  269. package/dist/server/src/history/constants.d.ts.map +1 -1
  270. package/dist/server/src/history/controllers/history-version.d.ts.map +1 -1
  271. package/dist/server/src/history/services/history.d.ts.map +1 -1
  272. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  273. package/dist/server/src/index.d.ts +22 -6
  274. package/dist/server/src/index.d.ts.map +1 -1
  275. package/dist/server/src/mcp/schemas/filters-schema.d.ts.map +1 -1
  276. package/dist/server/src/register.d.ts.map +1 -1
  277. package/dist/server/src/routes/index.d.ts.map +1 -1
  278. package/dist/server/src/services/content-types.d.ts +1 -3
  279. package/dist/server/src/services/content-types.d.ts.map +1 -1
  280. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  281. package/dist/server/src/services/index.d.ts +1 -3
  282. package/dist/server/src/services/index.d.ts.map +1 -1
  283. package/dist/server/src/services/utils/configuration/settings.d.ts.map +1 -1
  284. package/dist/shared/contracts/content-types.d.ts +5 -0
  285. package/dist/shared/contracts/content-types.d.ts.map +1 -1
  286. package/dist/shared/contracts/custom-order.d.ts +33 -0
  287. package/dist/shared/contracts/custom-order.d.ts.map +1 -0
  288. package/dist/shared/contracts/custom-order.js +3 -0
  289. package/dist/shared/contracts/custom-order.js.map +1 -0
  290. package/dist/shared/contracts/custom-order.mjs +2 -0
  291. package/dist/shared/contracts/custom-order.mjs.map +1 -0
  292. package/dist/shared/contracts/history-versions.d.ts +0 -1
  293. package/dist/shared/contracts/history-versions.d.ts.map +1 -1
  294. package/dist/shared/contracts/index.d.ts +1 -0
  295. package/dist/shared/contracts/index.d.ts.map +1 -1
  296. package/dist/shared/contracts/index.js +2 -0
  297. package/dist/shared/contracts/index.js.map +1 -1
  298. package/dist/shared/contracts/index.mjs +2 -0
  299. package/dist/shared/contracts/index.mjs.map +1 -1
  300. package/package.json +10 -10
@@ -8,6 +8,15 @@ var attributes = require('../services/utils/configuration/attributes.js');
8
8
  var documentStatus = require('./utils/document-status.js');
9
9
 
10
10
  const { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = strapiUtils.contentTypes.constants;
11
+ /**
12
+ * Fields every relation returned by findExisting carries, whatever the user's permissions.
13
+ */ const RELATION_BASE_FIELDS = [
14
+ 'id',
15
+ 'documentId',
16
+ 'locale',
17
+ 'publishedAt',
18
+ 'updatedAt'
19
+ ];
11
20
  const addFiltersClause = (params, filtersClause)=>{
12
21
  params.filters = params.filters || {};
13
22
  params.filters.$and = params.filters.$and || [];
@@ -56,7 +65,7 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
56
65
  $notNull: true
57
66
  }
58
67
  };
59
- const availableStatus = await strapi.query(targetUid).findMany({
68
+ const availableStatus = await strapi.db.query(targetUid).findMany({
60
69
  select: [
61
70
  'id',
62
71
  'documentId',
@@ -137,6 +146,10 @@ var relations = {
137
146
  if (!attribute || attribute.type !== 'relation') {
138
147
  throw new strapiUtils.errors.ValidationError(`The relational field ${targetField} doesn't exist on ${model}`);
139
148
  }
149
+ // Morph-to relations (morphToOne, morphToMany) have no single target model
150
+ if (attribute.target === undefined) {
151
+ throw new strapiUtils.errors.ValidationError(`The relational field ${targetField} on ${model} has no target model`);
152
+ }
140
153
  const sourceUid = model;
141
154
  const targetUid = attribute.target;
142
155
  const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(sourceUid, targetUid, ctx.request?.query?.locale);
@@ -148,7 +161,7 @@ var relations = {
148
161
  const isComponent = sourceSchema.modelType === 'component';
149
162
  if (!isComponent) {
150
163
  if (permissionChecker.cannot.read(null, targetField)) {
151
- return ctx.forbidden();
164
+ throw new strapiUtils.errors.ForbiddenError();
152
165
  }
153
166
  }
154
167
  let entryId = null;
@@ -385,6 +398,41 @@ var relations = {
385
398
  $null: true
386
399
  };
387
400
  }
401
+ const pageParams = {
402
+ page: ctx.request.query.page,
403
+ pageSize: ctx.request.query.pageSize
404
+ };
405
+ const defaultPagination = (total)=>({
406
+ page: 1,
407
+ pageCount: 1,
408
+ pageSize: 10,
409
+ total
410
+ });
411
+ /**
412
+ * The permission query only carries row-level conditions when the user's read permission on
413
+ * the target has conditions (e.g. "only entries I created"). Without them it only restricts
414
+ * the fields, so a single load returns exactly what the two-step flow below would: the
415
+ * relations of the page with the fields the user is allowed to read.
416
+ */ if (_.isEmpty(permissionQuery.filters)) {
417
+ const { select } = strapi.get('query-params').transform(targetUid, permissionQuery);
418
+ const permittedFields = Array.isArray(select) ? select : [];
419
+ const res = await loadRelations({
420
+ id: entryId
421
+ }, targetField, {
422
+ select: _.uniq([
423
+ ...RELATION_BASE_FIELDS,
424
+ ...permittedFields
425
+ ]),
426
+ ordering: 'desc',
427
+ ...pageParams,
428
+ filters
429
+ });
430
+ ctx.body = {
431
+ pagination: res.pagination || defaultPagination(res.results.length),
432
+ results: await addStatusToRelations(targetUid, res.results)
433
+ };
434
+ return;
435
+ }
388
436
  /**
389
437
  * If user does not have access to specific relations (custom conditions),
390
438
  * only the ids of the relations are returned.
@@ -396,16 +444,9 @@ var relations = {
396
444
  */ const res = await loadRelations({
397
445
  id: entryId
398
446
  }, targetField, {
399
- select: [
400
- 'id',
401
- 'documentId',
402
- 'locale',
403
- 'publishedAt',
404
- 'updatedAt'
405
- ],
447
+ select: RELATION_BASE_FIELDS,
406
448
  ordering: 'desc',
407
- page: ctx.request.query.page,
408
- pageSize: ctx.request.query.pageSize,
449
+ ...pageParams,
409
450
  filters
410
451
  });
411
452
  /**
@@ -431,12 +472,7 @@ var relations = {
431
472
  // NOTE: the order is very important to make sure sanitized relations are kept in priority
432
473
  const relationsUnion = _.uniqBy(_.concat(sanitizedRes.results, res.results), 'id');
433
474
  ctx.body = {
434
- pagination: res.pagination || {
435
- page: 1,
436
- pageCount: 1,
437
- pageSize: 10,
438
- total: relationsUnion.length
439
- },
475
+ pagination: res.pagination || defaultPagination(relationsUnion.length),
440
476
  results: await addStatusToRelations(targetUid, relationsUnion)
441
477
  };
442
478
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniqBy, concat, flow, isEmpty } from 'lodash';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\nimport { indexByDocumentId } from './utils/document-status';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, 'documentId']),\n ];\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const {\n idsToOmit,\n idsToInclude,\n // `_q` is the public query parameter name; keep the alias grep-able.\n _q: search,\n ...query\n } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (search) {\n const filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [filter]: search } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: [...new Set(idsToOmit)] },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish || sourceSchema?.modelType === 'component') {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very important to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy(concat(sanitizedRes.results, res.results), 'id');\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isSourceLocalized","localization","isLocalizedContentType","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
1
+ {"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniq, uniqBy, concat, flow, isEmpty } from 'lodash';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\nimport { indexByDocumentId } from './utils/document-status';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\n/**\n * Fields every relation returned by findExisting carries, whatever the user's permissions.\n */\nconst RELATION_BASE_FIELDS = ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'];\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.db.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string | undefined, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n // Morph-to relations (morphToOne, morphToMany) have no single target model\n if (attribute.target === undefined) {\n throw new errors.ValidationError(\n `The relational field ${targetField} on ${model} has no target model`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, 'documentId']),\n ];\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const {\n idsToOmit,\n idsToInclude,\n // `_q` is the public query parameter name; keep the alias grep-able.\n _q: search,\n ...query\n } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (search) {\n const filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [filter]: search } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: [...new Set(idsToOmit)] },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish || sourceSchema?.modelType === 'component') {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n const pageParams = {\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n };\n\n const defaultPagination = (total: number) => ({ page: 1, pageCount: 1, pageSize: 10, total });\n\n /**\n * The permission query only carries row-level conditions when the user's read permission on\n * the target has conditions (e.g. \"only entries I created\"). Without them it only restricts\n * the fields, so a single load returns exactly what the two-step flow below would: the\n * relations of the page with the fields the user is allowed to read.\n */\n if (isEmpty(permissionQuery.filters)) {\n const { select } = strapi.get('query-params').transform(targetUid, permissionQuery);\n const permittedFields = Array.isArray(select) ? select : [];\n\n const res = await loadRelations({ id: entryId }, targetField, {\n select: uniq([...RELATION_BASE_FIELDS, ...permittedFields]),\n ordering: 'desc',\n ...pageParams,\n filters,\n });\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(res.results.length),\n results: await addStatusToRelations(targetUid, res.results),\n };\n\n return;\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: RELATION_BASE_FIELDS,\n ordering: 'desc',\n ...pageParams,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very important to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy(concat(sanitizedRes.results, res.results), 'id');\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(relationsUnion.length),\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","RELATION_BASE_FIELDS","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","db","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isSourceLocalized","localization","isLocalizedContentType","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","cannot","ForbiddenError","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","findOne","NotFoundError","modelConfig","findConfiguration","targetSchema","flow","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","pageParams","page","pageSize","defaultPagination","total","pageCount","permittedFields","Array","isArray","uniq","ordering","pagination","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { uniqBy, concat, isEmpty, flow, property } from 'lodash';
1
+ import { isEmpty, uniq, uniqBy, concat, flow, property } from 'lodash';
2
2
  import { contentTypes, relations as relations$1, isOperatorOfType, errors } from '@strapi/utils';
3
3
  import { getService } from '../utils/index.mjs';
4
4
  import { validateFindExisting, validateFindAvailable } from './validation/relations.mjs';
@@ -6,6 +6,15 @@ import { isListable } from '../services/utils/configuration/attributes.mjs';
6
6
  import { indexByDocumentId } from './utils/document-status.mjs';
7
7
 
8
8
  const { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;
9
+ /**
10
+ * Fields every relation returned by findExisting carries, whatever the user's permissions.
11
+ */ const RELATION_BASE_FIELDS = [
12
+ 'id',
13
+ 'documentId',
14
+ 'locale',
15
+ 'publishedAt',
16
+ 'updatedAt'
17
+ ];
9
18
  const addFiltersClause = (params, filtersClause)=>{
10
19
  params.filters = params.filters || {};
11
20
  params.filters.$and = params.filters.$and || [];
@@ -54,7 +63,7 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
54
63
  $notNull: true
55
64
  }
56
65
  };
57
- const availableStatus = await strapi.query(targetUid).findMany({
66
+ const availableStatus = await strapi.db.query(targetUid).findMany({
58
67
  select: [
59
68
  'id',
60
69
  'documentId',
@@ -135,6 +144,10 @@ var relations = {
135
144
  if (!attribute || attribute.type !== 'relation') {
136
145
  throw new errors.ValidationError(`The relational field ${targetField} doesn't exist on ${model}`);
137
146
  }
147
+ // Morph-to relations (morphToOne, morphToMany) have no single target model
148
+ if (attribute.target === undefined) {
149
+ throw new errors.ValidationError(`The relational field ${targetField} on ${model} has no target model`);
150
+ }
138
151
  const sourceUid = model;
139
152
  const targetUid = attribute.target;
140
153
  const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(sourceUid, targetUid, ctx.request?.query?.locale);
@@ -146,7 +159,7 @@ var relations = {
146
159
  const isComponent = sourceSchema.modelType === 'component';
147
160
  if (!isComponent) {
148
161
  if (permissionChecker.cannot.read(null, targetField)) {
149
- return ctx.forbidden();
162
+ throw new errors.ForbiddenError();
150
163
  }
151
164
  }
152
165
  let entryId = null;
@@ -383,6 +396,41 @@ var relations = {
383
396
  $null: true
384
397
  };
385
398
  }
399
+ const pageParams = {
400
+ page: ctx.request.query.page,
401
+ pageSize: ctx.request.query.pageSize
402
+ };
403
+ const defaultPagination = (total)=>({
404
+ page: 1,
405
+ pageCount: 1,
406
+ pageSize: 10,
407
+ total
408
+ });
409
+ /**
410
+ * The permission query only carries row-level conditions when the user's read permission on
411
+ * the target has conditions (e.g. "only entries I created"). Without them it only restricts
412
+ * the fields, so a single load returns exactly what the two-step flow below would: the
413
+ * relations of the page with the fields the user is allowed to read.
414
+ */ if (isEmpty(permissionQuery.filters)) {
415
+ const { select } = strapi.get('query-params').transform(targetUid, permissionQuery);
416
+ const permittedFields = Array.isArray(select) ? select : [];
417
+ const res = await loadRelations({
418
+ id: entryId
419
+ }, targetField, {
420
+ select: uniq([
421
+ ...RELATION_BASE_FIELDS,
422
+ ...permittedFields
423
+ ]),
424
+ ordering: 'desc',
425
+ ...pageParams,
426
+ filters
427
+ });
428
+ ctx.body = {
429
+ pagination: res.pagination || defaultPagination(res.results.length),
430
+ results: await addStatusToRelations(targetUid, res.results)
431
+ };
432
+ return;
433
+ }
386
434
  /**
387
435
  * If user does not have access to specific relations (custom conditions),
388
436
  * only the ids of the relations are returned.
@@ -394,16 +442,9 @@ var relations = {
394
442
  */ const res = await loadRelations({
395
443
  id: entryId
396
444
  }, targetField, {
397
- select: [
398
- 'id',
399
- 'documentId',
400
- 'locale',
401
- 'publishedAt',
402
- 'updatedAt'
403
- ],
445
+ select: RELATION_BASE_FIELDS,
404
446
  ordering: 'desc',
405
- page: ctx.request.query.page,
406
- pageSize: ctx.request.query.pageSize,
447
+ ...pageParams,
407
448
  filters
408
449
  });
409
450
  /**
@@ -429,12 +470,7 @@ var relations = {
429
470
  // NOTE: the order is very important to make sure sanitized relations are kept in priority
430
471
  const relationsUnion = uniqBy(concat(sanitizedRes.results, res.results), 'id');
431
472
  ctx.body = {
432
- pagination: res.pagination || {
433
- page: 1,
434
- pageCount: 1,
435
- pageSize: 10,
436
- total: relationsUnion.length
437
- },
473
+ pagination: res.pagination || defaultPagination(relationsUnion.length),
438
474
  results: await addStatusToRelations(targetUid, relationsUnion)
439
475
  };
440
476
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniqBy, concat, flow, isEmpty } from 'lodash';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\nimport { indexByDocumentId } from './utils/document-status';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n return ctx.forbidden();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, 'documentId']),\n ];\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const {\n idsToOmit,\n idsToInclude,\n // `_q` is the public query parameter name; keep the alias grep-able.\n _q: search,\n ...query\n } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (search) {\n const filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [filter]: search } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: [...new Set(idsToOmit)] },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish || sourceSchema?.modelType === 'component') {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'],\n ordering: 'desc',\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very important to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy(concat(sanitizedRes.results, res.results), 'id');\n\n ctx.body = {\n pagination: res.pagination || {\n page: 1,\n pageCount: 1,\n pageSize: 10,\n total: relationsUnion.length,\n },\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isSourceLocalized","localization","isLocalizedContentType","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","ordering","page","pageSize","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat","pagination","pageCount","total"],"mappings":"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"}
1
+ {"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { property, uniq, uniqBy, concat, flow, isEmpty } from 'lodash';\n\nimport { isOperatorOfType, contentTypes, relations, errors } from '@strapi/utils';\nimport type { Data, Modules, UID } from '@strapi/types';\n\nimport { getService } from '../utils';\nimport { validateFindAvailable, validateFindExisting } from './validation/relations';\nimport { isListable } from '../services/utils/configuration/attributes';\nimport { indexByDocumentId } from './utils/document-status';\n\nconst { PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE } = contentTypes.constants;\n\ninterface RelationEntity {\n id: Data.ID;\n documentId: Modules.Documents.ID;\n updatedAt: string | Date;\n publishedAt?: string | Date;\n [key: string]: unknown;\n}\n\n/**\n * Fields every relation returned by findExisting carries, whatever the user's permissions.\n */\nconst RELATION_BASE_FIELDS = ['id', 'documentId', 'locale', 'publishedAt', 'updatedAt'];\n\nconst addFiltersClause = (params: any, filtersClause: any) => {\n params.filters = params.filters || {};\n params.filters.$and = params.filters.$and || [];\n params.filters.$and.push(filtersClause);\n};\n\nconst sanitizeMainField = (model: any, mainField: any, userAbility: any) => {\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model: model.uid,\n });\n\n // Whether the main field can be displayed or not, regardless of permissions.\n const isMainFieldListable = isListable(model, mainField);\n // Whether the user has the permission to access the model's main field (using RBAC abilities)\n const canReadMainField = permissionChecker.can.read(null, mainField);\n\n if (!isMainFieldListable || !canReadMainField) {\n // Default to 'documentId' if the actual main field shouldn't be displayed\n return 'documentId';\n }\n\n // Edge cases\n\n // 1. Enforce 'name' as the main field for users and permissions' roles\n if (model.uid === 'plugin::users-permissions.role') {\n return 'name';\n }\n\n return mainField;\n};\n\n/**\n *\n * All relations sent to this function should have the same status or no status\n */\nconst addStatusToRelations = async (targetUid: UID.Schema, relations: RelationEntity[]) => {\n if (!contentTypes.hasDraftAndPublish(strapi.getModel(targetUid))) {\n return relations;\n }\n\n const documentMetadata = getService('document-metadata');\n\n if (!relations.length) {\n return relations;\n }\n\n const firstRelation = relations[0];\n\n const filters: any = {\n documentId: { $in: relations.map((r) => r.documentId) },\n // NOTE: find the \"opposite\" status\n publishedAt: firstRelation.publishedAt !== null ? { $null: true } : { $notNull: true },\n };\n\n const availableStatus = await strapi.db.query(targetUid).findMany({\n select: ['id', 'documentId', 'locale', 'updatedAt', 'createdAt', 'publishedAt'],\n filters,\n });\n\n const statusByDocumentId = indexByDocumentId(availableStatus);\n\n return relations.map((relation: RelationEntity) => {\n const candidates = statusByDocumentId.get(relation.documentId as string) || [];\n const availableStatuses = relation.locale\n ? candidates.filter((c) => c.locale === relation.locale)\n : candidates;\n\n return {\n ...relation,\n status: documentMetadata.getStatus(relation, availableStatuses),\n };\n });\n};\n\nconst getPublishedAtClause = (status: string | undefined, uid: UID.Schema) => {\n const model = strapi.getModel(uid);\n\n /**\n * If dp is disabled, ignore the filter\n */\n if (!model || !contentTypes.hasDraftAndPublish(model)) {\n return {};\n }\n\n // Prioritize the draft status in case it's not provided\n return status === 'published' ? { $notNull: true } : { $null: true };\n};\n\nconst validateLocale = (sourceUid: UID.Schema, targetUid: UID.ContentType, locale?: string) => {\n const sourceModel = strapi.getModel(sourceUid);\n const targetModel = strapi.getModel(targetUid);\n\n // Without a localization provider, neither side is localized\n const isSourceLocalized = strapi.localization.isLocalizedContentType(sourceModel);\n const isTargetLocalized = strapi.localization.isLocalizedContentType(targetModel);\n\n return {\n locale,\n isSourceLocalized,\n isTargetLocalized,\n };\n};\n\nconst validateStatus = (\n sourceUid: UID.Schema,\n status?: Modules.Documents.Params.PublicationStatus.Kind\n) => {\n const sourceModel = strapi.getModel(sourceUid);\n\n const isDP = contentTypes.hasDraftAndPublish;\n const isSourceDP = isDP(sourceModel);\n\n // Default to draft if not set\n if (!isSourceDP && sourceModel.modelType === 'contentType') {\n return { status: undefined };\n }\n\n switch (status) {\n case 'published':\n return { status: 'published' };\n default:\n // Assign to draft if the status is not valid\n return { status: 'draft' };\n }\n};\n\nexport default {\n async extractAndValidateRequestInfo(ctx: any, id?: Data.ID) {\n const { userAbility } = ctx.state;\n const { model, targetField } = ctx.params;\n\n const sourceSchema = strapi.getModel(model);\n if (!sourceSchema) {\n throw new errors.ValidationError(`The model ${model} doesn't exist`);\n }\n\n const attribute: any = sourceSchema.attributes[targetField];\n if (!attribute || attribute.type !== 'relation') {\n throw new errors.ValidationError(\n `The relational field ${targetField} doesn't exist on ${model}`\n );\n }\n\n // Morph-to relations (morphToOne, morphToMany) have no single target model\n if (attribute.target === undefined) {\n throw new errors.ValidationError(\n `The relational field ${targetField} on ${model} has no target model`\n );\n }\n\n const sourceUid = model;\n const targetUid = attribute.target;\n\n const { locale, isSourceLocalized, isTargetLocalized } = validateLocale(\n sourceUid,\n targetUid,\n ctx.request?.query?.locale\n );\n const { status } = validateStatus(sourceUid, ctx.request?.query?.status);\n\n const permissionChecker = getService('permission-checker').create({\n userAbility,\n model,\n });\n\n const isComponent = sourceSchema.modelType === 'component';\n if (!isComponent) {\n if (permissionChecker.cannot.read(null, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n let entryId: string | number | null = null;\n\n if (id) {\n const where: Record<string, any> = {};\n\n if (!isComponent) {\n where.documentId = id;\n\n if (status) {\n where.publishedAt = getPublishedAtClause(status, sourceUid);\n }\n\n if (locale && isSourceLocalized) {\n where.locale = locale;\n }\n } else {\n // If the source is a component, we only need to filter by the\n // component's entity id\n where.id = id;\n }\n\n const permissionQuery = await permissionChecker.sanitizedQuery.read(ctx.query);\n const populate = await getService('populate-builder')(model)\n .populateFromQuery(permissionQuery)\n .build();\n\n const currentEntity = await strapi.db.query(model).findOne({\n where,\n populate,\n });\n\n // We need to check if the entity exists\n // and if the user has the permission to read it in this way\n // There may be multiple entities (publication states) under this\n // documentId + locale. We only need to check if one exists\n if (!currentEntity) {\n throw new errors.NotFoundError();\n }\n\n if (!isComponent) {\n if (permissionChecker.cannot.read(currentEntity, targetField)) {\n throw new errors.ForbiddenError();\n }\n }\n\n entryId = currentEntity.id;\n }\n\n const modelConfig = isComponent\n ? await getService('components').findConfiguration(sourceSchema)\n : await getService('content-types').findConfiguration(sourceSchema);\n\n const targetSchema = strapi.getModel(targetUid);\n\n const mainField = flow(\n property(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = [\n ...new Set([mainField, PUBLISHED_AT_ATTRIBUTE, UPDATED_AT_ATTRIBUTE, 'documentId']),\n ];\n\n if (isTargetLocalized) {\n fieldsToSelect.push('locale');\n }\n\n return {\n entryId,\n locale,\n status,\n attribute,\n fieldsToSelect,\n mainField,\n source: { schema: sourceSchema, isLocalized: isSourceLocalized },\n target: { schema: targetSchema, isLocalized: isTargetLocalized },\n sourceSchema,\n targetSchema,\n targetField,\n };\n },\n\n /**\n * Used to find new relations to add in a relational field.\n *\n * Component and document relations are dealt a bit differently (they don't have a document_id).\n */\n async findAvailable(ctx: any) {\n const { id } = ctx.request.query;\n\n await validateFindAvailable(ctx.request.query);\n\n const {\n locale,\n status,\n targetField,\n fieldsToSelect,\n mainField,\n source: {\n schema: { uid: sourceUid, modelType: sourceModelType },\n isLocalized: isSourceLocalized,\n },\n target: {\n schema: { uid: targetUid },\n isLocalized: isTargetLocalized,\n },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const {\n idsToOmit,\n idsToInclude,\n // `_q` is the public query parameter name; keep the alias grep-able.\n _q: search,\n ...query\n } = ctx.request.query;\n\n const permissionChecker = getService('permission-checker').create({\n userAbility: ctx.state.userAbility,\n model: targetUid,\n });\n const permissionQuery = await permissionChecker.sanitizedQuery.read(query);\n\n const queryParams = {\n sort: mainField,\n // cannot select other fields as the user may not have the permissions\n fields: fieldsToSelect,\n ...permissionQuery,\n };\n\n // If no status is requested, we find all the draft relations and later update them\n // with the latest available status\n addFiltersClause(queryParams, {\n publishedAt: getPublishedAtClause(status, targetUid),\n });\n\n // We will only filter by locale if the target content type is localized\n const filterByLocale = isTargetLocalized && locale;\n if (filterByLocale) {\n addFiltersClause(queryParams, { locale });\n }\n\n if (id) {\n /**\n * Exclude the relations that are already related to the source\n *\n * We also optionally filter the target relations by the requested\n * status and locale if provided.\n */\n const subQuery = strapi.db.queryBuilder(sourceUid);\n\n // The alias refers to the DB table of the target content type model\n const alias = subQuery.getAlias();\n\n const where: Record<string, any> = {\n [`${alias}.id`]: { $notNull: true },\n [`${alias}.document_id`]: { $notNull: true },\n };\n\n /**\n * Content Types -> Specify document id\n * Components -> Specify entity id (they don't have a document id)\n */\n if (sourceModelType === 'contentType') {\n where.document_id = id;\n\n const sourcePublishedAt = getPublishedAtClause(status, sourceUid);\n if (!isEmpty(sourcePublishedAt)) {\n where.published_at = sourcePublishedAt;\n }\n } else {\n where.id = id;\n }\n\n // Add the status and locale filters if they are provided\n const publishedAt = getPublishedAtClause(status, targetUid);\n if (!isEmpty(publishedAt)) {\n where[`${alias}.published_at`] = publishedAt;\n }\n\n // If target has localization we need to filter by locale\n if (isTargetLocalized && locale) {\n where[`${alias}.locale`] = locale;\n }\n\n if (isSourceLocalized && locale) {\n where.locale = locale;\n }\n\n /**\n * UI can provide a list of ids to omit,\n * those are the relations user set in the UI but has not persisted.\n * We don't want to include them in the available relations.\n */\n if ((idsToInclude?.length ?? 0) !== 0) {\n where[`${alias}.id`].$notIn = idsToInclude;\n }\n\n const knexSubQuery = subQuery\n .where(where)\n .join({ alias, targetField })\n .select(`${alias}.id`)\n .getKnexQuery();\n\n addFiltersClause(queryParams, {\n id: { $notIn: knexSubQuery },\n });\n }\n\n /**\n * Apply a filter to the mainField based on the search query and filter operator\n * searching should be allowed only on mainField for permission reasons\n */\n if (search) {\n const filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [filter]: search } });\n }\n\n if (idsToOmit?.length > 0) {\n // If we have ids to omit, we should filter them out\n addFiltersClause(queryParams, {\n id: { $notIn: [...new Set(idsToOmit)] },\n });\n }\n\n const dbQuery = strapi.get('query-params').transform(targetUid, queryParams);\n\n const res = await strapi.db.query(targetUid).findPage(dbQuery);\n\n ctx.body = {\n ...res,\n results: await addStatusToRelations(targetUid, res.results),\n };\n },\n\n async findExisting(ctx: any) {\n const { userAbility } = ctx.state;\n const { id } = ctx.params;\n\n await validateFindExisting(ctx.request.query);\n\n const {\n entryId,\n attribute,\n targetField,\n fieldsToSelect,\n status,\n source: { schema: sourceSchema },\n target: { schema: targetSchema },\n } = await this.extractAndValidateRequestInfo(ctx, id);\n\n const { uid: sourceUid } = sourceSchema;\n const { uid: targetUid } = targetSchema;\n\n const permissionQuery = await getService('permission-checker')\n .create({ userAbility, model: targetUid })\n .sanitizedQuery.read({ fields: fieldsToSelect });\n\n /**\n * loadPages can not be used for single relations,\n * this unifies the loading regardless of it's type\n *\n * NOTE: Relations need to be loaded using any db.query method\n * to ensure the proper ordering is applied\n */\n const dbQuery = strapi.db.query(sourceUid);\n const loadRelations = relations.isAnyToMany(attribute)\n ? (...args: Parameters<typeof dbQuery.loadPages>) => dbQuery.loadPages(...args)\n : (...args: Parameters<typeof dbQuery.load>) =>\n dbQuery\n .load(...args)\n // Ensure response is an array\n .then((res) => ({ results: res ? [res] : [] }));\n\n const filters: {\n publishedAt?: Record<string, any>;\n } = {};\n\n if (sourceSchema?.options?.draftAndPublish || sourceSchema?.modelType === 'component') {\n if (targetSchema?.options?.draftAndPublish) {\n if (status === 'published') {\n filters.publishedAt = { $notNull: true };\n } else {\n filters.publishedAt = { $null: true };\n }\n }\n } else if (targetSchema?.options?.draftAndPublish) {\n // NOTE: we must return the drafts as some targets might not have a published version yet\n filters.publishedAt = { $null: true };\n }\n\n const pageParams = {\n page: ctx.request.query.page,\n pageSize: ctx.request.query.pageSize,\n };\n\n const defaultPagination = (total: number) => ({ page: 1, pageCount: 1, pageSize: 10, total });\n\n /**\n * The permission query only carries row-level conditions when the user's read permission on\n * the target has conditions (e.g. \"only entries I created\"). Without them it only restricts\n * the fields, so a single load returns exactly what the two-step flow below would: the\n * relations of the page with the fields the user is allowed to read.\n */\n if (isEmpty(permissionQuery.filters)) {\n const { select } = strapi.get('query-params').transform(targetUid, permissionQuery);\n const permittedFields = Array.isArray(select) ? select : [];\n\n const res = await loadRelations({ id: entryId }, targetField, {\n select: uniq([...RELATION_BASE_FIELDS, ...permittedFields]),\n ordering: 'desc',\n ...pageParams,\n filters,\n });\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(res.results.length),\n results: await addStatusToRelations(targetUid, res.results),\n };\n\n return;\n }\n\n /**\n * If user does not have access to specific relations (custom conditions),\n * only the ids of the relations are returned.\n *\n * - First query loads all the ids.\n * - Second one also loads the main field, and excludes forbidden relations.\n *\n * The response contains the union of the two queries.\n */\n const res = await loadRelations({ id: entryId }, targetField, {\n select: RELATION_BASE_FIELDS,\n ordering: 'desc',\n ...pageParams,\n filters,\n });\n\n /**\n * Add all ids to load in permissionQuery\n * If any of the relations are not accessible, the permissionQuery will exclude them\n */\n const loadedIds = res.results.map((item: any) => item.id);\n addFiltersClause(permissionQuery, { id: { $in: loadedIds } });\n\n /**\n * Load the relations with the main field, the sanitized permission query\n * will exclude the relations the user does not have access to.\n *\n * Pagination is not necessary as the permissionQuery contains the ids to load.\n */\n const sanitizedRes = await loadRelations({ id: entryId }, targetField, {\n ...strapi.get('query-params').transform(targetUid, permissionQuery),\n ordering: 'desc',\n });\n\n // NOTE: the order is very important to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy(concat(sanitizedRes.results, res.results), 'id');\n\n ctx.body = {\n pagination: res.pagination || defaultPagination(relationsUnion.length),\n results: await addStatusToRelations(targetUid, relationsUnion),\n };\n },\n};\n"],"names":["PUBLISHED_AT_ATTRIBUTE","UPDATED_AT_ATTRIBUTE","contentTypes","constants","RELATION_BASE_FIELDS","addFiltersClause","params","filtersClause","filters","$and","push","sanitizeMainField","model","mainField","userAbility","permissionChecker","getService","create","uid","isMainFieldListable","isListable","canReadMainField","can","read","addStatusToRelations","targetUid","relations","hasDraftAndPublish","strapi","getModel","documentMetadata","length","firstRelation","documentId","$in","map","r","publishedAt","$null","$notNull","availableStatus","db","query","findMany","select","statusByDocumentId","indexByDocumentId","relation","candidates","get","availableStatuses","locale","filter","c","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isSourceLocalized","localization","isLocalizedContentType","isTargetLocalized","validateStatus","isDP","isSourceDP","modelType","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","cannot","ForbiddenError","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","findOne","NotFoundError","modelConfig","findConfiguration","targetSchema","flow","property","fieldsToSelect","Set","source","schema","isLocalized","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","search","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","sourcePublishedAt","isEmpty","published_at","$notIn","knexSubQuery","join","getKnexQuery","isOperatorOfType","_filter","dbQuery","transform","res","findPage","body","results","findExisting","validateFindExisting","loadRelations","isAnyToMany","args","loadPages","load","then","options","draftAndPublish","pageParams","page","pageSize","defaultPagination","total","pageCount","permittedFields","Array","isArray","uniq","ordering","pagination","loadedIds","item","sanitizedRes","relationsUnion","uniqBy","concat"],"mappings":"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"}
@@ -136,6 +136,10 @@ var singleTypes = {
136
136
  model
137
137
  });
138
138
  const document = await createOrUpdateDocument(ctx);
139
+ // The document can be deleted between the existence check and the update
140
+ if (document === null) {
141
+ return ctx.notFound();
142
+ }
139
143
  const sanitizedDocument = await permissionChecker.sanitizeOutput(document);
140
144
  ctx.body = await metadata.formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);
141
145
  },
@@ -214,7 +218,12 @@ var singleTypes = {
214
218
  const publishResult = await documentManager.publish(document.documentId, model, {
215
219
  locale
216
220
  });
217
- return publishResult.at(0);
221
+ const publishedVersion = publishResult.at(0);
222
+ // The draft can be deleted between the existence check and the publish
223
+ if (publishedVersion === undefined) {
224
+ throw new strapiUtils.errors.NotFoundError();
225
+ }
226
+ return publishedVersion;
218
227
  });
219
228
  const sanitizedDocument = await permissionChecker.sanitizeOutput(publishedDocument);
220
229
  ctx.body = await metadata.formatDocumentWithMetadata(permissionChecker, model, sanitizedDocument);