@strapi/content-manager 0.0.0-next.daa3d4c4db6322f58233f0ccb757d80dbd1b48e9 → 0.0.0-next.df0d99415fc543d9747f3946fd7d1a4c39052b95

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 (261) hide show
  1. package/dist/admin/components/ConfigurationForm/Fields.js +300 -204
  2. package/dist/admin/components/ConfigurationForm/Fields.js.map +1 -1
  3. package/dist/admin/components/ConfigurationForm/Fields.mjs +304 -209
  4. package/dist/admin/components/ConfigurationForm/Fields.mjs.map +1 -1
  5. package/dist/admin/components/LeftMenu.js +34 -30
  6. package/dist/admin/components/LeftMenu.js.map +1 -1
  7. package/dist/admin/components/LeftMenu.mjs +36 -32
  8. package/dist/admin/components/LeftMenu.mjs.map +1 -1
  9. package/dist/admin/components/Widgets.js +253 -0
  10. package/dist/admin/components/Widgets.js.map +1 -1
  11. package/dist/admin/components/Widgets.mjs +236 -3
  12. package/dist/admin/components/Widgets.mjs.map +1 -1
  13. package/dist/admin/history/components/VersionContent.js +24 -3
  14. package/dist/admin/history/components/VersionContent.js.map +1 -1
  15. package/dist/admin/history/components/VersionContent.mjs +25 -4
  16. package/dist/admin/history/components/VersionContent.mjs.map +1 -1
  17. package/dist/admin/history/components/VersionHeader.js +6 -0
  18. package/dist/admin/history/components/VersionHeader.js.map +1 -1
  19. package/dist/admin/history/components/VersionHeader.mjs +7 -1
  20. package/dist/admin/history/components/VersionHeader.mjs.map +1 -1
  21. package/dist/admin/hooks/useDocumentActions.js +7 -6
  22. package/dist/admin/hooks/useDocumentActions.js.map +1 -1
  23. package/dist/admin/hooks/useDocumentActions.mjs +8 -7
  24. package/dist/admin/hooks/useDocumentActions.mjs.map +1 -1
  25. package/dist/admin/index.js +47 -8
  26. package/dist/admin/index.js.map +1 -1
  27. package/dist/admin/index.mjs +47 -9
  28. package/dist/admin/index.mjs.map +1 -1
  29. package/dist/admin/layout.js +1 -27
  30. package/dist/admin/layout.js.map +1 -1
  31. package/dist/admin/layout.mjs +2 -9
  32. package/dist/admin/layout.mjs.map +1 -1
  33. package/dist/admin/pages/EditView/EditViewPage.js +99 -75
  34. package/dist/admin/pages/EditView/EditViewPage.js.map +1 -1
  35. package/dist/admin/pages/EditView/EditViewPage.mjs +101 -77
  36. package/dist/admin/pages/EditView/EditViewPage.mjs.map +1 -1
  37. package/dist/admin/pages/EditView/components/DocumentActions.js +83 -70
  38. package/dist/admin/pages/EditView/components/DocumentActions.js.map +1 -1
  39. package/dist/admin/pages/EditView/components/DocumentActions.mjs +85 -72
  40. package/dist/admin/pages/EditView/components/DocumentActions.mjs.map +1 -1
  41. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js +12 -15
  42. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.js.map +1 -1
  43. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs +12 -15
  44. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksContent.mjs.map +1 -1
  45. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js +54 -14
  46. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.js.map +1 -1
  47. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs +55 -15
  48. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksEditor.mjs.map +1 -1
  49. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js +21 -35
  50. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.js.map +1 -1
  51. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs +21 -35
  52. package/dist/admin/pages/EditView/components/FormInputs/BlocksInput/BlocksToolbar.mjs.map +1 -1
  53. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js +12 -1
  54. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.js.map +1 -1
  55. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs +13 -2
  56. package/dist/admin/pages/EditView/components/FormInputs/Component/NonRepeatable.mjs.map +1 -1
  57. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js +13 -2
  58. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.js.map +1 -1
  59. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs +14 -3
  60. package/dist/admin/pages/EditView/components/FormInputs/Component/Repeatable.mjs.map +1 -1
  61. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js +18 -5
  62. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.js.map +1 -1
  63. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs +20 -7
  64. package/dist/admin/pages/EditView/components/FormInputs/DynamicZone/DynamicComponent.mjs.map +1 -1
  65. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js +1 -0
  66. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.js.map +1 -1
  67. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs +1 -0
  68. package/dist/admin/pages/EditView/components/FormInputs/Relations/RelationModal.mjs.map +1 -1
  69. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +158 -106
  70. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
  71. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +161 -109
  72. package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
  73. package/dist/admin/pages/EditView/components/FormInputs/UID.js +4 -2
  74. package/dist/admin/pages/EditView/components/FormInputs/UID.js.map +1 -1
  75. package/dist/admin/pages/EditView/components/FormInputs/UID.mjs +4 -2
  76. package/dist/admin/pages/EditView/components/FormInputs/UID.mjs.map +1 -1
  77. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js +1 -1
  78. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.js.map +1 -1
  79. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.mjs +1 -1
  80. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/Editor.mjs.map +1 -1
  81. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js +86 -118
  82. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.js.map +1 -1
  83. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs +86 -118
  84. package/dist/admin/pages/EditView/components/FormInputs/Wysiwyg/WysiwygNav.mjs.map +1 -1
  85. package/dist/admin/pages/EditView/components/FormLayout.js +47 -27
  86. package/dist/admin/pages/EditView/components/FormLayout.js.map +1 -1
  87. package/dist/admin/pages/EditView/components/FormLayout.mjs +47 -27
  88. package/dist/admin/pages/EditView/components/FormLayout.mjs.map +1 -1
  89. package/dist/admin/pages/EditView/utils/data.js +103 -0
  90. package/dist/admin/pages/EditView/utils/data.js.map +1 -1
  91. package/dist/admin/pages/EditView/utils/data.mjs +103 -1
  92. package/dist/admin/pages/EditView/utils/data.mjs.map +1 -1
  93. package/dist/admin/pages/ListView/ListViewPage.js +227 -132
  94. package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
  95. package/dist/admin/pages/ListView/ListViewPage.mjs +229 -134
  96. package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
  97. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js +2 -1
  98. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.js.map +1 -1
  99. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs +2 -1
  100. package/dist/admin/pages/ListView/components/BulkActions/ConfirmBulkActionDialog.mjs.map +1 -1
  101. package/dist/admin/pages/ListView/components/Filters.js +4 -1
  102. package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
  103. package/dist/admin/pages/ListView/components/Filters.mjs +4 -1
  104. package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
  105. package/dist/admin/pages/ListView/components/TableActions.js +13 -3
  106. package/dist/admin/pages/ListView/components/TableActions.js.map +1 -1
  107. package/dist/admin/pages/ListView/components/TableActions.mjs +13 -3
  108. package/dist/admin/pages/ListView/components/TableActions.mjs.map +1 -1
  109. package/dist/admin/preview/components/PreviewSidePanel.js +31 -4
  110. package/dist/admin/preview/components/PreviewSidePanel.js.map +1 -1
  111. package/dist/admin/preview/components/PreviewSidePanel.mjs +32 -5
  112. package/dist/admin/preview/components/PreviewSidePanel.mjs.map +1 -1
  113. package/dist/admin/preview/pages/Preview.js +101 -35
  114. package/dist/admin/preview/pages/Preview.js.map +1 -1
  115. package/dist/admin/preview/pages/Preview.mjs +102 -36
  116. package/dist/admin/preview/pages/Preview.mjs.map +1 -1
  117. package/dist/admin/services/api.js +3 -1
  118. package/dist/admin/services/api.js.map +1 -1
  119. package/dist/admin/services/api.mjs +3 -1
  120. package/dist/admin/services/api.mjs.map +1 -1
  121. package/dist/admin/services/documents.js +32 -16
  122. package/dist/admin/services/documents.js.map +1 -1
  123. package/dist/admin/services/documents.mjs +32 -16
  124. package/dist/admin/services/documents.mjs.map +1 -1
  125. package/dist/admin/services/homepage.js +11 -2
  126. package/dist/admin/services/homepage.js.map +1 -1
  127. package/dist/admin/services/homepage.mjs +11 -3
  128. package/dist/admin/services/homepage.mjs.map +1 -1
  129. package/dist/admin/src/components/ConfigurationForm/Fields.d.ts +6 -4
  130. package/dist/admin/src/components/Widgets.d.ts +2 -1
  131. package/dist/admin/src/exports.d.ts +1 -0
  132. package/dist/admin/src/history/services/historyVersion.d.ts +1 -1
  133. package/dist/admin/src/hooks/useDocumentActions.d.ts +1 -0
  134. package/dist/admin/src/pages/EditView/components/FormInputs/UID.d.ts +1 -0
  135. package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +7 -8
  136. package/dist/admin/src/pages/EditView/utils/data.d.ts +19 -1
  137. package/dist/admin/src/preview/services/preview.d.ts +1 -1
  138. package/dist/admin/src/services/api.d.ts +1 -1
  139. package/dist/admin/src/services/components.d.ts +2 -2
  140. package/dist/admin/src/services/contentTypes.d.ts +3 -3
  141. package/dist/admin/src/services/documents.d.ts +23 -17
  142. package/dist/admin/src/services/homepage.d.ts +6 -2
  143. package/dist/admin/src/services/init.d.ts +1 -1
  144. package/dist/admin/src/services/relations.d.ts +2 -2
  145. package/dist/admin/src/services/uid.d.ts +3 -3
  146. package/dist/admin/src/utils/validation.d.ts +1 -0
  147. package/dist/admin/translations/en.json.js +7 -0
  148. package/dist/admin/translations/en.json.js.map +1 -1
  149. package/dist/admin/translations/en.json.mjs +7 -0
  150. package/dist/admin/translations/en.json.mjs.map +1 -1
  151. package/dist/admin/translations/es.json.js +5 -2
  152. package/dist/admin/translations/es.json.js.map +1 -1
  153. package/dist/admin/translations/es.json.mjs +5 -2
  154. package/dist/admin/translations/es.json.mjs.map +1 -1
  155. package/dist/admin/translations/fr.json.js +10 -2
  156. package/dist/admin/translations/fr.json.js.map +1 -1
  157. package/dist/admin/translations/fr.json.mjs +10 -2
  158. package/dist/admin/translations/fr.json.mjs.map +1 -1
  159. package/dist/admin/utils/validation.js +19 -7
  160. package/dist/admin/utils/validation.js.map +1 -1
  161. package/dist/admin/utils/validation.mjs +19 -7
  162. package/dist/admin/utils/validation.mjs.map +1 -1
  163. package/dist/server/controllers/content-types.js +11 -1
  164. package/dist/server/controllers/content-types.js.map +1 -1
  165. package/dist/server/controllers/content-types.mjs +11 -1
  166. package/dist/server/controllers/content-types.mjs.map +1 -1
  167. package/dist/server/controllers/relations.js +2 -2
  168. package/dist/server/controllers/relations.js.map +1 -1
  169. package/dist/server/controllers/relations.mjs +2 -2
  170. package/dist/server/controllers/relations.mjs.map +1 -1
  171. package/dist/server/controllers/validation/index.js +14 -2
  172. package/dist/server/controllers/validation/index.js.map +1 -1
  173. package/dist/server/controllers/validation/index.mjs +14 -2
  174. package/dist/server/controllers/validation/index.mjs.map +1 -1
  175. package/dist/server/history/services/lifecycles.js +23 -19
  176. package/dist/server/history/services/lifecycles.js.map +1 -1
  177. package/dist/server/history/services/lifecycles.mjs +23 -19
  178. package/dist/server/history/services/lifecycles.mjs.map +1 -1
  179. package/dist/server/homepage/controllers/homepage.js +5 -0
  180. package/dist/server/homepage/controllers/homepage.js.map +1 -1
  181. package/dist/server/homepage/controllers/homepage.mjs +5 -0
  182. package/dist/server/homepage/controllers/homepage.mjs.map +1 -1
  183. package/dist/server/homepage/routes/homepage.js +11 -0
  184. package/dist/server/homepage/routes/homepage.js.map +1 -1
  185. package/dist/server/homepage/routes/homepage.mjs +11 -0
  186. package/dist/server/homepage/routes/homepage.mjs.map +1 -1
  187. package/dist/server/homepage/services/homepage.js +86 -46
  188. package/dist/server/homepage/services/homepage.js.map +1 -1
  189. package/dist/server/homepage/services/homepage.mjs +86 -46
  190. package/dist/server/homepage/services/homepage.mjs.map +1 -1
  191. package/dist/server/preview/services/preview-config.js +5 -1
  192. package/dist/server/preview/services/preview-config.js.map +1 -1
  193. package/dist/server/preview/services/preview-config.mjs +5 -1
  194. package/dist/server/preview/services/preview-config.mjs.map +1 -1
  195. package/dist/server/preview/services/preview.js +4 -0
  196. package/dist/server/preview/services/preview.js.map +1 -1
  197. package/dist/server/preview/services/preview.mjs +4 -0
  198. package/dist/server/preview/services/preview.mjs.map +1 -1
  199. package/dist/server/services/data-mapper.js +4 -1
  200. package/dist/server/services/data-mapper.js.map +1 -1
  201. package/dist/server/services/data-mapper.mjs +4 -1
  202. package/dist/server/services/data-mapper.mjs.map +1 -1
  203. package/dist/server/services/document-manager.js +8 -1
  204. package/dist/server/services/document-manager.js.map +1 -1
  205. package/dist/server/services/document-manager.mjs +8 -1
  206. package/dist/server/services/document-manager.mjs.map +1 -1
  207. package/dist/server/services/document-metadata.js +3 -1
  208. package/dist/server/services/document-metadata.js.map +1 -1
  209. package/dist/server/services/document-metadata.mjs +3 -1
  210. package/dist/server/services/document-metadata.mjs.map +1 -1
  211. package/dist/server/services/utils/configuration/attributes.js +1 -1
  212. package/dist/server/services/utils/configuration/attributes.js.map +1 -1
  213. package/dist/server/services/utils/configuration/attributes.mjs +1 -1
  214. package/dist/server/services/utils/configuration/attributes.mjs.map +1 -1
  215. package/dist/server/services/utils/configuration/layouts.js +1 -1
  216. package/dist/server/services/utils/configuration/layouts.js.map +1 -1
  217. package/dist/server/services/utils/configuration/layouts.mjs +1 -1
  218. package/dist/server/services/utils/configuration/layouts.mjs.map +1 -1
  219. package/dist/server/services/utils/configuration/metadatas.js +8 -0
  220. package/dist/server/services/utils/configuration/metadatas.js.map +1 -1
  221. package/dist/server/services/utils/configuration/metadatas.mjs +8 -0
  222. package/dist/server/services/utils/configuration/metadatas.mjs.map +1 -1
  223. package/dist/server/services/utils/populate.js +11 -0
  224. package/dist/server/services/utils/populate.js.map +1 -1
  225. package/dist/server/services/utils/populate.mjs +11 -0
  226. package/dist/server/services/utils/populate.mjs.map +1 -1
  227. package/dist/server/src/controllers/content-types.d.ts.map +1 -1
  228. package/dist/server/src/controllers/validation/index.d.ts +6 -1
  229. package/dist/server/src/controllers/validation/index.d.ts.map +1 -1
  230. package/dist/server/src/history/services/lifecycles.d.ts.map +1 -1
  231. package/dist/server/src/homepage/controllers/homepage.d.ts +2 -1
  232. package/dist/server/src/homepage/controllers/homepage.d.ts.map +1 -1
  233. package/dist/server/src/homepage/index.d.ts +7 -0
  234. package/dist/server/src/homepage/index.d.ts.map +1 -1
  235. package/dist/server/src/homepage/routes/homepage.d.ts.map +1 -1
  236. package/dist/server/src/homepage/services/homepage.d.ts +4 -1
  237. package/dist/server/src/homepage/services/homepage.d.ts.map +1 -1
  238. package/dist/server/src/homepage/services/index.d.ts +7 -0
  239. package/dist/server/src/homepage/services/index.d.ts.map +1 -1
  240. package/dist/server/src/index.d.ts +8 -0
  241. package/dist/server/src/index.d.ts.map +1 -1
  242. package/dist/server/src/preview/services/index.d.ts +1 -0
  243. package/dist/server/src/preview/services/index.d.ts.map +1 -1
  244. package/dist/server/src/preview/services/preview-config.d.ts +1 -0
  245. package/dist/server/src/preview/services/preview-config.d.ts.map +1 -1
  246. package/dist/server/src/preview/services/preview.d.ts.map +1 -1
  247. package/dist/server/src/preview/utils.d.ts +1 -0
  248. package/dist/server/src/preview/utils.d.ts.map +1 -1
  249. package/dist/server/src/services/data-mapper.d.ts +1 -0
  250. package/dist/server/src/services/data-mapper.d.ts.map +1 -1
  251. package/dist/server/src/services/document-manager.d.ts.map +1 -1
  252. package/dist/server/src/services/document-metadata.d.ts.map +1 -1
  253. package/dist/server/src/services/index.d.ts +8 -0
  254. package/dist/server/src/services/index.d.ts.map +1 -1
  255. package/dist/server/src/services/utils/configuration/metadatas.d.ts.map +1 -1
  256. package/dist/server/src/services/utils/populate.d.ts.map +1 -1
  257. package/dist/shared/contracts/collection-types.d.ts +0 -1
  258. package/dist/shared/contracts/collection-types.d.ts.map +1 -1
  259. package/dist/shared/contracts/homepage.d.ts +13 -0
  260. package/dist/shared/contracts/homepage.d.ts.map +1 -1
  261. package/package.json +11 -9
@@ -1 +1 @@
1
- {"version":3,"file":"content-types.mjs","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { has, assoc, mapValues, prop } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { createModelConfigurationSchema, validateKind } from './validation';\n\nconst hasEditMainField = has('edit.mainField');\nconst getEditMainField = prop('edit.mainField');\nconst assocListMainField = assoc('list.mainField');\n\nconst assocMainField = (metadata: any) =>\n hasEditMainField(metadata) ? assocListMainField(getEditMainField(metadata), metadata) : metadata;\n\nexport default {\n async findContentTypes(ctx: any) {\n const { kind } = ctx.query;\n\n try {\n await validateKind(kind);\n } catch (error) {\n return ctx.send({ error }, 400);\n }\n\n const contentTypes = getService('content-types').findContentTypesByKind(kind);\n const { toDto } = getService('data-mapper');\n\n ctx.body = { data: contentTypes.map(toDto) };\n },\n\n async findContentTypesSettings(ctx: any) {\n const { findAllContentTypes, findConfiguration } = getService('content-types');\n\n const contentTypes = await findAllContentTypes();\n const configurations = await Promise.all(\n contentTypes.map(async (contentType: any) => {\n const { uid, settings } = await findConfiguration(contentType);\n return { uid, settings };\n })\n );\n\n ctx.body = {\n data: configurations,\n };\n },\n\n async findContentTypeConfiguration(ctx: any) {\n const { uid } = ctx.params;\n\n const contentTypeService = getService('content-types');\n\n const contentType = await contentTypeService.findContentType(uid);\n\n if (!contentType) {\n return ctx.notFound('contentType.notFound');\n }\n\n const configuration = await contentTypeService.findConfiguration(contentType);\n\n const confWithUpdatedMetadata = {\n ...configuration,\n metadatas: mapValues(assocMainField, configuration.metadatas),\n };\n\n const components = await contentTypeService.findComponentsConfigurations(contentType);\n\n ctx.body = {\n data: {\n contentType: confWithUpdatedMetadata,\n components,\n },\n };\n },\n\n async updateContentTypeConfiguration(ctx: any) {\n const { userAbility } = ctx.state;\n const { uid } = ctx.params;\n const { body } = ctx.request;\n\n const contentTypeService = getService('content-types');\n const metricsService = getService('metrics');\n\n const contentType = await contentTypeService.findContentType(uid);\n\n if (!contentType) {\n return ctx.notFound('contentType.notFound');\n }\n\n if (!getService('permission').canConfigureContentType({ userAbility, contentType })) {\n return ctx.forbidden();\n }\n\n let input;\n try {\n input = await createModelConfigurationSchema(contentType).validate(body, {\n abortEarly: false,\n stripUnknown: true,\n strict: true,\n });\n } catch (error: any) {\n return ctx.badRequest(null, {\n name: 'validationError',\n errors: error.errors,\n });\n }\n\n const newConfiguration = await contentTypeService.updateConfiguration(contentType, input);\n\n await metricsService.sendDidConfigureListView(contentType, newConfiguration);\n\n const confWithUpdatedMetadata = {\n ...newConfiguration,\n metadatas: mapValues(assocMainField, newConfiguration.metadatas),\n };\n\n const components = await contentTypeService.findComponentsConfigurations(contentType);\n\n ctx.body = {\n data: {\n contentType: confWithUpdatedMetadata,\n components,\n },\n };\n },\n};\n"],"names":["hasEditMainField","has","getEditMainField","prop","assocListMainField","assoc","assocMainField","metadata","findContentTypes","ctx","kind","query","validateKind","error","send","contentTypes","getService","findContentTypesByKind","toDto","body","data","map","findContentTypesSettings","findAllContentTypes","findConfiguration","configurations","Promise","all","contentType","uid","settings","findContentTypeConfiguration","params","contentTypeService","findContentType","notFound","configuration","confWithUpdatedMetadata","metadatas","mapValues","components","findComponentsConfigurations","updateContentTypeConfiguration","userAbility","state","request","metricsService","canConfigureContentType","forbidden","input","createModelConfigurationSchema","validate","abortEarly","stripUnknown","strict","badRequest","name","errors","newConfiguration","updateConfiguration","sendDidConfigureListView"],"mappings":"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"}
1
+ {"version":3,"file":"content-types.mjs","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { has, assoc, mapValues, prop } from 'lodash/fp';\nimport { getService } from '../utils';\nimport { createModelConfigurationSchema, validateKind } from './validation';\n\nconst hasEditMainField = has('edit.mainField');\nconst getEditMainField = prop('edit.mainField');\nconst assocListMainField = assoc('list.mainField');\n\nconst assocMainField = (metadata: any) =>\n hasEditMainField(metadata) ? assocListMainField(getEditMainField(metadata), metadata) : metadata;\n\nexport default {\n async findContentTypes(ctx: any) {\n const { kind } = ctx.query;\n\n try {\n await validateKind(kind);\n } catch (error) {\n return ctx.send({ error }, 400);\n }\n\n const contentTypes = getService('content-types').findContentTypesByKind(kind);\n const { toDto } = getService('data-mapper');\n\n ctx.body = { data: contentTypes.map(toDto) };\n },\n\n async findContentTypesSettings(ctx: any) {\n const { findAllContentTypes, findConfiguration } = getService('content-types');\n\n const contentTypes = await findAllContentTypes();\n const configurations = await Promise.all(\n contentTypes.map(async (contentType: any) => {\n const { uid, settings } = await findConfiguration(contentType);\n return { uid, settings };\n })\n );\n\n ctx.body = {\n data: configurations,\n };\n },\n\n async findContentTypeConfiguration(ctx: any) {\n const { uid } = ctx.params;\n\n const contentTypeService = getService('content-types');\n\n const contentType = await contentTypeService.findContentType(uid);\n\n if (!contentType) {\n return ctx.notFound('contentType.notFound');\n }\n\n const configuration = await contentTypeService.findConfiguration(contentType);\n\n const confWithUpdatedMetadata = {\n ...configuration,\n metadatas: {\n ...mapValues(assocMainField, configuration.metadatas),\n documentId: {\n edit: {},\n list: {\n label: 'documentId',\n searchable: true,\n sortable: true,\n },\n },\n },\n };\n\n const components = await contentTypeService.findComponentsConfigurations(contentType);\n\n ctx.body = {\n data: {\n contentType: confWithUpdatedMetadata,\n components,\n },\n };\n },\n\n async updateContentTypeConfiguration(ctx: any) {\n const { userAbility } = ctx.state;\n const { uid } = ctx.params;\n const { body } = ctx.request;\n\n const contentTypeService = getService('content-types');\n const metricsService = getService('metrics');\n\n const contentType = await contentTypeService.findContentType(uid);\n\n if (!contentType) {\n return ctx.notFound('contentType.notFound');\n }\n\n if (!getService('permission').canConfigureContentType({ userAbility, contentType })) {\n return ctx.forbidden();\n }\n\n let input;\n try {\n input = await createModelConfigurationSchema(contentType).validate(body, {\n abortEarly: false,\n stripUnknown: true,\n strict: true,\n });\n } catch (error: any) {\n return ctx.badRequest(null, {\n name: 'validationError',\n errors: error.errors,\n });\n }\n\n const newConfiguration = await contentTypeService.updateConfiguration(contentType, input);\n\n await metricsService.sendDidConfigureListView(contentType, newConfiguration);\n\n const confWithUpdatedMetadata = {\n ...newConfiguration,\n metadatas: mapValues(assocMainField, newConfiguration.metadatas),\n };\n\n const components = await contentTypeService.findComponentsConfigurations(contentType);\n\n ctx.body = {\n data: {\n contentType: confWithUpdatedMetadata,\n components,\n },\n };\n },\n};\n"],"names":["hasEditMainField","has","getEditMainField","prop","assocListMainField","assoc","assocMainField","metadata","findContentTypes","ctx","kind","query","validateKind","error","send","contentTypes","getService","findContentTypesByKind","toDto","body","data","map","findContentTypesSettings","findAllContentTypes","findConfiguration","configurations","Promise","all","contentType","uid","settings","findContentTypeConfiguration","params","contentTypeService","findContentType","notFound","configuration","confWithUpdatedMetadata","metadatas","mapValues","documentId","edit","list","label","searchable","sortable","components","findComponentsConfigurations","updateContentTypeConfiguration","userAbility","state","request","metricsService","canConfigureContentType","forbidden","input","createModelConfigurationSchema","validate","abortEarly","stripUnknown","strict","badRequest","name","errors","newConfiguration","updateConfiguration","sendDidConfigureListView"],"mappings":"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"}
@@ -22,8 +22,8 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
22
22
  // Whether the user has the permission to access the model's main field (using RBAC abilities)
23
23
  const canReadMainField = permissionChecker.can.read(null, mainField);
24
24
  if (!isMainFieldListable || !canReadMainField) {
25
- // Default to 'id' if the actual main field shouldn't be displayed
26
- return 'id';
25
+ // Default to 'documentId' if the actual main field shouldn't be displayed
26
+ return 'documentId';
27
27
  }
28
28
  // Edge cases
29
29
  // 1. Enforce 'name' as the main field for users and permissions' roles
@@ -1 +1 @@
1
- {"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\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';\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 'id' if the actual main field shouldn't be displayed\n return 'id';\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 return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\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 const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(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) return { status: undefined };\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 prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n '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 { idsToOmit, idsToInclude, _q, ...query } = 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 } 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 (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\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: uniq(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) {\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 import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\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","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","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":";;;;;;;;AASA,MAAM,EAAEA,sBAAsB,EAAEC,oBAAoB,EAAE,GAAGC,yBAAaC,SAAS;AAU/E,MAAMC,gBAAAA,GAAmB,CAACC,MAAaC,EAAAA,aAAAA,GAAAA;AACrCD,IAAAA,MAAAA,CAAOE,OAAO,GAAGF,MAAOE,CAAAA,OAAO,IAAI,EAAC;IACpCF,MAAOE,CAAAA,OAAO,CAACC,IAAI,GAAGH,OAAOE,OAAO,CAACC,IAAI,IAAI,EAAE;AAC/CH,IAAAA,MAAAA,CAAOE,OAAO,CAACC,IAAI,CAACC,IAAI,CAACH,aAAAA,CAAAA;AAC3B,CAAA;AAEA,MAAMI,iBAAAA,GAAoB,CAACC,KAAAA,EAAYC,SAAgBC,EAAAA,WAAAA,GAAAA;AACrD,IAAA,MAAMC,iBAAoBC,GAAAA,gBAAAA,CAAW,oBAAsBC,CAAAA,CAAAA,MAAM,CAAC;AAChEH,QAAAA,WAAAA;AACAF,QAAAA,KAAAA,EAAOA,MAAMM;AACf,KAAA,CAAA;;IAGA,MAAMC,mBAAAA,GAAsBC,sBAAWR,KAAOC,EAAAA,SAAAA,CAAAA;;AAE9C,IAAA,MAAMQ,mBAAmBN,iBAAkBO,CAAAA,GAAG,CAACC,IAAI,CAAC,IAAMV,EAAAA,SAAAA,CAAAA;IAE1D,IAAI,CAACM,mBAAuB,IAAA,CAACE,gBAAkB,EAAA;;QAE7C,OAAO,IAAA;AACT;;;IAKA,IAAIT,KAAAA,CAAMM,GAAG,KAAK,gCAAkC,EAAA;QAClD,OAAO,MAAA;AACT;IAEA,OAAOL,SAAAA;AACT,CAAA;AAEA;;;IAIA,MAAMW,oBAAuB,GAAA,OAAOC,SAAuBC,EAAAA,SAAAA,GAAAA;AACzD,IAAA,IAAI,CAACvB,wBAAawB,CAAAA,kBAAkB,CAACC,MAAOC,CAAAA,QAAQ,CAACJ,SAAa,CAAA,CAAA,EAAA;QAChE,OAAOC,SAAAA;AACT;AAEA,IAAA,MAAMI,mBAAmBd,gBAAW,CAAA,mBAAA,CAAA;IAEpC,IAAI,CAACU,SAAUK,CAAAA,MAAM,EAAE;QACrB,OAAOL,SAAAA;AACT;IAEA,MAAMM,aAAAA,GAAgBN,SAAS,CAAC,CAAE,CAAA;AAElC,IAAA,MAAMlB,OAAe,GAAA;QACnByB,UAAY,EAAA;AAAEC,YAAAA,GAAAA,EAAKR,UAAUS,GAAG,CAAC,CAACC,CAAAA,GAAMA,EAAEH,UAAU;AAAE,SAAA;;QAEtDI,WAAaL,EAAAA,aAAAA,CAAcK,WAAW,KAAK,IAAO,GAAA;YAAEC,KAAO,EAAA;SAAS,GAAA;YAAEC,QAAU,EAAA;AAAK;AACvF,KAAA;AAEA,IAAA,MAAMC,kBAAkB,MAAMZ,MAAAA,CAAOa,KAAK,CAAChB,SAAAA,CAAAA,CAAWiB,QAAQ,CAAC;QAC7DC,MAAQ,EAAA;AAAC,YAAA,IAAA;AAAM,YAAA,YAAA;AAAc,YAAA,QAAA;AAAU,YAAA,WAAA;AAAa,YAAA,WAAA;AAAa,YAAA;AAAc,SAAA;AAC/EnC,QAAAA;AACF,KAAA,CAAA;IAEA,OAAOkB,SAAAA,CAAUS,GAAG,CAAC,CAACS,QAAAA,GAAAA;QACpB,MAAMC,iBAAAA,GAAoBL,gBAAgBM,MAAM,CAC9C,CAACC,iBACCA,GAAAA,iBAAAA,CAAkBd,UAAU,KAAKW,QAASX,CAAAA,UAAU,KACnDW,QAAAA,CAASI,MAAM,GAAGD,iBAAAA,CAAkBC,MAAM,KAAKJ,QAAAA,CAASI,MAAM,GAAG,IAAG,CAAA,CAAA;QAGzE,OAAO;AACL,YAAA,GAAGJ,QAAQ;YACXK,MAAQnB,EAAAA,gBAAAA,CAAiBoB,SAAS,CAACN,QAAUC,EAAAA,iBAAAA;AAC/C,SAAA;AACF,KAAA,CAAA;AACF,CAAA;AAEA,MAAMM,oBAAAA,GAAuB,CAACF,MAAgB/B,EAAAA,GAAAA,GAAAA;IAC5C,MAAMN,KAAAA,GAAQgB,MAAOC,CAAAA,QAAQ,CAACX,GAAAA,CAAAA;AAE9B;;AAEC,MACD,IAAI,CAACN,KAAAA,IAAS,CAACT,wBAAawB,CAAAA,kBAAkB,CAACf,KAAQ,CAAA,EAAA;AACrD,QAAA,OAAO,EAAC;AACV;;AAGA,IAAA,OAAOqC,WAAW,WAAc,GAAA;QAAEV,QAAU,EAAA;KAAS,GAAA;QAAED,KAAO,EAAA;AAAK,KAAA;AACrE,CAAA;AAEA,MAAMc,cAAAA,GAAiB,CAACC,SAAAA,EAAuB5B,SAA4BuB,EAAAA,MAAAA,GAAAA;IACzE,MAAMM,WAAAA,GAAc1B,MAAOC,CAAAA,QAAQ,CAACwB,SAAAA,CAAAA;IACpC,MAAME,WAAAA,GAAc3B,MAAOC,CAAAA,QAAQ,CAACJ,SAAAA,CAAAA;IAEpC,MAAM+B,WAAAA,GAAc5B,OAAO6B,MAAM,CAAC,QAAQC,OAAO,CAAC,iBAAiBC,sBAAsB;AACzF,IAAA,MAAMC,oBAAoBJ,WAAYF,CAAAA,WAAAA,CAAAA;AACtC,IAAA,MAAMO,oBAAoBL,WAAYD,CAAAA,WAAAA,CAAAA;IAEtC,OAAO;AACLP,QAAAA,MAAAA;AACAY,QAAAA,iBAAAA;AACAC,QAAAA;AACF,KAAA;AACF,CAAA;AAEA,MAAMC,cAAAA,GAAiB,CACrBT,SACAJ,EAAAA,MAAAA,GAAAA;IAEA,MAAMK,WAAAA,GAAc1B,MAAOC,CAAAA,QAAQ,CAACwB,SAAAA,CAAAA;IAEpC,MAAMU,IAAAA,GAAO5D,yBAAawB,kBAAkB;AAC5C,IAAA,MAAMqC,aAAaD,IAAKT,CAAAA,WAAAA,CAAAA;;IAGxB,IAAI,CAACU,YAAY,OAAO;QAAEf,MAAQgB,EAAAA;AAAU,KAAA;IAE5C,OAAQhB,MAAAA;QACN,KAAK,WAAA;YACH,OAAO;gBAAEA,MAAQ,EAAA;AAAY,aAAA;AAC/B,QAAA;;YAEE,OAAO;gBAAEA,MAAQ,EAAA;AAAQ,aAAA;AAC7B;AACF,CAAA;AAEA,gBAAe;IACb,MAAMiB,6BAAAA,CAAAA,CAA8BC,GAAQ,EAAEC,EAAY,EAAA;AACxD,QAAA,MAAM,EAAEtD,WAAW,EAAE,GAAGqD,IAAIE,KAAK;AACjC,QAAA,MAAM,EAAEzD,KAAK,EAAE0D,WAAW,EAAE,GAAGH,IAAI7D,MAAM;QAEzC,MAAMiE,YAAAA,GAAe3C,MAAOC,CAAAA,QAAQ,CAACjB,KAAAA,CAAAA;AACrC,QAAA,IAAI,CAAC2D,YAAc,EAAA;YACjB,MAAM,IAAIC,mBAAOC,eAAe,CAAC,CAAC,UAAU,EAAE7D,KAAM,CAAA,cAAc,CAAC,CAAA;AACrE;AAEA,QAAA,MAAM8D,SAAiBH,GAAAA,YAAAA,CAAaI,UAAU,CAACL,WAAY,CAAA;AAC3D,QAAA,IAAI,CAACI,SAAAA,IAAaA,SAAUE,CAAAA,IAAI,KAAK,UAAY,EAAA;YAC/C,MAAM,IAAIJ,kBAAOC,CAAAA,eAAe,CAC9B,CAAC,qBAAqB,EAAEH,WAAY,CAAA,kBAAkB,EAAE1D,KAAAA,CAAM,CAAC,CAAA;AAEnE;AAEA,QAAA,MAAMyC,SAAYzC,GAAAA,KAAAA;QAClB,MAAMa,SAAAA,GAAYiD,UAAUG,MAAM;AAElC,QAAA,MAAM,EAAE7B,MAAM,EAAEY,iBAAiB,EAAEC,iBAAiB,EAAE,GAAGT,cAAAA,CACvDC,SACA5B,EAAAA,SAAAA,EACA0C,GAAIW,CAAAA,OAAO,EAAErC,KAAOO,EAAAA,MAAAA,CAAAA;QAEtB,MAAM,EAAEC,MAAM,EAAE,GAAGa,eAAeT,SAAWc,EAAAA,GAAAA,CAAIW,OAAO,EAAErC,KAAOQ,EAAAA,MAAAA,CAAAA;AAEjE,QAAA,MAAMlC,iBAAoBC,GAAAA,gBAAAA,CAAW,oBAAsBC,CAAAA,CAAAA,MAAM,CAAC;AAChEH,YAAAA,WAAAA;AACAF,YAAAA;AACF,SAAA,CAAA;QAEA,MAAMmE,WAAAA,GAAcR,YAAaS,CAAAA,SAAS,KAAK,WAAA;AAC/C,QAAA,IAAI,CAACD,WAAa,EAAA;AAChB,YAAA,IAAIhE,kBAAkBkE,MAAM,CAAC1D,IAAI,CAAC,MAAM+C,WAAc,CAAA,EAAA;AACpD,gBAAA,OAAOH,IAAIe,SAAS,EAAA;AACtB;AACF;AAEA,QAAA,IAAIC,OAAkC,GAAA,IAAA;AAEtC,QAAA,IAAIf,EAAI,EAAA;AACN,YAAA,MAAMgB,QAA6B,EAAC;AAEpC,YAAA,IAAI,CAACL,WAAa,EAAA;AAChBK,gBAAAA,KAAAA,CAAMnD,UAAU,GAAGmC,EAAAA;AAEnB,gBAAA,IAAInB,MAAQ,EAAA;oBACVmC,KAAM/C,CAAAA,WAAW,GAAGc,oBAAAA,CAAqBF,MAAQI,EAAAA,SAAAA,CAAAA;AACnD;AAEA,gBAAA,IAAIL,UAAUY,iBAAmB,EAAA;AAC/BwB,oBAAAA,KAAAA,CAAMpC,MAAM,GAAGA,MAAAA;AACjB;aACK,MAAA;;;AAGLoC,gBAAAA,KAAAA,CAAMhB,EAAE,GAAGA,EAAAA;AACb;YAEA,MAAMiB,eAAAA,GAAkB,MAAMtE,iBAAkBuE,CAAAA,cAAc,CAAC/D,IAAI,CAAC4C,IAAI1B,KAAK,CAAA;YAC7E,MAAM8C,QAAAA,GAAW,MAAMvE,gBAAW,CAAA,kBAAA,CAAA,CAAoBJ,OACnD4E,iBAAiB,CAACH,iBAClBI,KAAK,EAAA;YAER,MAAMC,aAAAA,GAAgB,MAAM9D,MAAO+D,CAAAA,EAAE,CAAClD,KAAK,CAAC7B,KAAOgF,CAAAA,CAAAA,OAAO,CAAC;AACzDR,gBAAAA,KAAAA;AACAG,gBAAAA;AACF,aAAA,CAAA;;;;;AAMA,YAAA,IAAI,CAACG,aAAe,EAAA;gBAClB,MAAM,IAAIlB,mBAAOqB,aAAa,EAAA;AAChC;AAEA,YAAA,IAAI,CAACd,WAAa,EAAA;AAChB,gBAAA,IAAIhE,kBAAkBkE,MAAM,CAAC1D,IAAI,CAACmE,eAAepB,WAAc,CAAA,EAAA;oBAC7D,MAAM,IAAIE,mBAAOsB,cAAc,EAAA;AACjC;AACF;AAEAX,YAAAA,OAAAA,GAAUO,cAActB,EAAE;AAC5B;AAEA,QAAA,MAAM2B,WAAchB,GAAAA,WAAAA,GAChB,MAAM/D,gBAAAA,CAAW,YAAcgF,CAAAA,CAAAA,iBAAiB,CAACzB,YAAAA,CAAAA,GACjD,MAAMvD,gBAAAA,CAAW,eAAiBgF,CAAAA,CAAAA,iBAAiB,CAACzB,YAAAA,CAAAA;QAExD,MAAM0B,YAAAA,GAAerE,MAAOC,CAAAA,QAAQ,CAACJ,SAAAA,CAAAA;AAErC,QAAA,MAAMZ,YAAYqF,OAChBC,CAAAA,OAAAA,CAAK,CAAC,UAAU,EAAE7B,YAAY,eAAe,CAAC,GAC9C,CAACzD,SAAAA,GAAcA,aAAa,IAC5B,EAAA,CAACA,YAAcF,iBAAkBsF,CAAAA,YAAAA,EAAcpF,WAAWC,WAC1DiF,CAAAA,CAAAA,CAAAA,WAAAA,CAAAA;AAEF,QAAA,MAAMK,iBAAiBC,OAAK,CAAA;AAC1BxF,YAAAA,SAAAA;AACAZ,YAAAA,sBAAAA;AACAC,YAAAA,oBAAAA;AACA,YAAA;AACD,SAAA,CAAA;AAED,QAAA,IAAI2D,iBAAmB,EAAA;AACrBuC,YAAAA,cAAAA,CAAe1F,IAAI,CAAC,QAAA,CAAA;AACtB;QAEA,OAAO;AACLyE,YAAAA,OAAAA;AACAnC,YAAAA,MAAAA;AACAC,YAAAA,MAAAA;AACAyB,YAAAA,SAAAA;AACA0B,YAAAA,cAAAA;AACAvF,YAAAA,SAAAA;YACAyF,MAAQ,EAAA;gBAAEC,MAAQhC,EAAAA,YAAAA;gBAAcf,WAAaI,EAAAA;AAAkB,aAAA;YAC/DiB,MAAQ,EAAA;gBAAE0B,MAAQN,EAAAA,YAAAA;gBAAczC,WAAaK,EAAAA;AAAkB,aAAA;AAC/DU,YAAAA,YAAAA;AACA0B,YAAAA,YAAAA;AACA3B,YAAAA;AACF,SAAA;AACF,KAAA;AAEA;;;;MAKA,MAAMkC,eAAcrC,GAAQ,EAAA;AAC1B,QAAA,MAAM,EAAEC,EAAE,EAAE,GAAGD,GAAIW,CAAAA,OAAO,CAACrC,KAAK;AAEhC,QAAA,MAAMgE,iCAAsBtC,CAAAA,GAAAA,CAAIW,OAAO,CAACrC,KAAK,CAAA;QAE7C,MAAM,EACJO,MAAM,EACNC,MAAM,EACNqB,WAAW,EACX8B,cAAc,EACdvF,SAAS,EACTyF,MAAQ,EAAA,EACNC,QAAQ,EAAErF,GAAAA,EAAKmC,SAAS,EAAE2B,SAAAA,EAAW0B,eAAe,EAAE,EACtDlD,aAAaI,iBAAiB,EAC/B,EACDiB,MAAQ,EAAA,EACN0B,QAAQ,EAAErF,GAAAA,EAAKO,SAAS,EAAE,EAC1B+B,aAAaK,iBAAiB,EAC/B,EACF,GAAG,MAAM,IAAI,CAACK,6BAA6B,CAACC,GAAKC,EAAAA,EAAAA,CAAAA;AAElD,QAAA,MAAM,EAAEuC,SAAS,EAAEC,YAAY,EAAEC,EAAE,EAAE,GAAGpE,KAAO,EAAA,GAAG0B,GAAIW,CAAAA,OAAO,CAACrC,KAAK;AAEnE,QAAA,MAAM1B,iBAAoBC,GAAAA,gBAAAA,CAAW,oBAAsBC,CAAAA,CAAAA,MAAM,CAAC;YAChEH,WAAaqD,EAAAA,GAAAA,CAAIE,KAAK,CAACvD,WAAW;YAClCF,KAAOa,EAAAA;AACT,SAAA,CAAA;AACA,QAAA,MAAM4D,kBAAkB,MAAMtE,iBAAAA,CAAkBuE,cAAc,CAAC/D,IAAI,CAACkB,KAAAA,CAAAA;AAEpE,QAAA,MAAMqE,WAAc,GAAA;YAClBC,IAAMlG,EAAAA,SAAAA;;YAENmG,MAAQZ,EAAAA,cAAAA;AACR,YAAA,GAAGf;AACL,SAAA;;;AAIAhF,QAAAA,gBAAAA,CAAiByG,WAAa,EAAA;AAC5BzE,YAAAA,WAAAA,EAAac,qBAAqBF,MAAQxB,EAAAA,SAAAA;AAC5C,SAAA,CAAA;;AAGA,QAAA,MAAMwF,iBAAiBpD,iBAAqBb,IAAAA,MAAAA;AAC5C,QAAA,IAAIiE,cAAgB,EAAA;AAClB5G,YAAAA,gBAAAA,CAAiByG,WAAa,EAAA;AAAE9D,gBAAAA;AAAO,aAAA,CAAA;AACzC;AAEA,QAAA,IAAIoB,EAAI,EAAA;AACN;;;;;AAKC,UACD,MAAM8C,QAAWtF,GAAAA,MAAAA,CAAO+D,EAAE,CAACwB,YAAY,CAAC9D,SAAAA,CAAAA;;YAGxC,MAAM+D,KAAAA,GAAQF,SAASG,QAAQ,EAAA;AAE/B,YAAA,MAAMjC,KAA6B,GAAA;AACjC,gBAAA,CAAC,CAAC,EAAEgC,KAAAA,CAAM,GAAG,CAAC,GAAG;oBAAE7E,QAAU,EAAA;AAAK,iBAAA;AAClC,gBAAA,CAAC,CAAC,EAAE6E,KAAAA,CAAM,YAAY,CAAC,GAAG;oBAAE7E,QAAU,EAAA;AAAK;AAC7C,aAAA;AAEA;;;UAIA,IAAImE,oBAAoB,aAAe,EAAA;AACrCtB,gBAAAA,KAAAA,CAAMkC,WAAW,GAAGlD,EAAAA;aACf,MAAA;AACLgB,gBAAAA,KAAAA,CAAMhB,EAAE,GAAGA,EAAAA;AACb;;YAGA,MAAM/B,WAAAA,GAAcc,qBAAqBF,MAAQxB,EAAAA,SAAAA,CAAAA;YACjD,IAAI,CAAC8F,WAAQlF,WAAc,CAAA,EAAA;AACzB+C,gBAAAA,KAAK,CAAC,CAAC,EAAEgC,MAAM,aAAa,CAAC,CAAC,GAAG/E,WAAAA;AACnC;;AAGA,YAAA,IAAIwB,qBAAqBb,MAAQ,EAAA;AAC/BoC,gBAAAA,KAAK,CAAC,CAAC,EAAEgC,MAAM,OAAO,CAAC,CAAC,GAAGpE,MAAAA;AAC7B;AAEA,YAAA,IAAIY,qBAAqBZ,MAAQ,EAAA;AAC/BoC,gBAAAA,KAAAA,CAAMpC,MAAM,GAAGA,MAAAA;AACjB;AAEA;;;;AAIC,UACD,IAAI,CAAC4D,cAAc7E,MAAU,IAAA,CAAA,MAAO,CAAG,EAAA;gBACrCqD,KAAK,CAAC,CAAC,EAAEgC,KAAAA,CAAM,GAAG,CAAC,CAAC,CAACI,MAAM,GAAGZ,YAAAA;AAChC;AAEA,YAAA,MAAMa,eAAeP,QAClB9B,CAAAA,KAAK,CAACA,KAAAA,CAAAA,CACNsC,IAAI,CAAC;AAAEN,gBAAAA,KAAAA;AAAO9C,gBAAAA;aACd3B,CAAAA,CAAAA,MAAM,CAAC,CAAC,EAAEyE,MAAM,GAAG,CAAC,EACpBO,YAAY,EAAA;AAEftH,YAAAA,gBAAAA,CAAiByG,WAAa,EAAA;gBAC5B1C,EAAI,EAAA;oBAAEoD,MAAQC,EAAAA;AAAa;AAC7B,aAAA,CAAA;AACF;AAEA;;;AAGC,QACD,IAAIZ,EAAI,EAAA;YACN,MAAMe,OAAAA,GAAUC,6BAAiB,OAASpF,EAAAA,KAAAA,CAAMmF,OAAO,CAAInF,GAAAA,KAAAA,CAAMmF,OAAO,GAAG,YAAA;AAC3EvH,YAAAA,gBAAAA,CAAiByG,WAAa,EAAA;AAAE,gBAAA,CAACjG,YAAY;AAAE,oBAAA,CAAC+G,UAAUf;AAAG;AAAE,aAAA,CAAA;AACjE;QAEA,IAAIF,SAAAA,EAAW5E,SAAS,CAAG,EAAA;;AAEzB1B,YAAAA,gBAAAA,CAAiByG,WAAa,EAAA;gBAC5B1C,EAAI,EAAA;AAAEoD,oBAAAA,MAAAA,EAAQnB,OAAKM,CAAAA,SAAAA;AAAW;AAChC,aAAA,CAAA;AACF;AAEA,QAAA,MAAMmB,UAAUlG,MAAOmG,CAAAA,GAAG,CAAC,cAAgBC,CAAAA,CAAAA,SAAS,CAACvG,SAAWqF,EAAAA,WAAAA,CAAAA;QAEhE,MAAMmB,GAAAA,GAAM,MAAMrG,MAAO+D,CAAAA,EAAE,CAAClD,KAAK,CAAChB,SAAWyG,CAAAA,CAAAA,QAAQ,CAACJ,OAAAA,CAAAA;AAEtD3D,QAAAA,GAAAA,CAAIgE,IAAI,GAAG;AACT,YAAA,GAAGF,GAAG;AACNG,YAAAA,OAAAA,EAAS,MAAM5G,oBAAAA,CAAqBC,SAAWwG,EAAAA,GAAAA,CAAIG,OAAO;AAC5D,SAAA;AACF,KAAA;AAEA,IAAA,MAAMC,cAAalE,GAAQ,EAAA;AACzB,QAAA,MAAM,EAAErD,WAAW,EAAE,GAAGqD,IAAIE,KAAK;AACjC,QAAA,MAAM,EAAED,EAAE,EAAE,GAAGD,IAAI7D,MAAM;AAEzB,QAAA,MAAMgI,gCAAqBnE,CAAAA,GAAAA,CAAIW,OAAO,CAACrC,KAAK,CAAA;AAE5C,QAAA,MAAM,EACJ0C,OAAO,EACPT,SAAS,EACTJ,WAAW,EACX8B,cAAc,EACdnD,MAAM,EACNqD,MAAAA,EAAQ,EAAEC,MAAAA,EAAQhC,YAAY,EAAE,EAChCM,MAAAA,EAAQ,EAAE0B,MAAAA,EAAQN,YAAY,EAAE,EACjC,GAAG,MAAM,IAAI,CAAC/B,6BAA6B,CAACC,GAAKC,EAAAA,EAAAA,CAAAA;AAElD,QAAA,MAAM,EAAElD,GAAAA,EAAKmC,SAAS,EAAE,GAAGkB,YAAAA;AAC3B,QAAA,MAAM,EAAErD,GAAAA,EAAKO,SAAS,EAAE,GAAGwE,YAAAA;AAE3B,QAAA,MAAMZ,eAAkB,GAAA,MAAMrE,gBAAW,CAAA,oBAAA,CAAA,CACtCC,MAAM,CAAC;AAAEH,YAAAA,WAAAA;YAAaF,KAAOa,EAAAA;SAC7B6D,CAAAA,CAAAA,cAAc,CAAC/D,IAAI,CAAC;YAAEyF,MAAQZ,EAAAA;AAAe,SAAA,CAAA;AAEhD;;;;;;AAMC,QACD,MAAM0B,OAAUlG,GAAAA,MAAAA,CAAO+D,EAAE,CAAClD,KAAK,CAACY,SAAAA,CAAAA;AAChC,QAAA,MAAMkF,gBAAgB7G,qBAAU8G,CAAAA,WAAW,CAAC9D,SACxC,CAAA,GAAA,CAAC,GAAG+D,IAA+CX,GAAAA,OAAAA,CAAQY,SAAS,CAAID,GAAAA,IAAAA,CAAAA,GACxE,CAAC,GAAGA,IAAAA,GACFX,QACGa,IAAI,CAAA,GAAIF,KACT;aACCG,IAAI,CAAC,CAACX,GAAAA,IAAS;AAAEG,oBAAAA,OAAAA,EAASH,GAAM,GAAA;AAACA,wBAAAA;AAAI,qBAAA,GAAG;iBAAG,CAAA,CAAA;AAEpD,QAAA,MAAMzH,UAEF,EAAC;QAEL,IAAI+D,YAAAA,EAAcsE,SAASC,eAAiB,EAAA;YAC1C,IAAI7C,YAAAA,EAAc4C,SAASC,eAAiB,EAAA;AAC1C,gBAAA,IAAI7F,WAAW,WAAa,EAAA;AAC1BzC,oBAAAA,OAAAA,CAAQ6B,WAAW,GAAG;wBAAEE,QAAU,EAAA;AAAK,qBAAA;iBAClC,MAAA;AACL/B,oBAAAA,OAAAA,CAAQ6B,WAAW,GAAG;wBAAEC,KAAO,EAAA;AAAK,qBAAA;AACtC;AACF;SACK,MAAA,IAAI2D,YAAc4C,EAAAA,OAAAA,EAASC,eAAiB,EAAA;;AAEjDtI,YAAAA,OAAAA,CAAQ6B,WAAW,GAAG;gBAAEC,KAAO,EAAA;AAAK,aAAA;AACtC;AAEA;;;;;;;;QASA,MAAM2F,GAAM,GAAA,MAAMM,aAAc,CAAA;YAAEnE,EAAIe,EAAAA;AAAQ,SAAA,EAAGb,WAAa,EAAA;YAC5D3B,MAAQ,EAAA;AAAC,gBAAA,IAAA;AAAM,gBAAA,YAAA;AAAc,gBAAA,QAAA;AAAU,gBAAA,aAAA;AAAe,gBAAA;AAAY,aAAA;YAClEoG,QAAU,EAAA,MAAA;AACVC,YAAAA,IAAAA,EAAM7E,GAAIW,CAAAA,OAAO,CAACrC,KAAK,CAACuG,IAAI;AAC5BC,YAAAA,QAAAA,EAAU9E,GAAIW,CAAAA,OAAO,CAACrC,KAAK,CAACwG,QAAQ;AACpCzI,YAAAA;AACF,SAAA,CAAA;AAEA;;;QAIA,MAAM0I,SAAYjB,GAAAA,GAAAA,CAAIG,OAAO,CAACjG,GAAG,CAAC,CAACgH,IAAcA,GAAAA,IAAAA,CAAK/E,EAAE,CAAA;AACxD/D,QAAAA,gBAAAA,CAAiBgF,eAAiB,EAAA;YAAEjB,EAAI,EAAA;gBAAElC,GAAKgH,EAAAA;AAAU;AAAE,SAAA,CAAA;AAE3D;;;;;QAMA,MAAME,YAAe,GAAA,MAAMb,aAAc,CAAA;YAAEnE,EAAIe,EAAAA;AAAQ,SAAA,EAAGb,WAAa,EAAA;AACrE,YAAA,GAAG1C,OAAOmG,GAAG,CAAC,gBAAgBC,SAAS,CAACvG,WAAW4D,eAAgB,CAAA;YACnE0D,QAAU,EAAA;AACZ,SAAA,CAAA;;QAGA,MAAMM,cAAAA,GAAiBC,UAAO,IAAMC,EAAAA,SAAAA,CAAOH,aAAahB,OAAO,EAAEH,IAAIG,OAAO,CAAA,CAAA;AAE5EjE,QAAAA,GAAAA,CAAIgE,IAAI,GAAG;YACTqB,UAAYvB,EAAAA,GAAAA,CAAIuB,UAAU,IAAI;gBAC5BR,IAAM,EAAA,CAAA;gBACNS,SAAW,EAAA,CAAA;gBACXR,QAAU,EAAA,EAAA;AACVS,gBAAAA,KAAAA,EAAOL,eAAetH;AACxB,aAAA;YACAqG,OAAS,EAAA,MAAM5G,qBAAqBC,SAAW4H,EAAAA,cAAAA;AACjD,SAAA;AACF;AACF,CAAE;;;;"}
1
+ {"version":3,"file":"relations.js","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\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';\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 return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\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 const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(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) return { status: undefined };\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 prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n '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 { idsToOmit, idsToInclude, _q, ...query } = 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 } 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 (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\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: uniq(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) {\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 import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\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","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","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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"}
@@ -20,8 +20,8 @@ const sanitizeMainField = (model, mainField, userAbility)=>{
20
20
  // Whether the user has the permission to access the model's main field (using RBAC abilities)
21
21
  const canReadMainField = permissionChecker.can.read(null, mainField);
22
22
  if (!isMainFieldListable || !canReadMainField) {
23
- // Default to 'id' if the actual main field shouldn't be displayed
24
- return 'id';
23
+ // Default to 'documentId' if the actual main field shouldn't be displayed
24
+ return 'documentId';
25
25
  }
26
26
  // Edge cases
27
27
  // 1. Enforce 'name' as the main field for users and permissions' roles
@@ -1 +1 @@
1
- {"version":3,"file":"relations.mjs","sources":["../../../server/src/controllers/relations.ts"],"sourcesContent":["import { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\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';\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 'id' if the actual main field shouldn't be displayed\n return 'id';\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 return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\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 const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(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) return { status: undefined };\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 prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n '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 { idsToOmit, idsToInclude, _q, ...query } = 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 } 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 (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\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: uniq(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) {\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 import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\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","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","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 { prop, uniq, uniqBy, concat, flow, isEmpty } from 'lodash/fp';\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';\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 return relations.map((relation: RelationEntity) => {\n const availableStatuses = availableStatus.filter(\n (availableDocument: RelationEntity) =>\n availableDocument.documentId === relation.documentId &&\n (relation.locale ? availableDocument.locale === relation.locale : true)\n );\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 const isLocalized = strapi.plugin('i18n').service('content-types').isLocalizedContentType;\n const isSourceLocalized = isLocalized(sourceModel);\n const isTargetLocalized = isLocalized(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) return { status: undefined };\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 prop(`metadatas.${targetField}.edit.mainField`),\n (mainField) => mainField || 'id',\n (mainField) => sanitizeMainField(targetSchema, mainField, userAbility)\n )(modelConfig);\n\n const fieldsToSelect = uniq([\n mainField,\n PUBLISHED_AT_ATTRIBUTE,\n UPDATED_AT_ATTRIBUTE,\n '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 { idsToOmit, idsToInclude, _q, ...query } = 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 } 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 (_q) {\n const _filter = isOperatorOfType('where', query._filter) ? query._filter : '$containsi';\n addFiltersClause(queryParams, { [mainField]: { [_filter]: _q } });\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: uniq(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) {\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 import to make sure sanitized relations are kept in priority\n const relationsUnion = uniqBy('id', concat(sanitizedRes.results, res.results));\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","relation","availableStatuses","filter","availableDocument","locale","status","getStatus","getPublishedAtClause","validateLocale","sourceUid","sourceModel","targetModel","isLocalized","plugin","service","isLocalizedContentType","isSourceLocalized","isTargetLocalized","validateStatus","isDP","isSourceDP","undefined","extractAndValidateRequestInfo","ctx","id","state","targetField","sourceSchema","errors","ValidationError","attribute","attributes","type","target","request","isComponent","modelType","cannot","forbidden","entryId","where","permissionQuery","sanitizedQuery","populate","populateFromQuery","build","currentEntity","db","findOne","NotFoundError","ForbiddenError","modelConfig","findConfiguration","targetSchema","flow","prop","fieldsToSelect","uniq","source","schema","findAvailable","validateFindAvailable","sourceModelType","idsToOmit","idsToInclude","_q","queryParams","sort","fields","filterByLocale","subQuery","queryBuilder","alias","getAlias","document_id","isEmpty","$notIn","knexSubQuery","join","getKnexQuery","_filter","isOperatorOfType","dbQuery","get","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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"}
@@ -25,7 +25,9 @@ const generateUIDInputSchema = strapiUtils.yup.object({
25
25
  const checkUIDAvailabilityInputSchema = strapiUtils.yup.object({
26
26
  contentTypeUID: strapiUtils.yup.string().required(),
27
27
  field: strapiUtils.yup.string().required(),
28
- value: strapiUtils.yup.string().matches(/^[A-Za-z0-9-_.~]*$/).required()
28
+ value: strapiUtils.yup.string().required().test('isValueMatchingRegex', `\${path} must match the custom regex or the default one "/^[A-Za-z0-9-_.~]*$/"`, function(value, context) {
29
+ return value === '' || (context.options.context?.regex ? new RegExp(context.options?.context.regex).test(value) : /^[A-Za-z0-9-_.~]*$/.test(value));
30
+ })
29
31
  });
30
32
  const validateUIDField = (contentTypeUID, field)=>{
31
33
  const model = strapi.contentTypes[contentTypeUID];
@@ -46,7 +48,17 @@ const validateUIDField = (contentTypeUID, field)=>{
46
48
  const validateKind = strapiUtils.validateYupSchema(kindSchema);
47
49
  const validateBulkActionInput = strapiUtils.validateYupSchema(bulkActionInputSchema);
48
50
  const validateGenerateUIDInput = strapiUtils.validateYupSchema(generateUIDInputSchema);
49
- const validateCheckUIDAvailabilityInput = strapiUtils.validateYupSchema(checkUIDAvailabilityInputSchema);
51
+ const validateCheckUIDAvailabilityInput = (body)=>{
52
+ const options = {};
53
+ const contentType = body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;
54
+ if (contentType?.attributes[body.field] && `regex` in contentType.attributes[body.field] && contentType.attributes[body.field].regex) {
55
+ options.context = {
56
+ regex: (contentType?.attributes[body.field]).regex
57
+ };
58
+ }
59
+ const validator = strapiUtils.validateYupSchema(checkUIDAvailabilityInputSchema, options);
60
+ return validator(body);
61
+ };
50
62
 
51
63
  exports.validateBulkActionInput = validateBulkActionInput;
52
64
  exports.validateCheckUIDAvailabilityInput = validateCheckUIDAvailabilityInput;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { yup, validateYupSchema, errors } from '@strapi/utils';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'];\n\n/**\n * Validates type kind\n */\nconst kindSchema = yup.string().oneOf(TYPES).nullable();\n\nconst bulkActionInputSchema = yup\n .object({\n documentIds: yup.array().of(yup.strapiID()).min(1).required(),\n })\n .required();\n\nconst generateUIDInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n data: yup.object().required(),\n});\n\nconst checkUIDAvailabilityInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n value: yup\n .string()\n .matches(/^[A-Za-z0-9-_.~]*$/)\n .required(),\n});\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateYupSchema(kindSchema);\nconst validateBulkActionInput = validateYupSchema(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateYupSchema(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = validateYupSchema(checkUIDAvailabilityInputSchema);\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","yup","string","oneOf","nullable","bulkActionInputSchema","object","documentIds","array","of","strapiID","min","required","generateUIDInputSchema","contentTypeUID","field","data","checkUIDAvailabilityInputSchema","value","matches","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateYupSchema","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput"],"mappings":";;;;;;;;AAIA,MAAM,EAAEA,eAAe,EAAEC,eAAe,EAAE,GAAGC,kBAAAA;AAC7C,MAAMC,KAAQ,GAAA;AAAC,IAAA,YAAA;AAAc,IAAA;AAAiB,CAAA;AAE9C;;IAGA,MAAMC,aAAaC,eAAIC,CAAAA,MAAM,GAAGC,KAAK,CAACJ,OAAOK,QAAQ,EAAA;AAErD,MAAMC,qBAAAA,GAAwBJ,eAC3BK,CAAAA,MAAM,CAAC;IACNC,WAAaN,EAAAA,eAAAA,CAAIO,KAAK,EAAA,CAAGC,EAAE,CAACR,eAAIS,CAAAA,QAAQ,EAAIC,CAAAA,CAAAA,GAAG,CAAC,CAAA,CAAA,CAAGC,QAAQ;AAC7D,CAAA,CAAA,CACCA,QAAQ,EAAA;AAEX,MAAMC,sBAAAA,GAAyBZ,eAAIK,CAAAA,MAAM,CAAC;IACxCQ,cAAgBb,EAAAA,eAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,eAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IAC5BI,IAAMf,EAAAA,eAAAA,CAAIK,MAAM,EAAA,CAAGM,QAAQ;AAC7B,CAAA,CAAA;AAEA,MAAMK,+BAAAA,GAAkChB,eAAIK,CAAAA,MAAM,CAAC;IACjDQ,cAAgBb,EAAAA,eAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,eAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;AAC5BM,IAAAA,KAAAA,EAAOjB,gBACJC,MAAM,EAAA,CACNiB,OAAO,CAAC,sBACRP,QAAQ;AACb,CAAA,CAAA;AAEMQ,MAAAA,gBAAAA,GAAmB,CAACN,cAAqBC,EAAAA,KAAAA,GAAAA;AAC7C,IAAA,MAAMM,KAAQC,GAAAA,MAAAA,CAAOC,YAAY,CAACT,cAAe,CAAA;AAEjD,IAAA,IAAI,CAACO,KAAO,EAAA;AACV,QAAA,MAAM,IAAIxB,eAAgB,CAAA,uBAAA,CAAA;AAC5B;AAEA,IAAA,IACE,CAAC2B,CAAAA,CAAEC,GAAG,CAACJ,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcN,QAAAA;KAAM,CACnCS,IAAAA,CAAAA,CAAEE,GAAG,CAACL,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcN,QAAAA,KAAAA;AAAO,QAAA;AAAO,KAAA,CAAA,KAAM,KAChD,EAAA;AACA,QAAA,MAAM,IAAIlB,eAAgB,CAAA,CAAC,EAAEkB,KAAAA,CAAM,kCAAkC,CAAC,CAAA;AACxE;AACF;AAcA,MAAMY,eAAeC,6BAAkB5B,CAAAA,UAAAA;AACvC,MAAM6B,0BAA0BD,6BAAkBvB,CAAAA,qBAAAA;AAClD,MAAMyB,2BAA2BF,6BAAkBf,CAAAA,sBAAAA;AACnD,MAAMkB,oCAAoCH,6BAAkBX,CAAAA,+BAAAA;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { Schema, UID } from '@strapi/types';\nimport { yup, validateYupSchema, errors } from '@strapi/utils';\nimport { ValidateOptions } from 'yup/lib/types';\nimport { TestContext } from 'yup';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'];\n\n/**\n * Validates type kind\n */\nconst kindSchema = yup.string().oneOf(TYPES).nullable();\n\nconst bulkActionInputSchema = yup\n .object({\n documentIds: yup.array().of(yup.strapiID()).min(1).required(),\n })\n .required();\n\nconst generateUIDInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n data: yup.object().required(),\n});\n\nconst checkUIDAvailabilityInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n value: yup\n .string()\n .required()\n .test(\n 'isValueMatchingRegex',\n `\\${path} must match the custom regex or the default one \"/^[A-Za-z0-9-_.~]*$/\"`,\n function (value, context: TestContext<{ regex?: string }>) {\n return (\n value === '' ||\n (context.options.context?.regex\n ? new RegExp(context.options?.context.regex).test(value as string)\n : /^[A-Za-z0-9-_.~]*$/.test(value as string))\n );\n }\n ),\n});\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateYupSchema(kindSchema);\nconst validateBulkActionInput = validateYupSchema(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateYupSchema(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = (body: {\n contentTypeUID: UID.ContentType;\n field: string;\n value: string;\n}) => {\n const options: ValidateOptions<{ regex?: string }> = {};\n\n const contentType =\n body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;\n\n if (\n contentType?.attributes[body.field] &&\n `regex` in contentType.attributes[body.field] &&\n (contentType.attributes[body.field] as Schema.Attribute.UID).regex\n ) {\n options.context = {\n regex: (contentType?.attributes[body.field] as Schema.Attribute.UID).regex,\n };\n }\n\n const validator = validateYupSchema(checkUIDAvailabilityInputSchema, options);\n\n return validator(body);\n};\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","yup","string","oneOf","nullable","bulkActionInputSchema","object","documentIds","array","of","strapiID","min","required","generateUIDInputSchema","contentTypeUID","field","data","checkUIDAvailabilityInputSchema","value","test","context","options","regex","RegExp","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateYupSchema","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput","body","contentType","attributes","validator"],"mappings":"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"}
@@ -23,7 +23,9 @@ const generateUIDInputSchema = yup.object({
23
23
  const checkUIDAvailabilityInputSchema = yup.object({
24
24
  contentTypeUID: yup.string().required(),
25
25
  field: yup.string().required(),
26
- value: yup.string().matches(/^[A-Za-z0-9-_.~]*$/).required()
26
+ value: yup.string().required().test('isValueMatchingRegex', `\${path} must match the custom regex or the default one "/^[A-Za-z0-9-_.~]*$/"`, function(value, context) {
27
+ return value === '' || (context.options.context?.regex ? new RegExp(context.options?.context.regex).test(value) : /^[A-Za-z0-9-_.~]*$/.test(value));
28
+ })
27
29
  });
28
30
  const validateUIDField = (contentTypeUID, field)=>{
29
31
  const model = strapi.contentTypes[contentTypeUID];
@@ -44,7 +46,17 @@ const validateUIDField = (contentTypeUID, field)=>{
44
46
  const validateKind = validateYupSchema(kindSchema);
45
47
  const validateBulkActionInput = validateYupSchema(bulkActionInputSchema);
46
48
  const validateGenerateUIDInput = validateYupSchema(generateUIDInputSchema);
47
- const validateCheckUIDAvailabilityInput = validateYupSchema(checkUIDAvailabilityInputSchema);
49
+ const validateCheckUIDAvailabilityInput = (body)=>{
50
+ const options = {};
51
+ const contentType = body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;
52
+ if (contentType?.attributes[body.field] && `regex` in contentType.attributes[body.field] && contentType.attributes[body.field].regex) {
53
+ options.context = {
54
+ regex: (contentType?.attributes[body.field]).regex
55
+ };
56
+ }
57
+ const validator = validateYupSchema(checkUIDAvailabilityInputSchema, options);
58
+ return validator(body);
59
+ };
48
60
 
49
61
  export { validateBulkActionInput, validateCheckUIDAvailabilityInput, validateGenerateUIDInput, validateKind, validateUIDField };
50
62
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { yup, validateYupSchema, errors } from '@strapi/utils';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'];\n\n/**\n * Validates type kind\n */\nconst kindSchema = yup.string().oneOf(TYPES).nullable();\n\nconst bulkActionInputSchema = yup\n .object({\n documentIds: yup.array().of(yup.strapiID()).min(1).required(),\n })\n .required();\n\nconst generateUIDInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n data: yup.object().required(),\n});\n\nconst checkUIDAvailabilityInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n value: yup\n .string()\n .matches(/^[A-Za-z0-9-_.~]*$/)\n .required(),\n});\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateYupSchema(kindSchema);\nconst validateBulkActionInput = validateYupSchema(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateYupSchema(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = validateYupSchema(checkUIDAvailabilityInputSchema);\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","yup","string","oneOf","nullable","bulkActionInputSchema","object","documentIds","array","of","strapiID","min","required","generateUIDInputSchema","contentTypeUID","field","data","checkUIDAvailabilityInputSchema","value","matches","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateYupSchema","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput"],"mappings":";;;;;;AAIA,MAAM,EAAEA,eAAe,EAAEC,eAAe,EAAE,GAAGC,MAAAA;AAC7C,MAAMC,KAAQ,GAAA;AAAC,IAAA,YAAA;AAAc,IAAA;AAAiB,CAAA;AAE9C;;IAGA,MAAMC,aAAaC,GAAIC,CAAAA,MAAM,GAAGC,KAAK,CAACJ,OAAOK,QAAQ,EAAA;AAErD,MAAMC,qBAAAA,GAAwBJ,GAC3BK,CAAAA,MAAM,CAAC;IACNC,WAAaN,EAAAA,GAAAA,CAAIO,KAAK,EAAA,CAAGC,EAAE,CAACR,GAAIS,CAAAA,QAAQ,EAAIC,CAAAA,CAAAA,GAAG,CAAC,CAAA,CAAA,CAAGC,QAAQ;AAC7D,CAAA,CAAA,CACCA,QAAQ,EAAA;AAEX,MAAMC,sBAAAA,GAAyBZ,GAAIK,CAAAA,MAAM,CAAC;IACxCQ,cAAgBb,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IAC5BI,IAAMf,EAAAA,GAAAA,CAAIK,MAAM,EAAA,CAAGM,QAAQ;AAC7B,CAAA,CAAA;AAEA,MAAMK,+BAAAA,GAAkChB,GAAIK,CAAAA,MAAM,CAAC;IACjDQ,cAAgBb,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;AAC5BM,IAAAA,KAAAA,EAAOjB,IACJC,MAAM,EAAA,CACNiB,OAAO,CAAC,sBACRP,QAAQ;AACb,CAAA,CAAA;AAEMQ,MAAAA,gBAAAA,GAAmB,CAACN,cAAqBC,EAAAA,KAAAA,GAAAA;AAC7C,IAAA,MAAMM,KAAQC,GAAAA,MAAAA,CAAOC,YAAY,CAACT,cAAe,CAAA;AAEjD,IAAA,IAAI,CAACO,KAAO,EAAA;AACV,QAAA,MAAM,IAAIxB,eAAgB,CAAA,uBAAA,CAAA;AAC5B;AAEA,IAAA,IACE,CAAC2B,CAAAA,CAAEC,GAAG,CAACJ,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcN,QAAAA;KAAM,CACnCS,IAAAA,CAAAA,CAAEE,GAAG,CAACL,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcN,QAAAA,KAAAA;AAAO,QAAA;AAAO,KAAA,CAAA,KAAM,KAChD,EAAA;AACA,QAAA,MAAM,IAAIlB,eAAgB,CAAA,CAAC,EAAEkB,KAAAA,CAAM,kCAAkC,CAAC,CAAA;AACxE;AACF;AAcA,MAAMY,eAAeC,iBAAkB5B,CAAAA,UAAAA;AACvC,MAAM6B,0BAA0BD,iBAAkBvB,CAAAA,qBAAAA;AAClD,MAAMyB,2BAA2BF,iBAAkBf,CAAAA,sBAAAA;AACnD,MAAMkB,oCAAoCH,iBAAkBX,CAAAA,+BAAAA;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../server/src/controllers/validation/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport { Schema, UID } from '@strapi/types';\nimport { yup, validateYupSchema, errors } from '@strapi/utils';\nimport { ValidateOptions } from 'yup/lib/types';\nimport { TestContext } from 'yup';\nimport createModelConfigurationSchema from './model-configuration';\n\nconst { PaginationError, ValidationError } = errors;\nconst TYPES = ['singleType', 'collectionType'];\n\n/**\n * Validates type kind\n */\nconst kindSchema = yup.string().oneOf(TYPES).nullable();\n\nconst bulkActionInputSchema = yup\n .object({\n documentIds: yup.array().of(yup.strapiID()).min(1).required(),\n })\n .required();\n\nconst generateUIDInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n data: yup.object().required(),\n});\n\nconst checkUIDAvailabilityInputSchema = yup.object({\n contentTypeUID: yup.string().required(),\n field: yup.string().required(),\n value: yup\n .string()\n .required()\n .test(\n 'isValueMatchingRegex',\n `\\${path} must match the custom regex or the default one \"/^[A-Za-z0-9-_.~]*$/\"`,\n function (value, context: TestContext<{ regex?: string }>) {\n return (\n value === '' ||\n (context.options.context?.regex\n ? new RegExp(context.options?.context.regex).test(value as string)\n : /^[A-Za-z0-9-_.~]*$/.test(value as string))\n );\n }\n ),\n});\n\nconst validateUIDField = (contentTypeUID: any, field: any) => {\n const model = strapi.contentTypes[contentTypeUID];\n\n if (!model) {\n throw new ValidationError('ContentType not found');\n }\n\n if (\n !_.has(model, ['attributes', field]) ||\n _.get(model, ['attributes', field, 'type']) !== 'uid'\n ) {\n throw new ValidationError(`${field} must be a valid \\`uid\\` attribute`);\n }\n};\n\nconst validatePagination = ({ page, pageSize }: any) => {\n const pageNumber = parseInt(page, 10);\n const pageSizeNumber = parseInt(pageSize, 10);\n\n if (Number.isNaN(pageNumber) || pageNumber < 1) {\n throw new PaginationError('invalid pageNumber param');\n }\n if (Number.isNaN(pageSizeNumber) || pageSizeNumber < 1) {\n throw new PaginationError('invalid pageSize param');\n }\n};\n\nconst validateKind = validateYupSchema(kindSchema);\nconst validateBulkActionInput = validateYupSchema(bulkActionInputSchema);\nconst validateGenerateUIDInput = validateYupSchema(generateUIDInputSchema);\nconst validateCheckUIDAvailabilityInput = (body: {\n contentTypeUID: UID.ContentType;\n field: string;\n value: string;\n}) => {\n const options: ValidateOptions<{ regex?: string }> = {};\n\n const contentType =\n body.contentTypeUID in strapi.contentTypes ? strapi.contentTypes[body.contentTypeUID] : null;\n\n if (\n contentType?.attributes[body.field] &&\n `regex` in contentType.attributes[body.field] &&\n (contentType.attributes[body.field] as Schema.Attribute.UID).regex\n ) {\n options.context = {\n regex: (contentType?.attributes[body.field] as Schema.Attribute.UID).regex,\n };\n }\n\n const validator = validateYupSchema(checkUIDAvailabilityInputSchema, options);\n\n return validator(body);\n};\n\nexport {\n createModelConfigurationSchema,\n validateUIDField,\n validatePagination,\n validateKind,\n validateBulkActionInput,\n validateGenerateUIDInput,\n validateCheckUIDAvailabilityInput,\n};\n"],"names":["PaginationError","ValidationError","errors","TYPES","kindSchema","yup","string","oneOf","nullable","bulkActionInputSchema","object","documentIds","array","of","strapiID","min","required","generateUIDInputSchema","contentTypeUID","field","data","checkUIDAvailabilityInputSchema","value","test","context","options","regex","RegExp","validateUIDField","model","strapi","contentTypes","_","has","get","validateKind","validateYupSchema","validateBulkActionInput","validateGenerateUIDInput","validateCheckUIDAvailabilityInput","body","contentType","attributes","validator"],"mappings":";;;;;;AAOA,MAAM,EAAEA,eAAe,EAAEC,eAAe,EAAE,GAAGC,MAAAA;AAC7C,MAAMC,KAAQ,GAAA;AAAC,IAAA,YAAA;AAAc,IAAA;AAAiB,CAAA;AAE9C;;IAGA,MAAMC,aAAaC,GAAIC,CAAAA,MAAM,GAAGC,KAAK,CAACJ,OAAOK,QAAQ,EAAA;AAErD,MAAMC,qBAAAA,GAAwBJ,GAC3BK,CAAAA,MAAM,CAAC;IACNC,WAAaN,EAAAA,GAAAA,CAAIO,KAAK,EAAA,CAAGC,EAAE,CAACR,GAAIS,CAAAA,QAAQ,EAAIC,CAAAA,CAAAA,GAAG,CAAC,CAAA,CAAA,CAAGC,QAAQ;AAC7D,CAAA,CAAA,CACCA,QAAQ,EAAA;AAEX,MAAMC,sBAAAA,GAAyBZ,GAAIK,CAAAA,MAAM,CAAC;IACxCQ,cAAgBb,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IAC5BI,IAAMf,EAAAA,GAAAA,CAAIK,MAAM,EAAA,CAAGM,QAAQ;AAC7B,CAAA,CAAA;AAEA,MAAMK,+BAAAA,GAAkChB,GAAIK,CAAAA,MAAM,CAAC;IACjDQ,cAAgBb,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;IACrCG,KAAOd,EAAAA,GAAAA,CAAIC,MAAM,EAAA,CAAGU,QAAQ,EAAA;AAC5BM,IAAAA,KAAAA,EAAOjB,GACJC,CAAAA,MAAM,EACNU,CAAAA,QAAQ,GACRO,IAAI,CACH,sBACA,EAAA,CAAC,8EAA8E,CAAC,EAChF,SAAUD,KAAK,EAAEE,OAAwC,EAAA;QACvD,OACEF,KAAAA,KAAU,OACTE,OAAAA,CAAQC,OAAO,CAACD,OAAO,EAAEE,KAAAA,GACtB,IAAIC,MAAAA,CAAOH,QAAQC,OAAO,EAAED,QAAQE,KAAOH,CAAAA,CAAAA,IAAI,CAACD,KAChD,CAAA,GAAA,oBAAA,CAAqBC,IAAI,CAACD,KAAe,CAAA,CAAA;AAEjD,KAAA;AAEN,CAAA,CAAA;AAEMM,MAAAA,gBAAAA,GAAmB,CAACV,cAAqBC,EAAAA,KAAAA,GAAAA;AAC7C,IAAA,MAAMU,KAAQC,GAAAA,MAAAA,CAAOC,YAAY,CAACb,cAAe,CAAA;AAEjD,IAAA,IAAI,CAACW,KAAO,EAAA;AACV,QAAA,MAAM,IAAI5B,eAAgB,CAAA,uBAAA,CAAA;AAC5B;AAEA,IAAA,IACE,CAAC+B,CAAAA,CAAEC,GAAG,CAACJ,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcV,QAAAA;KAAM,CACnCa,IAAAA,CAAAA,CAAEE,GAAG,CAACL,KAAO,EAAA;AAAC,QAAA,YAAA;AAAcV,QAAAA,KAAAA;AAAO,QAAA;AAAO,KAAA,CAAA,KAAM,KAChD,EAAA;AACA,QAAA,MAAM,IAAIlB,eAAgB,CAAA,CAAC,EAAEkB,KAAAA,CAAM,kCAAkC,CAAC,CAAA;AACxE;AACF;AAcA,MAAMgB,eAAeC,iBAAkBhC,CAAAA,UAAAA;AACvC,MAAMiC,0BAA0BD,iBAAkB3B,CAAAA,qBAAAA;AAClD,MAAM6B,2BAA2BF,iBAAkBnB,CAAAA,sBAAAA;AACnD,MAAMsB,oCAAoC,CAACC,IAAAA,GAAAA;AAKzC,IAAA,MAAMf,UAA+C,EAAC;AAEtD,IAAA,MAAMgB,WACJD,GAAAA,IAAAA,CAAKtB,cAAc,IAAIY,MAAOC,CAAAA,YAAY,GAAGD,MAAAA,CAAOC,YAAY,CAACS,IAAKtB,CAAAA,cAAc,CAAC,GAAG,IAAA;IAE1F,IACEuB,WAAAA,EAAaC,UAAU,CAACF,IAAKrB,CAAAA,KAAK,CAAC,IACnC,CAAC,KAAK,CAAC,IAAIsB,WAAYC,CAAAA,UAAU,CAACF,IAAAA,CAAKrB,KAAK,CAAC,IAC5CsB,WAAYC,CAAAA,UAAU,CAACF,IAAAA,CAAKrB,KAAK,CAAC,CAA0BO,KAAK,EAClE;AACAD,QAAAA,OAAAA,CAAQD,OAAO,GAAG;YAChBE,KAAO,EAACe,CAAAA,WAAAA,EAAaC,UAAU,CAACF,KAAKrB,KAAK,CAAC,EAA0BO;AACvE,SAAA;AACF;IAEA,MAAMiB,SAAAA,GAAYP,kBAAkBf,+BAAiCI,EAAAA,OAAAA,CAAAA;AAErE,IAAA,OAAOkB,SAAUH,CAAAA,IAAAA,CAAAA;AACnB;;;;"}
@@ -2,7 +2,6 @@
2
2
 
3
3
  var strapiUtils = require('@strapi/utils');
4
4
  var fp = require('lodash/fp');
5
- var nodeSchedule = require('node-schedule');
6
5
  var utils$1 = require('../utils.js');
7
6
  var constants = require('../constants.js');
8
7
  var utils = require('./utils.js');
@@ -58,18 +57,20 @@ var utils = require('./utils.js');
58
57
  };
59
58
  const createLifecyclesService = ({ strapi: strapi1 })=>{
60
59
  const state = {
61
- deleteExpiredJob: null,
62
60
  isInitialized: false
63
61
  };
64
62
  const serviceUtils = utils.createServiceUtils({
65
63
  strapi: strapi1
66
64
  });
65
+ const { persistTablesWithPrefix } = strapi1.service('admin::persist-tables');
67
66
  return {
68
67
  async bootstrap () {
69
68
  // Prevent initializing the service twice
70
69
  if (state.isInitialized) {
71
70
  return;
72
71
  }
72
+ // Avoid data loss in case users temporarily don't have a license
73
+ await persistTablesWithPrefix('strapi_history_versions');
73
74
  strapi1.documents.use(async (context, next)=>{
74
75
  const result = await next();
75
76
  if (!shouldCreateHistoryVersion(context)) {
@@ -124,27 +125,30 @@ const createLifecyclesService = ({ strapi: strapi1 })=>{
124
125
  return result;
125
126
  });
126
127
  // Schedule a job to delete expired history versions every day at midnight
127
- state.deleteExpiredJob = nodeSchedule.scheduleJob('historyDaily', '0 0 * * *', ()=>{
128
- const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;
129
- const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
130
- strapi1.db.query(constants.HISTORY_VERSION_UID).deleteMany({
131
- where: {
132
- created_at: {
133
- $lt: expirationDate
134
- }
135
- }
136
- }).catch((error)=>{
137
- if (error instanceof Error) {
138
- strapi1.log.error('Error deleting expired history versions', error.message);
139
- }
140
- });
128
+ strapi1.cron.add({
129
+ deleteHistoryDaily: {
130
+ async task () {
131
+ const retentionDaysInMilliseconds = serviceUtils.getRetentionDays() * 24 * 60 * 60 * 1000;
132
+ const expirationDate = new Date(Date.now() - retentionDaysInMilliseconds);
133
+ strapi1.db.query(constants.HISTORY_VERSION_UID).deleteMany({
134
+ where: {
135
+ created_at: {
136
+ $lt: expirationDate
137
+ }
138
+ }
139
+ }).catch((error)=>{
140
+ if (error instanceof Error) {
141
+ strapi1.log.error('Error deleting expired history versions', error.message);
142
+ }
143
+ });
144
+ },
145
+ options: '0 0 * * *'
146
+ }
141
147
  });
142
148
  state.isInitialized = true;
143
149
  },
144
150
  async destroy () {
145
- if (state.deleteExpiredJob) {
146
- state.deleteExpiredJob.cancel();
147
- }
151
+ strapi1.cron.remove('deleteHistoryDaily');
148
152
  }
149
153
  };
150
154
  };