@directus/api 20.0.0 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/auth/drivers/ldap.js +5 -5
  3. package/dist/auth/drivers/local.js +4 -4
  4. package/dist/auth/drivers/oauth2.js +5 -5
  5. package/dist/auth/drivers/openid.js +3 -5
  6. package/dist/auth/drivers/saml.js +1 -1
  7. package/dist/auth.js +1 -1
  8. package/dist/cache.js +4 -1
  9. package/dist/cli/commands/bootstrap/index.js +10 -3
  10. package/dist/cli/commands/count/index.js +1 -1
  11. package/dist/cli/commands/database/install.js +1 -1
  12. package/dist/cli/commands/database/migrate.js +1 -1
  13. package/dist/cli/commands/init/index.js +9 -10
  14. package/dist/cli/commands/roles/create.js +1 -1
  15. package/dist/cli/commands/schema/apply.js +1 -1
  16. package/dist/cli/commands/schema/snapshot.js +1 -1
  17. package/dist/cli/commands/users/create.js +1 -1
  18. package/dist/cli/commands/users/passwd.js +1 -1
  19. package/dist/cli/load-extensions.js +1 -1
  20. package/dist/cli/utils/defaults.d.ts +4 -11
  21. package/dist/cli/utils/defaults.js +7 -1
  22. package/dist/constants.d.ts +1 -1
  23. package/dist/constants.js +2 -2
  24. package/dist/controllers/access.d.ts +2 -0
  25. package/dist/controllers/access.js +148 -0
  26. package/dist/controllers/assets.js +1 -1
  27. package/dist/controllers/auth.js +6 -17
  28. package/dist/controllers/files.js +1 -1
  29. package/dist/controllers/permissions.js +14 -2
  30. package/dist/controllers/policies.d.ts +2 -0
  31. package/dist/controllers/policies.js +169 -0
  32. package/dist/controllers/roles.js +22 -1
  33. package/dist/controllers/schema.js +1 -1
  34. package/dist/controllers/tus.js +11 -23
  35. package/dist/controllers/users.js +0 -55
  36. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +16 -0
  37. package/dist/database/get-ast-from-query/get-ast-from-query.js +82 -0
  38. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +13 -0
  39. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +69 -0
  40. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +15 -0
  41. package/dist/database/get-ast-from-query/lib/parse-fields.js +190 -0
  42. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +14 -0
  43. package/dist/database/get-ast-from-query/utils/get-deep-query.js +17 -0
  44. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +2 -0
  45. package/dist/database/get-ast-from-query/utils/get-related-collection.js +13 -0
  46. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +2 -0
  47. package/dist/database/get-ast-from-query/utils/get-relation.js +7 -0
  48. package/dist/database/helpers/fn/types.d.ts +2 -1
  49. package/dist/database/helpers/fn/types.js +1 -1
  50. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  51. package/dist/database/helpers/geometry/dialects/mssql.js +4 -2
  52. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  53. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  54. package/dist/database/helpers/geometry/dialects/oracle.js +5 -3
  55. package/dist/database/helpers/geometry/types.d.ts +1 -1
  56. package/dist/database/helpers/geometry/types.js +4 -2
  57. package/dist/database/index.js +3 -2
  58. package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
  59. package/dist/database/migrations/20210519A-add-system-fk-triggers.js +1 -1
  60. package/dist/database/migrations/20210802A-replace-groups.js +1 -1
  61. package/dist/database/migrations/20230721A-require-shares-fields.js +1 -1
  62. package/dist/database/migrations/20240710A-permissions-policies.d.ts +3 -0
  63. package/dist/database/migrations/20240710A-permissions-policies.js +169 -0
  64. package/dist/database/migrations/run.js +1 -1
  65. package/dist/database/run-ast/lib/get-db-query.d.ts +4 -0
  66. package/dist/database/run-ast/lib/get-db-query.js +208 -0
  67. package/dist/database/run-ast/lib/parse-current-level.d.ts +7 -0
  68. package/dist/database/run-ast/lib/parse-current-level.js +41 -0
  69. package/dist/database/run-ast/run-ast.d.ts +7 -0
  70. package/dist/database/run-ast/run-ast.js +107 -0
  71. package/dist/database/{run-ast.d.ts → run-ast/types.d.ts} +3 -9
  72. package/dist/database/run-ast/types.js +1 -0
  73. package/dist/database/run-ast/utils/apply-case-when.d.ts +16 -0
  74. package/dist/database/run-ast/utils/apply-case-when.js +26 -0
  75. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +3 -0
  76. package/dist/database/run-ast/utils/apply-parent-filters.js +55 -0
  77. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +10 -0
  78. package/dist/database/run-ast/utils/get-column-pre-processor.js +57 -0
  79. package/dist/database/run-ast/utils/get-field-alias.d.ts +2 -0
  80. package/dist/database/run-ast/utils/get-field-alias.js +4 -0
  81. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +5 -0
  82. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +23 -0
  83. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +3 -0
  84. package/dist/database/run-ast/utils/merge-with-parent-items.js +87 -0
  85. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +3 -0
  86. package/dist/database/run-ast/utils/remove-temporary-fields.js +73 -0
  87. package/dist/emitter.js +1 -1
  88. package/dist/extensions/lib/get-shared-deps-mapping.js +1 -1
  89. package/dist/extensions/lib/installation/manager.js +1 -1
  90. package/dist/extensions/lib/sandbox/register/call-reference.js +1 -1
  91. package/dist/extensions/lib/sandbox/sdk/generators/log.js +1 -1
  92. package/dist/extensions/lib/sync-extensions.js +1 -1
  93. package/dist/extensions/manager.js +1 -1
  94. package/dist/flows.js +4 -5
  95. package/dist/{logger.js → logger/index.js} +2 -8
  96. package/dist/logger/redact-query.d.ts +1 -0
  97. package/dist/logger/redact-query.js +13 -0
  98. package/dist/mailer.js +1 -1
  99. package/dist/middleware/authenticate.js +2 -7
  100. package/dist/middleware/cache.js +2 -2
  101. package/dist/middleware/error-handler.js +1 -1
  102. package/dist/middleware/rate-limiter-global.js +1 -1
  103. package/dist/middleware/respond.js +2 -2
  104. package/dist/operations/log/index.js +1 -1
  105. package/dist/operations/mail/index.js +1 -1
  106. package/dist/permissions/cache.d.ts +2 -0
  107. package/dist/permissions/cache.js +23 -0
  108. package/dist/permissions/lib/fetch-permissions.d.ts +10 -0
  109. package/dist/permissions/lib/fetch-permissions.js +55 -0
  110. package/dist/permissions/lib/fetch-policies.d.ts +7 -0
  111. package/dist/permissions/lib/fetch-policies.js +28 -0
  112. package/dist/permissions/lib/fetch-roles-tree.d.ts +3 -0
  113. package/dist/permissions/lib/fetch-roles-tree.js +28 -0
  114. package/dist/{services/permissions → permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  115. package/dist/permissions/lib/with-app-minimal-permissions.js +10 -0
  116. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +7 -0
  117. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +56 -0
  118. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +3 -0
  119. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +16 -0
  120. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +8 -0
  121. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +24 -0
  122. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +9 -0
  123. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +31 -0
  124. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +16 -0
  125. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +27 -0
  126. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +10 -0
  127. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +23 -0
  128. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +5 -0
  129. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +7 -0
  130. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +5 -0
  131. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +10 -0
  132. package/dist/permissions/modules/fetch-global-access/types.d.ts +4 -0
  133. package/dist/permissions/modules/fetch-global-access/types.js +1 -0
  134. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +4 -0
  135. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +27 -0
  136. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +12 -0
  137. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +32 -0
  138. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +4 -0
  139. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +29 -0
  140. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +4 -0
  141. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +49 -0
  142. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +3 -0
  143. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +56 -0
  144. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +4 -0
  145. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +8 -0
  146. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +9 -0
  147. package/dist/permissions/modules/process-ast/lib/inject-cases.js +93 -0
  148. package/dist/permissions/modules/process-ast/process-ast.d.ts +9 -0
  149. package/dist/permissions/modules/process-ast/process-ast.js +39 -0
  150. package/dist/permissions/modules/process-ast/types.d.ts +24 -0
  151. package/dist/permissions/modules/process-ast/types.js +1 -0
  152. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +2 -0
  153. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +7 -0
  154. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +12 -0
  155. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +30 -0
  156. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +15 -0
  157. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +50 -0
  158. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +3 -0
  159. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +9 -0
  160. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +3 -0
  161. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +34 -0
  162. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +1 -0
  163. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +3 -0
  164. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +5 -0
  165. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +7 -0
  166. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +2 -0
  167. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +3 -0
  168. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +2 -0
  169. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +3 -0
  170. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +3 -0
  171. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +16 -0
  172. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +2 -0
  173. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +12 -0
  174. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +2 -0
  175. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +28 -0
  176. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +5 -0
  177. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +12 -0
  178. package/dist/permissions/modules/process-payload/process-payload.d.ts +13 -0
  179. package/dist/permissions/modules/process-payload/process-payload.js +77 -0
  180. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +12 -0
  181. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +11 -0
  182. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +9 -0
  183. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +33 -0
  184. package/dist/permissions/modules/validate-access/validate-access.d.ts +14 -0
  185. package/dist/permissions/modules/validate-access/validate-access.js +28 -0
  186. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +1 -0
  187. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +8 -0
  188. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +5 -0
  189. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +10 -0
  190. package/dist/permissions/types.d.ts +6 -0
  191. package/dist/permissions/types.js +1 -0
  192. package/dist/permissions/utils/create-default-accountability.d.ts +2 -0
  193. package/dist/permissions/utils/create-default-accountability.js +11 -0
  194. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +8 -0
  195. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +27 -0
  196. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +9 -0
  197. package/dist/permissions/utils/fetch-dynamic-variable-context.js +43 -0
  198. package/dist/permissions/utils/filter-policies-by-ip.d.ts +2 -0
  199. package/dist/permissions/utils/filter-policies-by-ip.js +15 -0
  200. package/dist/permissions/utils/get-unaliased-field-key.d.ts +5 -0
  201. package/dist/permissions/utils/get-unaliased-field-key.js +17 -0
  202. package/dist/permissions/utils/process-permissions.d.ts +7 -0
  203. package/dist/permissions/utils/process-permissions.js +9 -0
  204. package/dist/permissions/utils/with-cache.d.ts +10 -0
  205. package/dist/permissions/utils/with-cache.js +25 -0
  206. package/dist/request/is-denied-ip.js +1 -1
  207. package/dist/server.js +1 -1
  208. package/dist/services/access.d.ts +10 -0
  209. package/dist/services/access.js +43 -0
  210. package/dist/services/activity.js +23 -11
  211. package/dist/services/assets.d.ts +2 -3
  212. package/dist/services/assets.js +11 -6
  213. package/dist/services/authentication.js +18 -18
  214. package/dist/services/collections.js +18 -17
  215. package/dist/services/fields.d.ts +0 -1
  216. package/dist/services/fields.js +53 -24
  217. package/dist/services/files/utils/get-metadata.js +1 -1
  218. package/dist/services/files.js +25 -15
  219. package/dist/services/graphql/index.d.ts +3 -3
  220. package/dist/services/graphql/index.js +126 -22
  221. package/dist/services/graphql/subscription.js +2 -4
  222. package/dist/services/graphql/utils/process-error.js +1 -1
  223. package/dist/services/graphql/utils/sanitize-gql-schema.js +1 -1
  224. package/dist/services/import-export.js +19 -5
  225. package/dist/services/index.d.ts +3 -2
  226. package/dist/services/index.js +3 -2
  227. package/dist/services/items.d.ts +3 -3
  228. package/dist/services/items.js +115 -44
  229. package/dist/services/mail/index.js +1 -1
  230. package/dist/services/meta.js +60 -23
  231. package/dist/services/notifications.js +15 -7
  232. package/dist/services/payload.d.ts +9 -10
  233. package/dist/services/payload.js +18 -3
  234. package/dist/services/{permissions/index.d.ts → permissions.d.ts} +5 -7
  235. package/dist/services/{permissions/index.js → permissions.js} +30 -54
  236. package/dist/services/policies.d.ts +12 -0
  237. package/dist/services/policies.js +87 -0
  238. package/dist/services/relations.d.ts +0 -6
  239. package/dist/services/relations.js +26 -29
  240. package/dist/services/roles.d.ts +4 -12
  241. package/dist/services/roles.js +57 -424
  242. package/dist/services/server.js +1 -1
  243. package/dist/services/shares.d.ts +0 -2
  244. package/dist/services/shares.js +13 -9
  245. package/dist/services/specifications.d.ts +2 -2
  246. package/dist/services/specifications.js +39 -27
  247. package/dist/services/tus/data-store.js +3 -1
  248. package/dist/services/users.d.ts +1 -5
  249. package/dist/services/users.js +79 -162
  250. package/dist/services/utils.js +11 -7
  251. package/dist/services/versions.d.ts +0 -2
  252. package/dist/services/versions.js +34 -10
  253. package/dist/services/webhooks.js +1 -1
  254. package/dist/telemetry/lib/get-report.js +2 -2
  255. package/dist/telemetry/lib/track.js +1 -1
  256. package/dist/telemetry/utils/check-user-limits.d.ts +5 -0
  257. package/dist/telemetry/utils/check-user-limits.js +19 -0
  258. package/dist/types/ast.d.ts +43 -1
  259. package/dist/types/items.d.ts +11 -0
  260. package/dist/utils/apply-diff.js +1 -1
  261. package/dist/utils/apply-query.d.ts +4 -3
  262. package/dist/utils/apply-query.js +37 -8
  263. package/dist/utils/delete-from-require-cache.js +1 -1
  264. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +17 -0
  265. package/dist/utils/fetch-user-count/fetch-access-lookup.js +22 -0
  266. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +16 -0
  267. package/dist/utils/fetch-user-count/fetch-access-roles.js +37 -0
  268. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +6 -0
  269. package/dist/utils/fetch-user-count/fetch-active-users.js +3 -0
  270. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +12 -0
  271. package/dist/utils/fetch-user-count/fetch-user-count.js +57 -0
  272. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +20 -0
  273. package/dist/utils/fetch-user-count/get-user-count-query.js +17 -0
  274. package/dist/utils/get-accountability-for-role.js +16 -25
  275. package/dist/utils/get-accountability-for-token.js +17 -16
  276. package/dist/utils/get-cache-key.d.ts +1 -1
  277. package/dist/utils/get-cache-key.js +12 -1
  278. package/dist/utils/get-column.d.ts +2 -1
  279. package/dist/utils/get-column.js +1 -0
  280. package/dist/utils/get-default-value.js +1 -1
  281. package/dist/utils/get-ip-from-req.js +1 -1
  282. package/dist/utils/get-schema.js +1 -1
  283. package/dist/utils/get-service.js +5 -1
  284. package/dist/utils/is-url-allowed.js +1 -1
  285. package/dist/utils/reduce-schema.d.ts +4 -6
  286. package/dist/utils/reduce-schema.js +16 -32
  287. package/dist/utils/sanitize-query.js +1 -1
  288. package/dist/utils/transaction.js +1 -1
  289. package/dist/utils/validate-env.js +1 -1
  290. package/dist/utils/validate-storage.js +1 -1
  291. package/dist/utils/validate-user-count-integrity.d.ts +13 -0
  292. package/dist/utils/validate-user-count-integrity.js +29 -0
  293. package/dist/websocket/authenticate.d.ts +0 -2
  294. package/dist/websocket/authenticate.js +0 -12
  295. package/dist/websocket/controllers/base.d.ts +1 -1
  296. package/dist/websocket/controllers/base.js +21 -17
  297. package/dist/websocket/controllers/graphql.js +2 -5
  298. package/dist/websocket/controllers/hooks.js +4 -0
  299. package/dist/websocket/controllers/rest.js +1 -3
  300. package/dist/websocket/errors.js +1 -1
  301. package/dist/websocket/handlers/subscribe.js +0 -2
  302. package/dist/websocket/utils/items.d.ts +1 -1
  303. package/package.json +28 -27
  304. package/dist/database/run-ast.js +0 -450
  305. package/dist/middleware/check-ip.d.ts +0 -2
  306. package/dist/middleware/check-ip.js +0 -37
  307. package/dist/middleware/get-permissions.d.ts +0 -3
  308. package/dist/middleware/get-permissions.js +0 -10
  309. package/dist/services/authorization.d.ts +0 -17
  310. package/dist/services/authorization.js +0 -456
  311. package/dist/services/permissions/lib/with-app-minimal-permissions.js +0 -13
  312. package/dist/telemetry/utils/check-increased-user-limits.d.ts +0 -7
  313. package/dist/telemetry/utils/check-increased-user-limits.js +0 -25
  314. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +0 -6
  315. package/dist/telemetry/utils/get-role-counts-by-roles.js +0 -27
  316. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +0 -11
  317. package/dist/telemetry/utils/get-role-counts-by-users.js +0 -34
  318. package/dist/telemetry/utils/get-user-count.d.ts +0 -8
  319. package/dist/telemetry/utils/get-user-count.js +0 -33
  320. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +0 -7
  321. package/dist/telemetry/utils/get-user-counts-by-roles.js +0 -35
  322. package/dist/utils/get-ast-from-query.d.ts +0 -13
  323. package/dist/utils/get-ast-from-query.js +0 -297
  324. package/dist/utils/get-permissions.d.ts +0 -2
  325. package/dist/utils/get-permissions.js +0 -150
  326. package/dist/utils/merge-permissions-for-share.d.ts +0 -4
  327. package/dist/utils/merge-permissions-for-share.js +0 -109
  328. package/dist/utils/merge-permissions.d.ts +0 -3
  329. package/dist/utils/merge-permissions.js +0 -95
  330. /package/dist/{logger.d.ts → logger/index.d.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@directus/api",
3
- "version": "20.0.0",
3
+ "version": "21.0.0-rc.0",
4
4
  "description": "Directus is a real-time API and App dashboard for managing SQL database content",
5
5
  "keywords": [
6
6
  "directus",
@@ -99,7 +99,7 @@
99
99
  "graphql-ws": "5.16.0",
100
100
  "helmet": "7.1.0",
101
101
  "icc": "3.0.0",
102
- "inquirer": "9.2.23",
102
+ "inquirer": "9.3.2",
103
103
  "ioredis": "5.4.1",
104
104
  "ip-matching": "2.1.2",
105
105
  "isolated-vm": "4.7.2",
@@ -135,7 +135,7 @@
135
135
  "pino-http": "9.0.0",
136
136
  "pino-http-print": "3.1.0",
137
137
  "pino-pretty": "11.2.1",
138
- "qs": "6.12.1",
138
+ "qs": "6.12.2",
139
139
  "rate-limiter-flexible": "5.0.3",
140
140
  "rollup": "4.17.2",
141
141
  "samlify": "2.8.10",
@@ -146,32 +146,32 @@
146
146
  "tar": "7.4.0",
147
147
  "tsx": "4.12.0",
148
148
  "wellknown": "0.5.0",
149
- "ws": "8.17.1",
149
+ "ws": "8.18.0",
150
150
  "zod": "3.23.8",
151
151
  "zod-validation-error": "3.3.0",
152
- "@directus/app": "12.2.0",
153
- "@directus/constants": "11.0.4",
154
- "@directus/extensions": "1.0.9",
155
- "@directus/errors": "0.3.3",
156
- "@directus/env": "1.2.0",
157
- "@directus/extensions-registry": "1.0.9",
158
- "@directus/extensions-sdk": "11.0.9",
152
+ "@directus/constants": "11.1.0-rc.1",
153
+ "@directus/env": "1.3.1-rc.0",
154
+ "@directus/errors": "0.4.0-rc.1",
155
+ "@directus/app": "13.0.0-rc.2",
156
+ "@directus/extensions": "2.0.0-rc.1",
157
+ "@directus/extensions-registry": "1.0.10-rc.0",
158
+ "@directus/extensions-sdk": "11.0.10-rc.0",
159
+ "@directus/memory": "1.1.0-rc.1",
159
160
  "@directus/format-title": "10.1.2",
160
- "@directus/memory": "1.0.10",
161
- "@directus/pressure": "1.0.21",
161
+ "@directus/pressure": "1.0.22-rc.0",
162
162
  "@directus/schema": "11.0.3",
163
163
  "@directus/specs": "10.2.10",
164
- "@directus/storage-driver-azure": "10.0.23",
165
- "@directus/storage-driver-cloudinary": "10.0.23",
166
- "@directus/storage-driver-gcs": "10.0.24",
167
164
  "@directus/storage": "10.1.0",
165
+ "@directus/storage-driver-azure": "10.0.24-rc.0",
166
+ "@directus/storage-driver-cloudinary": "10.0.24-rc.0",
167
+ "@directus/storage-driver-gcs": "10.0.25-rc.0",
168
168
  "@directus/storage-driver-local": "10.1.0",
169
- "@directus/storage-driver-s3": "10.1.0",
170
- "@directus/system-data": "1.1.0",
171
- "@directus/storage-driver-supabase": "1.0.15",
172
- "@directus/utils": "11.0.10",
173
- "@directus/validation": "0.0.18",
174
- "directus": "10.13.0"
169
+ "@directus/storage-driver-s3": "10.1.1-rc.0",
170
+ "@directus/storage-driver-supabase": "1.0.16-rc.0",
171
+ "@directus/validation": "0.0.19-rc.0",
172
+ "directus": "11.0.0-rc.3",
173
+ "@directus/system-data": "2.0.0-rc.1",
174
+ "@directus/utils": "12.0.0-rc.1"
175
175
  },
176
176
  "devDependencies": {
177
177
  "@ngneat/falso": "7.2.0",
@@ -185,7 +185,7 @@
185
185
  "@types/destroy": "1.0.3",
186
186
  "@types/encodeurl": "1.0.2",
187
187
  "@types/express": "4.17.21",
188
- "@types/express-serve-static-core": "4.19.3",
188
+ "@types/express-serve-static-core": "4.19.5",
189
189
  "@types/fs-extra": "11.0.4",
190
190
  "@types/glob-to-regexp": "0.4.4",
191
191
  "@types/inquirer": "9.0.7",
@@ -214,11 +214,11 @@
214
214
  "vitest": "1.5.3",
215
215
  "@directus/random": "0.2.8",
216
216
  "@directus/tsconfig": "1.0.1",
217
- "@directus/types": "11.2.0"
217
+ "@directus/types": "12.0.0-rc.1"
218
218
  },
219
219
  "optionalDependencies": {
220
- "@keyv/redis": "2.8.4",
221
- "mysql": "2.18.1",
220
+ "@keyv/redis": "2.8.5",
221
+ "mysql2": "3.10.0",
222
222
  "nodemailer-mailgun-transport": "2.1.5",
223
223
  "nodemailer-sendgrid": "1.0.3",
224
224
  "oracledb": "6.5.1",
@@ -233,6 +233,7 @@
233
233
  "build": "tsc --project tsconfig.prod.json && copyfiles \"src/**/*.{yaml,liquid}\" -u 1 dist",
234
234
  "cli": "NODE_ENV=development SERVE_APP=false tsx src/cli/run.ts",
235
235
  "dev": "NODE_ENV=development SERVE_APP=true tsx watch --ignore extensions --clear-screen=false src/start.ts",
236
- "test": "vitest --watch=false"
236
+ "test": "vitest run",
237
+ "test:watch": "vitest"
237
238
  }
238
239
  }
@@ -1,450 +0,0 @@
1
- import { useEnv } from '@directus/env';
2
- import { toArray } from '@directus/utils';
3
- import { clone, cloneDeep, isNil, merge, pick, uniq } from 'lodash-es';
4
- import { PayloadService } from '../services/payload.js';
5
- import { applyFunctionToColumnName } from '../utils/apply-function-to-column-name.js';
6
- import applyQuery, { applyLimit, applySort, generateAlias } from '../utils/apply-query.js';
7
- import { getCollectionFromAlias } from '../utils/get-collection-from-alias.js';
8
- import { getColumn } from '../utils/get-column.js';
9
- import { parseFilterKey } from '../utils/parse-filter-key.js';
10
- import { getHelpers } from './helpers/index.js';
11
- import getDatabase from './index.js';
12
- /**
13
- * Execute a given AST using Knex. Returns array of items based on requested AST.
14
- */
15
- export default async function runAST(originalAST, schema, options) {
16
- const ast = cloneDeep(originalAST);
17
- const knex = options?.knex || getDatabase();
18
- if (ast.type === 'a2o') {
19
- const results = {};
20
- for (const collection of ast.names) {
21
- results[collection] = await run(collection, ast.children[collection], ast.query[collection]);
22
- }
23
- return results;
24
- }
25
- else {
26
- return await run(ast.name, ast.children, options?.query || ast.query);
27
- }
28
- async function run(collection, children, query) {
29
- const env = useEnv();
30
- // Retrieve the database columns to select in the current AST
31
- const { fieldNodes, primaryKeyField, nestedCollectionNodes } = await parseCurrentLevel(schema, collection, children, query);
32
- // The actual knex query builder instance. This is a promise that resolves with the raw items from the db
33
- const dbQuery = await getDBQuery(schema, knex, collection, fieldNodes, query);
34
- const rawItems = await dbQuery;
35
- if (!rawItems)
36
- return null;
37
- // Run the items through the special transforms
38
- const payloadService = new PayloadService(collection, { knex, schema });
39
- let items = await payloadService.processValues('read', rawItems, query.alias ?? {});
40
- if (!items || (Array.isArray(items) && items.length === 0))
41
- return items;
42
- // Apply the `_in` filters to the nested collection batches
43
- const nestedNodes = applyParentFilters(schema, nestedCollectionNodes, items);
44
- for (const nestedNode of nestedNodes) {
45
- let nestedItems = [];
46
- if (nestedNode.type === 'o2m') {
47
- let hasMore = true;
48
- let batchCount = 0;
49
- while (hasMore) {
50
- const node = merge({}, nestedNode, {
51
- query: {
52
- limit: env['RELATIONAL_BATCH_SIZE'],
53
- offset: batchCount * env['RELATIONAL_BATCH_SIZE'],
54
- page: null,
55
- },
56
- });
57
- nestedItems = (await runAST(node, schema, { knex, nested: true }));
58
- if (nestedItems) {
59
- items = mergeWithParentItems(schema, nestedItems, items, nestedNode);
60
- }
61
- if (!nestedItems || nestedItems.length < env['RELATIONAL_BATCH_SIZE']) {
62
- hasMore = false;
63
- }
64
- batchCount++;
65
- }
66
- }
67
- else {
68
- const node = merge({}, nestedNode, {
69
- query: { limit: -1 },
70
- });
71
- nestedItems = (await runAST(node, schema, { knex, nested: true }));
72
- if (nestedItems) {
73
- // Merge all fetched nested records with the parent items
74
- items = mergeWithParentItems(schema, nestedItems, items, nestedNode);
75
- }
76
- }
77
- }
78
- // During the fetching of data, we have to inject a couple of required fields for the child nesting
79
- // to work (primary / foreign keys) even if they're not explicitly requested. After all fetching
80
- // and nesting is done, we parse through the output structure, and filter out all non-requested
81
- // fields
82
- if (options?.nested !== true && options?.stripNonRequested !== false) {
83
- items = removeTemporaryFields(schema, items, originalAST, primaryKeyField);
84
- }
85
- return items;
86
- }
87
- }
88
- async function parseCurrentLevel(schema, collection, children, query) {
89
- const primaryKeyField = schema.collections[collection].primary;
90
- const columnsInCollection = Object.keys(schema.collections[collection].fields);
91
- const columnsToSelectInternal = [];
92
- const nestedCollectionNodes = [];
93
- for (const child of children) {
94
- if (child.type === 'field' || child.type === 'functionField') {
95
- const { fieldName } = parseFilterKey(child.name);
96
- if (columnsInCollection.includes(fieldName)) {
97
- columnsToSelectInternal.push(child.fieldKey);
98
- }
99
- continue;
100
- }
101
- if (!child.relation)
102
- continue;
103
- if (child.type === 'm2o') {
104
- columnsToSelectInternal.push(child.relation.field);
105
- }
106
- if (child.type === 'a2o') {
107
- columnsToSelectInternal.push(child.relation.field);
108
- columnsToSelectInternal.push(child.relation.meta.one_collection_field);
109
- }
110
- nestedCollectionNodes.push(child);
111
- }
112
- const isAggregate = (query.group || (query.aggregate && Object.keys(query.aggregate).length > 0)) ?? false;
113
- /** Always fetch primary key in case there's a nested relation that needs it. Aggregate payloads
114
- * can't have nested relational fields
115
- */
116
- if (isAggregate === false && columnsToSelectInternal.includes(primaryKeyField) === false) {
117
- columnsToSelectInternal.push(primaryKeyField);
118
- }
119
- /** Make sure select list has unique values */
120
- const columnsToSelect = [...new Set(columnsToSelectInternal)];
121
- const fieldNodes = columnsToSelect.map((column) => children.find((childNode) => (childNode.type === 'field' || childNode.type === 'functionField') && childNode.fieldKey === column) ?? {
122
- type: 'field',
123
- name: column,
124
- fieldKey: column,
125
- });
126
- return { fieldNodes, nestedCollectionNodes, primaryKeyField };
127
- }
128
- function getColumnPreprocessor(knex, schema, table) {
129
- const helpers = getHelpers(knex);
130
- return function (fieldNode) {
131
- let alias = undefined;
132
- if (fieldNode.name !== fieldNode.fieldKey) {
133
- alias = fieldNode.fieldKey;
134
- }
135
- let field;
136
- if (fieldNode.type === 'field' || fieldNode.type === 'functionField') {
137
- const { fieldName } = parseFilterKey(fieldNode.name);
138
- field = schema.collections[table].fields[fieldName];
139
- }
140
- else {
141
- field = schema.collections[fieldNode.relation.collection].fields[fieldNode.relation.field];
142
- }
143
- if (field?.type?.startsWith('geometry')) {
144
- return helpers.st.asText(table, field.field);
145
- }
146
- if (fieldNode.type === 'functionField') {
147
- return getColumn(knex, table, fieldNode.name, alias, schema, { query: fieldNode.query });
148
- }
149
- return getColumn(knex, table, fieldNode.name, alias, schema);
150
- };
151
- }
152
- async function getDBQuery(schema, knex, table, fieldNodes, query) {
153
- const env = useEnv();
154
- const preProcess = getColumnPreprocessor(knex, schema, table);
155
- const queryCopy = clone(query);
156
- const helpers = getHelpers(knex);
157
- queryCopy.limit = typeof queryCopy.limit === 'number' ? queryCopy.limit : Number(env['QUERY_LIMIT_DEFAULT']);
158
- // Queries with aggregates and groupBy will not have duplicate result
159
- if (queryCopy.aggregate || queryCopy.group) {
160
- const flatQuery = knex.select(fieldNodes.map(preProcess)).from(table);
161
- return await applyQuery(knex, table, flatQuery, queryCopy, schema).query;
162
- }
163
- const primaryKey = schema.collections[table].primary;
164
- const aliasMap = Object.create(null);
165
- let dbQuery = knex.from(table);
166
- let sortRecords;
167
- const innerQuerySortRecords = [];
168
- let hasMultiRelationalSort;
169
- if (queryCopy.sort) {
170
- const sortResult = applySort(knex, schema, dbQuery, queryCopy, table, aliasMap, true);
171
- if (sortResult) {
172
- sortRecords = sortResult.sortRecords;
173
- hasMultiRelationalSort = sortResult.hasMultiRelationalSort;
174
- }
175
- }
176
- const { hasMultiRelationalFilter } = applyQuery(knex, table, dbQuery, queryCopy, schema, {
177
- aliasMap,
178
- isInnerQuery: true,
179
- hasMultiRelationalSort,
180
- });
181
- const needsInnerQuery = hasMultiRelationalSort || hasMultiRelationalFilter;
182
- if (needsInnerQuery) {
183
- dbQuery.select(`${table}.${primaryKey}`).distinct();
184
- }
185
- else {
186
- dbQuery.select(fieldNodes.map(preProcess));
187
- }
188
- if (sortRecords) {
189
- // Clears the order if any, eg: from MSSQL offset
190
- dbQuery.clear('order');
191
- if (needsInnerQuery) {
192
- let orderByString = '';
193
- const orderByFields = [];
194
- sortRecords.map((sortRecord) => {
195
- if (orderByString.length !== 0) {
196
- orderByString += ', ';
197
- }
198
- const sortAlias = `sort_${generateAlias()}`;
199
- if (sortRecord.column.includes('.')) {
200
- const [alias, field] = sortRecord.column.split('.');
201
- const originalCollectionName = getCollectionFromAlias(alias, aliasMap);
202
- dbQuery.select(getColumn(knex, alias, field, sortAlias, schema, { originalCollectionName }));
203
- orderByString += `?? ${sortRecord.order}`;
204
- orderByFields.push(getColumn(knex, alias, field, false, schema, { originalCollectionName }));
205
- }
206
- else {
207
- dbQuery.select(getColumn(knex, table, sortRecord.column, sortAlias, schema));
208
- orderByString += `?? ${sortRecord.order}`;
209
- orderByFields.push(getColumn(knex, table, sortRecord.column, false, schema));
210
- }
211
- innerQuerySortRecords.push({ alias: sortAlias, order: sortRecord.order });
212
- });
213
- dbQuery.orderByRaw(orderByString, orderByFields);
214
- if (hasMultiRelationalSort) {
215
- dbQuery = helpers.schema.applyMultiRelationalSort(knex, dbQuery, table, primaryKey, orderByString, orderByFields);
216
- }
217
- }
218
- else {
219
- sortRecords.map((sortRecord) => {
220
- if (sortRecord.column.includes('.')) {
221
- const [alias, field] = sortRecord.column.split('.');
222
- sortRecord.column = getColumn(knex, alias, field, false, schema, {
223
- originalCollectionName: getCollectionFromAlias(alias, aliasMap),
224
- });
225
- }
226
- else {
227
- sortRecord.column = getColumn(knex, table, sortRecord.column, false, schema);
228
- }
229
- });
230
- dbQuery.orderBy(sortRecords);
231
- }
232
- }
233
- if (!needsInnerQuery)
234
- return dbQuery;
235
- const wrapperQuery = knex
236
- .select(fieldNodes.map(preProcess))
237
- .from(table)
238
- .innerJoin(knex.raw('??', dbQuery.as('inner')), `${table}.${primaryKey}`, `inner.${primaryKey}`);
239
- if (sortRecords && needsInnerQuery) {
240
- innerQuerySortRecords.map((innerQuerySortRecord) => {
241
- wrapperQuery.orderBy(`inner.${innerQuerySortRecord.alias}`, innerQuerySortRecord.order);
242
- });
243
- if (hasMultiRelationalSort) {
244
- wrapperQuery.where('inner.directus_row_number', '=', 1);
245
- applyLimit(knex, wrapperQuery, queryCopy.limit);
246
- }
247
- }
248
- return wrapperQuery;
249
- }
250
- function applyParentFilters(schema, nestedCollectionNodes, parentItem) {
251
- const parentItems = toArray(parentItem);
252
- for (const nestedNode of nestedCollectionNodes) {
253
- if (!nestedNode.relation)
254
- continue;
255
- if (nestedNode.type === 'm2o') {
256
- const foreignField = schema.collections[nestedNode.relation.related_collection].primary;
257
- const foreignIds = uniq(parentItems.map((res) => res[nestedNode.relation.field])).filter((id) => !isNil(id));
258
- merge(nestedNode, { query: { filter: { [foreignField]: { _in: foreignIds } } } });
259
- }
260
- else if (nestedNode.type === 'o2m') {
261
- const relatedM2OisFetched = !!nestedNode.children.find((child) => {
262
- return child.type === 'field' && child.name === nestedNode.relation.field;
263
- });
264
- if (relatedM2OisFetched === false) {
265
- nestedNode.children.push({
266
- type: 'field',
267
- name: nestedNode.relation.field,
268
- fieldKey: nestedNode.relation.field,
269
- });
270
- }
271
- if (nestedNode.relation.meta?.sort_field) {
272
- nestedNode.children.push({
273
- type: 'field',
274
- name: nestedNode.relation.meta.sort_field,
275
- fieldKey: nestedNode.relation.meta.sort_field,
276
- });
277
- }
278
- const foreignField = nestedNode.relation.field;
279
- const foreignIds = uniq(parentItems.map((res) => res[nestedNode.parentKey])).filter((id) => !isNil(id));
280
- merge(nestedNode, { query: { filter: { [foreignField]: { _in: foreignIds } } } });
281
- }
282
- else if (nestedNode.type === 'a2o') {
283
- const keysPerCollection = {};
284
- for (const parentItem of parentItems) {
285
- const collection = parentItem[nestedNode.relation.meta.one_collection_field];
286
- if (!keysPerCollection[collection])
287
- keysPerCollection[collection] = [];
288
- keysPerCollection[collection].push(parentItem[nestedNode.relation.field]);
289
- }
290
- for (const relatedCollection of nestedNode.names) {
291
- const foreignField = nestedNode.relatedKey[relatedCollection];
292
- const foreignIds = uniq(keysPerCollection[relatedCollection]);
293
- merge(nestedNode, {
294
- query: { [relatedCollection]: { filter: { [foreignField]: { _in: foreignIds } }, limit: foreignIds.length } },
295
- });
296
- }
297
- }
298
- }
299
- return nestedCollectionNodes;
300
- }
301
- function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
302
- const env = useEnv();
303
- const nestedItems = toArray(nestedItem);
304
- const parentItems = clone(toArray(parentItem));
305
- if (nestedNode.type === 'm2o') {
306
- for (const parentItem of parentItems) {
307
- const itemChild = nestedItems.find((nestedItem) => {
308
- return (nestedItem[schema.collections[nestedNode.relation.related_collection].primary] ==
309
- parentItem[nestedNode.relation.field]);
310
- });
311
- parentItem[nestedNode.fieldKey] = itemChild || null;
312
- }
313
- }
314
- else if (nestedNode.type === 'o2m') {
315
- for (const parentItem of parentItems) {
316
- if (!parentItem[nestedNode.fieldKey])
317
- parentItem[nestedNode.fieldKey] = [];
318
- const itemChildren = nestedItems.filter((nestedItem) => {
319
- if (nestedItem === null)
320
- return false;
321
- if (Array.isArray(nestedItem[nestedNode.relation.field]))
322
- return true;
323
- return (nestedItem[nestedNode.relation.field] ==
324
- parentItem[schema.collections[nestedNode.relation.related_collection].primary] ||
325
- nestedItem[nestedNode.relation.field]?.[schema.collections[nestedNode.relation.related_collection].primary] == parentItem[schema.collections[nestedNode.relation.related_collection].primary]);
326
- });
327
- parentItem[nestedNode.fieldKey].push(...itemChildren);
328
- const limit = nestedNode.query.limit ?? Number(env['QUERY_LIMIT_DEFAULT']);
329
- if (nestedNode.query.page && nestedNode.query.page > 1) {
330
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(limit * (nestedNode.query.page - 1));
331
- }
332
- if (nestedNode.query.offset && nestedNode.query.offset >= 0) {
333
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(nestedNode.query.offset);
334
- }
335
- if (limit !== -1) {
336
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, limit);
337
- }
338
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].sort((a, b) => {
339
- // This is pre-filled in get-ast-from-query
340
- const sortField = nestedNode.query.sort[0];
341
- let column = sortField;
342
- let order = 'asc';
343
- if (sortField.startsWith('-')) {
344
- column = sortField.substring(1);
345
- order = 'desc';
346
- }
347
- if (a[column] === b[column])
348
- return 0;
349
- if (a[column] === null)
350
- return 1;
351
- if (b[column] === null)
352
- return -1;
353
- if (order === 'asc') {
354
- return a[column] < b[column] ? -1 : 1;
355
- }
356
- else {
357
- return a[column] < b[column] ? 1 : -1;
358
- }
359
- });
360
- }
361
- }
362
- else if (nestedNode.type === 'a2o') {
363
- for (const parentItem of parentItems) {
364
- if (!nestedNode.relation.meta?.one_collection_field) {
365
- parentItem[nestedNode.fieldKey] = null;
366
- continue;
367
- }
368
- const relatedCollection = parentItem[nestedNode.relation.meta.one_collection_field];
369
- if (!nestedItem[relatedCollection]) {
370
- parentItem[nestedNode.fieldKey] = null;
371
- continue;
372
- }
373
- const itemChild = nestedItem[relatedCollection].find((nestedItem) => {
374
- return nestedItem[nestedNode.relatedKey[relatedCollection]] == parentItem[nestedNode.fieldKey];
375
- });
376
- parentItem[nestedNode.fieldKey] = itemChild || null;
377
- }
378
- }
379
- return Array.isArray(parentItem) ? parentItems : parentItems[0];
380
- }
381
- function removeTemporaryFields(schema, rawItem, ast, primaryKeyField, parentItem) {
382
- const rawItems = cloneDeep(toArray(rawItem));
383
- const items = [];
384
- if (ast.type === 'a2o') {
385
- const fields = {};
386
- const nestedCollectionNodes = {};
387
- for (const relatedCollection of ast.names) {
388
- if (!fields[relatedCollection])
389
- fields[relatedCollection] = [];
390
- if (!nestedCollectionNodes[relatedCollection])
391
- nestedCollectionNodes[relatedCollection] = [];
392
- for (const child of ast.children[relatedCollection]) {
393
- if (child.type === 'field' || child.type === 'functionField') {
394
- fields[relatedCollection].push(child.name);
395
- }
396
- else {
397
- fields[relatedCollection].push(child.fieldKey);
398
- nestedCollectionNodes[relatedCollection].push(child);
399
- }
400
- }
401
- }
402
- for (const rawItem of rawItems) {
403
- const relatedCollection = parentItem?.[ast.relation.meta.one_collection_field];
404
- if (rawItem === null || rawItem === undefined)
405
- return rawItem;
406
- let item = rawItem;
407
- for (const nestedNode of nestedCollectionNodes[relatedCollection]) {
408
- item[nestedNode.fieldKey] = removeTemporaryFields(schema, item[nestedNode.fieldKey], nestedNode, schema.collections[nestedNode.relation.collection].primary, item);
409
- }
410
- const fieldsWithFunctionsApplied = fields[relatedCollection].map((field) => applyFunctionToColumnName(field));
411
- item =
412
- fields[relatedCollection].length > 0 ? pick(rawItem, fieldsWithFunctionsApplied) : rawItem[primaryKeyField];
413
- items.push(item);
414
- }
415
- }
416
- else {
417
- const fields = [];
418
- const nestedCollectionNodes = [];
419
- for (const child of ast.children) {
420
- fields.push(child.fieldKey);
421
- if (child.type !== 'field' && child.type !== 'functionField') {
422
- nestedCollectionNodes.push(child);
423
- }
424
- }
425
- // Make sure any requested aggregate fields are included
426
- if (ast.query?.aggregate) {
427
- for (const [operation, aggregateFields] of Object.entries(ast.query.aggregate)) {
428
- if (!fields)
429
- continue;
430
- if (operation === 'count' && aggregateFields.includes('*'))
431
- fields.push('count');
432
- fields.push(...aggregateFields.map((field) => `${operation}.${field}`));
433
- }
434
- }
435
- for (const rawItem of rawItems) {
436
- if (rawItem === null || rawItem === undefined)
437
- return rawItem;
438
- let item = rawItem;
439
- for (const nestedNode of nestedCollectionNodes) {
440
- item[nestedNode.fieldKey] = removeTemporaryFields(schema, item[nestedNode.fieldKey], nestedNode, nestedNode.type === 'm2o'
441
- ? schema.collections[nestedNode.relation.related_collection].primary
442
- : schema.collections[nestedNode.relation.collection].primary, item);
443
- }
444
- const fieldsWithFunctionsApplied = fields.map((field) => applyFunctionToColumnName(field));
445
- item = fields.length > 0 ? pick(rawItem, fieldsWithFunctionsApplied) : rawItem[primaryKeyField];
446
- items.push(item);
447
- }
448
- }
449
- return Array.isArray(rawItem) ? items : items[0];
450
- }
@@ -1,2 +0,0 @@
1
- import type { RequestHandler } from 'express';
2
- export declare const checkIP: RequestHandler;
@@ -1,37 +0,0 @@
1
- import { InvalidIpError } from '@directus/errors';
2
- import getDatabase from '../database/index.js';
3
- import { useLogger } from '../logger.js';
4
- import asyncHandler from '../utils/async-handler.js';
5
- import { ipInNetworks } from '../utils/ip-in-networks.js';
6
- export const checkIP = asyncHandler(async (req, _res, next) => {
7
- const database = getDatabase();
8
- const logger = useLogger();
9
- const { role: roleId, ip } = req.accountability;
10
- const query = database.select('ip_access').from('directus_roles');
11
- if (roleId) {
12
- query.where({ id: roleId });
13
- }
14
- else {
15
- query.whereNull('id');
16
- }
17
- const role = await query.first();
18
- if (!role?.ip_access)
19
- return next();
20
- const ipAllowList = role.ip_access.split(',').filter((ip) => ip);
21
- if (ipAllowList.length > 0) {
22
- if (!ip)
23
- throw new InvalidIpError();
24
- let allowed;
25
- try {
26
- allowed = ipInNetworks(ip, ipAllowList);
27
- }
28
- catch (error) {
29
- logger.warn(`Invalid IP access configuration for role "${roleId}"`);
30
- logger.warn(error);
31
- throw new InvalidIpError();
32
- }
33
- if (!allowed)
34
- throw new InvalidIpError();
35
- }
36
- return next();
37
- });
@@ -1,3 +0,0 @@
1
- import type { RequestHandler } from 'express';
2
- declare const getPermissions: RequestHandler;
3
- export default getPermissions;
@@ -1,10 +0,0 @@
1
- import asyncHandler from '../utils/async-handler.js';
2
- import { getPermissions as getPermissionsUtil } from '../utils/get-permissions.js';
3
- const getPermissions = asyncHandler(async (req, _res, next) => {
4
- if (!req.accountability) {
5
- throw new Error('getPermissions middleware needs to be called after authenticate');
6
- }
7
- req.accountability.permissions = await getPermissionsUtil(req.accountability, req.schema);
8
- return next();
9
- });
10
- export default getPermissions;
@@ -1,17 +0,0 @@
1
- import type { Accountability, Item, PermissionsAction, PrimaryKey, SchemaOverview } from '@directus/types';
2
- import type { Knex } from 'knex';
3
- import type { AST, AbstractServiceOptions } from '../types/index.js';
4
- import { PayloadService } from './payload.js';
5
- export declare class AuthorizationService {
6
- knex: Knex;
7
- accountability: Accountability | null;
8
- payloadService: PayloadService;
9
- schema: SchemaOverview;
10
- constructor(options: AbstractServiceOptions);
11
- processAST(ast: AST, action?: PermissionsAction): Promise<AST>;
12
- /**
13
- * Checks if the provided payload matches the configured permissions, and adds the presets to the payload.
14
- */
15
- validatePayload(action: PermissionsAction, collection: string, data: Partial<Item>): Partial<Item>;
16
- checkAccess(action: PermissionsAction, collection: string, pk?: PrimaryKey | PrimaryKey[]): Promise<void>;
17
- }