directus 9.22.4 → 9.23.3

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 (404) hide show
  1. package/dist/app.js +19 -14
  2. package/dist/auth/auth.d.ts +3 -3
  3. package/dist/auth/auth.js +2 -0
  4. package/dist/auth/drivers/ldap.d.ts +2 -2
  5. package/dist/auth/drivers/ldap.js +47 -36
  6. package/dist/auth/drivers/local.d.ts +1 -1
  7. package/dist/auth/drivers/local.js +13 -10
  8. package/dist/auth/drivers/oauth2.d.ts +1 -1
  9. package/dist/auth/drivers/oauth2.js +22 -15
  10. package/dist/auth/drivers/openid.d.ts +1 -1
  11. package/dist/auth/drivers/openid.js +23 -16
  12. package/dist/auth/drivers/saml.d.ts +1 -1
  13. package/dist/auth/drivers/saml.js +10 -7
  14. package/dist/auth.d.ts +1 -1
  15. package/dist/auth.js +4 -4
  16. package/dist/cache.d.ts +9 -1
  17. package/dist/cache.js +59 -16
  18. package/dist/cli/commands/bootstrap/index.js +2 -2
  19. package/dist/cli/commands/init/index.js +3 -3
  20. package/dist/cli/commands/schema/apply.js +21 -20
  21. package/dist/cli/commands/schema/snapshot.js +2 -2
  22. package/dist/cli/utils/create-db-connection.d.ts +2 -1
  23. package/dist/cli/utils/create-db-connection.js +2 -1
  24. package/dist/cli/utils/create-env/env-stub.liquid +1 -1
  25. package/dist/cli/utils/create-env/index.d.ts +2 -2
  26. package/dist/cli/utils/drivers.d.ts +3 -9
  27. package/dist/constants.d.ts +3 -9
  28. package/dist/constants.js +5 -10
  29. package/dist/controllers/activity.js +1 -2
  30. package/dist/controllers/assets.js +17 -12
  31. package/dist/controllers/auth.js +29 -15
  32. package/dist/controllers/dashboards.js +5 -2
  33. package/dist/controllers/extensions.js +7 -7
  34. package/dist/controllers/fields.js +4 -4
  35. package/dist/controllers/files.js +11 -6
  36. package/dist/controllers/flows.js +5 -2
  37. package/dist/controllers/folders.js +5 -2
  38. package/dist/controllers/graphql.js +6 -0
  39. package/dist/controllers/items.js +5 -2
  40. package/dist/controllers/not-found.d.ts +1 -1
  41. package/dist/controllers/not-found.js +1 -2
  42. package/dist/controllers/notifications.js +5 -2
  43. package/dist/controllers/operations.js +5 -2
  44. package/dist/controllers/panels.js +5 -2
  45. package/dist/controllers/permissions.js +5 -2
  46. package/dist/controllers/presets.js +5 -2
  47. package/dist/controllers/roles.js +5 -2
  48. package/dist/controllers/schema.d.ts +2 -0
  49. package/dist/controllers/schema.js +98 -0
  50. package/dist/controllers/shares.js +8 -5
  51. package/dist/controllers/users.js +16 -20
  52. package/dist/controllers/utils.js +6 -11
  53. package/dist/controllers/webhooks.js +5 -2
  54. package/dist/database/helpers/fn/dialects/mssql.d.ts +1 -1
  55. package/dist/database/helpers/fn/dialects/mssql.js +10 -11
  56. package/dist/database/helpers/fn/dialects/mysql.d.ts +1 -1
  57. package/dist/database/helpers/fn/dialects/mysql.js +2 -3
  58. package/dist/database/helpers/fn/dialects/oracle.d.ts +1 -1
  59. package/dist/database/helpers/fn/dialects/oracle.js +10 -11
  60. package/dist/database/helpers/fn/dialects/postgres.d.ts +1 -1
  61. package/dist/database/helpers/fn/dialects/postgres.js +10 -11
  62. package/dist/database/helpers/fn/dialects/sqlite.d.ts +1 -1
  63. package/dist/database/helpers/fn/dialects/sqlite.js +10 -11
  64. package/dist/database/helpers/fn/types.d.ts +5 -5
  65. package/dist/database/helpers/fn/types.js +5 -4
  66. package/dist/database/helpers/geometry/dialects/mssql.d.ts +3 -3
  67. package/dist/database/helpers/geometry/dialects/mysql.d.ts +1 -1
  68. package/dist/database/helpers/geometry/dialects/oracle.d.ts +3 -3
  69. package/dist/database/helpers/geometry/dialects/postgres.d.ts +3 -3
  70. package/dist/database/helpers/geometry/dialects/postgres.js +1 -2
  71. package/dist/database/helpers/geometry/dialects/redshift.d.ts +2 -2
  72. package/dist/database/helpers/geometry/dialects/sqlite.d.ts +1 -1
  73. package/dist/database/helpers/geometry/types.d.ts +2 -2
  74. package/dist/database/helpers/geometry/types.js +1 -2
  75. package/dist/database/helpers/index.d.ts +5 -5
  76. package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +2 -2
  77. package/dist/database/helpers/schema/dialects/mssql.d.ts +1 -1
  78. package/dist/database/helpers/schema/dialects/mysql.d.ts +1 -1
  79. package/dist/database/helpers/schema/dialects/mysql.js +1 -2
  80. package/dist/database/helpers/schema/dialects/oracle.d.ts +5 -2
  81. package/dist/database/helpers/schema/dialects/oracle.js +23 -0
  82. package/dist/database/helpers/schema/types.d.ts +9 -7
  83. package/dist/database/helpers/schema/types.js +7 -1
  84. package/dist/database/helpers/types.d.ts +1 -1
  85. package/dist/database/helpers/types.js +1 -0
  86. package/dist/database/index.d.ts +2 -1
  87. package/dist/database/index.js +8 -8
  88. package/dist/database/migrations/20201028A-remove-collection-foreign-keys.d.ts +1 -1
  89. package/dist/database/migrations/20201029A-remove-system-relations.d.ts +1 -1
  90. package/dist/database/migrations/20201029B-remove-system-collections.d.ts +1 -1
  91. package/dist/database/migrations/20201029C-remove-system-fields.d.ts +1 -1
  92. package/dist/database/migrations/20201105A-add-cascade-system-relations.d.ts +1 -1
  93. package/dist/database/migrations/20201105B-change-webhook-url-type.d.ts +1 -1
  94. package/dist/database/migrations/20210225A-add-relations-sort-field.d.ts +1 -1
  95. package/dist/database/migrations/20210225A-add-relations-sort-field.js +1 -2
  96. package/dist/database/migrations/20210304A-remove-locked-fields.d.ts +1 -1
  97. package/dist/database/migrations/20210312A-webhooks-collections-text.d.ts +1 -1
  98. package/dist/database/migrations/20210331A-add-refresh-interval.d.ts +1 -1
  99. package/dist/database/migrations/20210415A-make-filesize-nullable.d.ts +1 -1
  100. package/dist/database/migrations/20210416A-add-collections-accountability.d.ts +1 -1
  101. package/dist/database/migrations/20210422A-remove-files-interface.d.ts +1 -1
  102. package/dist/database/migrations/20210506A-rename-interfaces.d.ts +1 -1
  103. package/dist/database/migrations/20210510A-restructure-relations.d.ts +1 -1
  104. package/dist/database/migrations/20210518A-add-foreign-key-constraints.d.ts +1 -1
  105. package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
  106. package/dist/database/migrations/20210519A-add-system-fk-triggers.d.ts +1 -1
  107. package/dist/database/migrations/20210519A-add-system-fk-triggers.js +2 -2
  108. package/dist/database/migrations/20210521A-add-collections-icon-color.d.ts +1 -1
  109. package/dist/database/migrations/20210525A-add-insights.d.ts +1 -1
  110. package/dist/database/migrations/20210608A-add-deep-clone-config.d.ts +1 -1
  111. package/dist/database/migrations/20210626A-change-filesize-bigint.d.ts +1 -1
  112. package/dist/database/migrations/20210716A-add-conditions-to-fields.d.ts +1 -1
  113. package/dist/database/migrations/20210721A-add-default-folder.d.ts +1 -1
  114. package/dist/database/migrations/20210802A-replace-groups.d.ts +1 -1
  115. package/dist/database/migrations/20210803A-add-required-to-fields.d.ts +1 -1
  116. package/dist/database/migrations/20210805A-update-groups.d.ts +1 -1
  117. package/dist/database/migrations/20210805B-change-image-metadata-structure.d.ts +1 -1
  118. package/dist/database/migrations/20210811A-add-geometry-config.d.ts +1 -1
  119. package/dist/database/migrations/20210831A-remove-limit-column.d.ts +1 -1
  120. package/dist/database/migrations/20210903A-add-auth-provider.d.ts +1 -1
  121. package/dist/database/migrations/20210907A-webhooks-collections-not-null.d.ts +1 -1
  122. package/dist/database/migrations/20210910A-move-module-setup.d.ts +1 -1
  123. package/dist/database/migrations/20210920A-webhooks-url-not-null.d.ts +1 -1
  124. package/dist/database/migrations/20210924A-add-collection-organization.d.ts +1 -1
  125. package/dist/database/migrations/20210927A-replace-fields-group.d.ts +1 -1
  126. package/dist/database/migrations/20210927B-replace-m2m-interface.d.ts +1 -1
  127. package/dist/database/migrations/20210929A-rename-login-action.d.ts +1 -1
  128. package/dist/database/migrations/20211007A-update-presets.d.ts +1 -1
  129. package/dist/database/migrations/20211007A-update-presets.js +7 -9
  130. package/dist/database/migrations/20211009A-add-auth-data.d.ts +1 -1
  131. package/dist/database/migrations/20211016A-add-webhook-headers.d.ts +1 -1
  132. package/dist/database/migrations/20211103A-set-unique-to-user-token.d.ts +1 -1
  133. package/dist/database/migrations/20211103B-update-special-geometry.d.ts +1 -1
  134. package/dist/database/migrations/20211104A-remove-collections-listing.d.ts +1 -1
  135. package/dist/database/migrations/20211118A-add-notifications.d.ts +1 -1
  136. package/dist/database/migrations/20211211A-add-shares.d.ts +1 -1
  137. package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +1 -1
  138. package/dist/database/migrations/20220303A-remove-default-project-color.d.ts +1 -1
  139. package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +1 -1
  140. package/dist/database/migrations/20220314A-add-translation-strings.d.ts +1 -1
  141. package/dist/database/migrations/20220322A-rename-field-typecast-flags.d.ts +1 -1
  142. package/dist/database/migrations/20220323A-add-field-validation.d.ts +1 -1
  143. package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +1 -1
  144. package/dist/database/migrations/20220325B-add-default-language.d.ts +1 -1
  145. package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +1 -1
  146. package/dist/database/migrations/20220429A-add-flows.d.ts +1 -1
  147. package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +1 -1
  148. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +1 -1
  149. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +1 -1
  150. package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +1 -1
  151. package/dist/database/migrations/20220801A-update-notifications-timestamp-column.d.ts +1 -1
  152. package/dist/database/migrations/20220802A-add-custom-aspect-ratios.d.ts +1 -1
  153. package/dist/database/migrations/20220826A-add-origin-to-accountability.d.ts +1 -1
  154. package/dist/database/migrations/run.d.ts +1 -1
  155. package/dist/database/run-ast.d.ts +3 -3
  156. package/dist/database/run-ast.js +19 -28
  157. package/dist/database/seeds/run.d.ts +1 -1
  158. package/dist/database/seeds/run.js +1 -2
  159. package/dist/database/system-data/app-access-permissions/index.d.ts +1 -1
  160. package/dist/database/system-data/collections/index.d.ts +1 -1
  161. package/dist/database/system-data/fields/collections.yaml +2 -0
  162. package/dist/database/system-data/fields/index.d.ts +1 -1
  163. package/dist/database/system-data/fields/index.js +1 -2
  164. package/dist/database/system-data/fields/settings.yaml +4 -0
  165. package/dist/database/system-data/relations/index.d.ts +1 -1
  166. package/dist/emitter.d.ts +1 -1
  167. package/dist/emitter.js +3 -0
  168. package/dist/env.js +19 -4
  169. package/dist/exceptions/database/dialects/mssql.d.ts +1 -1
  170. package/dist/exceptions/database/dialects/mssql.js +5 -6
  171. package/dist/exceptions/database/dialects/mysql.d.ts +1 -1
  172. package/dist/exceptions/database/dialects/mysql.js +19 -25
  173. package/dist/exceptions/database/dialects/oracle.d.ts +1 -1
  174. package/dist/exceptions/database/dialects/postgres.d.ts +1 -1
  175. package/dist/exceptions/database/dialects/sqlite.d.ts +1 -1
  176. package/dist/exceptions/database/translate.d.ts +1 -1
  177. package/dist/exceptions/database/value-out-of-range.js +1 -1
  178. package/dist/exceptions/range-not-satisfiable.js +2 -3
  179. package/dist/extensions.d.ts +1 -1
  180. package/dist/extensions.js +34 -24
  181. package/dist/flows.js +56 -30
  182. package/dist/logger.d.ts +1 -1
  183. package/dist/logger.js +19 -3
  184. package/dist/messenger.js +8 -6
  185. package/dist/middleware/authenticate.d.ts +1 -1
  186. package/dist/middleware/authenticate.js +12 -5
  187. package/dist/middleware/cache.d.ts +1 -1
  188. package/dist/middleware/cache.js +7 -7
  189. package/dist/middleware/check-ip.d.ts +1 -1
  190. package/dist/middleware/check-ip.js +1 -1
  191. package/dist/middleware/collection-exists.d.ts +1 -1
  192. package/dist/middleware/collection-exists.js +2 -2
  193. package/dist/middleware/cors.d.ts +1 -1
  194. package/dist/middleware/error-handler.d.ts +1 -1
  195. package/dist/middleware/error-handler.js +9 -10
  196. package/dist/middleware/extract-token.d.ts +1 -1
  197. package/dist/middleware/get-permissions.d.ts +1 -1
  198. package/dist/middleware/graphql.d.ts +1 -1
  199. package/dist/middleware/graphql.js +3 -3
  200. package/dist/middleware/rate-limiter-global.d.ts +5 -0
  201. package/dist/middleware/rate-limiter-global.js +48 -0
  202. package/dist/middleware/{rate-limiter.d.ts → rate-limiter-ip.d.ts} +2 -2
  203. package/dist/middleware/{rate-limiter.js → rate-limiter-ip.js} +3 -3
  204. package/dist/middleware/respond.d.ts +1 -1
  205. package/dist/middleware/respond.js +18 -14
  206. package/dist/middleware/sanitize-query.d.ts +1 -1
  207. package/dist/middleware/schema.d.ts +1 -1
  208. package/dist/middleware/use-collection.d.ts +1 -1
  209. package/dist/operations/condition/index.d.ts +1 -1
  210. package/dist/operations/exec/index.js +14 -3
  211. package/dist/operations/item-create/index.js +1 -2
  212. package/dist/operations/item-delete/index.d.ts +1 -1
  213. package/dist/operations/item-read/index.d.ts +1 -1
  214. package/dist/operations/item-update/index.d.ts +1 -1
  215. package/dist/operations/item-update/index.js +1 -2
  216. package/dist/operations/notification/index.js +1 -2
  217. package/dist/operations/request/index.js +21 -20
  218. package/dist/operations/trigger/index.d.ts +2 -0
  219. package/dist/operations/trigger/index.js +27 -11
  220. package/dist/rate-limiter.d.ts +1 -1
  221. package/dist/rate-limiter.js +8 -8
  222. package/dist/request/index.d.ts +5 -0
  223. package/dist/request/index.js +18 -0
  224. package/dist/request/index.test.d.ts +1 -0
  225. package/dist/request/request-interceptor.d.ts +2 -0
  226. package/dist/request/request-interceptor.js +33 -0
  227. package/dist/request/request-interceptor.test.d.ts +1 -0
  228. package/dist/request/response-interceptor.d.ts +2 -0
  229. package/dist/request/response-interceptor.js +9 -0
  230. package/dist/request/response-interceptor.test.d.ts +1 -0
  231. package/dist/request/validate-ip.d.ts +1 -0
  232. package/dist/request/validate-ip.js +27 -0
  233. package/dist/request/validate-ip.test.d.ts +1 -0
  234. package/dist/server.js +8 -9
  235. package/dist/services/activity.d.ts +1 -1
  236. package/dist/services/activity.js +7 -6
  237. package/dist/services/assets.d.ts +3 -3
  238. package/dist/services/assets.js +33 -26
  239. package/dist/services/authentication.d.ts +2 -2
  240. package/dist/services/authentication.js +18 -15
  241. package/dist/services/authorization.d.ts +3 -3
  242. package/dist/services/authorization.js +27 -31
  243. package/dist/services/collections.d.ts +5 -5
  244. package/dist/services/collections.js +52 -48
  245. package/dist/services/dashboards.d.ts +1 -1
  246. package/dist/services/fields.d.ts +5 -5
  247. package/dist/services/fields.js +49 -48
  248. package/dist/services/files.d.ts +1 -2
  249. package/dist/services/files.js +70 -108
  250. package/dist/services/flows.d.ts +2 -2
  251. package/dist/services/folders.d.ts +1 -1
  252. package/dist/services/graphql/index.d.ts +4 -4
  253. package/dist/services/graphql/index.js +181 -170
  254. package/dist/services/graphql/utils/add-path-to-validation-error.js +1 -2
  255. package/dist/services/graphql/utils/process-error.d.ts +2 -2
  256. package/dist/services/graphql/utils/process-error.js +29 -9
  257. package/dist/services/import-export.d.ts +7 -5
  258. package/dist/services/import-export.js +41 -24
  259. package/dist/services/import-export.test.d.ts +1 -0
  260. package/dist/services/index.d.ts +1 -0
  261. package/dist/services/index.js +1 -0
  262. package/dist/services/items.d.ts +3 -3
  263. package/dist/services/items.js +67 -42
  264. package/dist/services/mail/index.d.ts +4 -4
  265. package/dist/services/mail/index.js +9 -5
  266. package/dist/services/meta.d.ts +3 -3
  267. package/dist/services/meta.js +10 -9
  268. package/dist/services/notifications.d.ts +3 -3
  269. package/dist/services/notifications.js +7 -6
  270. package/dist/services/operations.d.ts +2 -2
  271. package/dist/services/panels.d.ts +1 -1
  272. package/dist/services/payload.d.ts +3 -3
  273. package/dist/services/payload.js +124 -122
  274. package/dist/services/permissions.d.ts +3 -3
  275. package/dist/services/permissions.js +11 -11
  276. package/dist/services/presets.d.ts +1 -1
  277. package/dist/services/relations.d.ts +6 -6
  278. package/dist/services/relations.js +47 -43
  279. package/dist/services/revisions.d.ts +1 -1
  280. package/dist/services/roles.d.ts +2 -2
  281. package/dist/services/roles.js +34 -13
  282. package/dist/services/schema.d.ts +15 -0
  283. package/dist/services/schema.js +56 -0
  284. package/dist/services/schema.test.d.ts +1 -0
  285. package/dist/services/server.d.ts +3 -3
  286. package/dist/services/server.js +69 -13
  287. package/dist/services/settings.d.ts +1 -1
  288. package/dist/services/shares.d.ts +2 -2
  289. package/dist/services/shares.js +14 -15
  290. package/dist/services/specifications.d.ts +4 -4
  291. package/dist/services/specifications.js +132 -116
  292. package/dist/services/tfa.d.ts +2 -2
  293. package/dist/services/tfa.js +7 -5
  294. package/dist/services/users.d.ts +3 -3
  295. package/dist/services/users.js +89 -62
  296. package/dist/services/utils.d.ts +3 -3
  297. package/dist/services/utils.js +10 -8
  298. package/dist/services/webhooks.d.ts +2 -2
  299. package/dist/services/webhooks.js +2 -1
  300. package/dist/types/assets.d.ts +2 -2
  301. package/dist/types/ast.d.ts +1 -1
  302. package/dist/types/auth.d.ts +2 -2
  303. package/dist/types/collection.d.ts +2 -2
  304. package/dist/types/database.d.ts +3 -0
  305. package/dist/types/database.js +4 -0
  306. package/dist/types/events.d.ts +2 -2
  307. package/dist/types/graphql.d.ts +2 -2
  308. package/dist/types/index.d.ts +1 -0
  309. package/dist/types/index.js +1 -0
  310. package/dist/types/items.d.ts +7 -2
  311. package/dist/types/services.d.ts +5 -5
  312. package/dist/types/snapshot.d.ts +25 -3
  313. package/dist/types/snapshot.js +14 -0
  314. package/dist/utils/apply-diff.d.ts +9 -0
  315. package/dist/utils/apply-diff.js +256 -0
  316. package/dist/utils/apply-diff.test.d.ts +1 -0
  317. package/dist/utils/apply-query.d.ts +3 -3
  318. package/dist/utils/apply-query.js +15 -16
  319. package/dist/utils/apply-snapshot.d.ts +3 -5
  320. package/dist/utils/apply-snapshot.js +9 -240
  321. package/dist/utils/construct-flow-tree.d.ts +1 -1
  322. package/dist/utils/construct-flow-tree.js +2 -2
  323. package/dist/utils/filter-items.d.ts +1 -1
  324. package/dist/utils/get-accountability-for-role.d.ts +2 -2
  325. package/dist/utils/get-accountability-for-role.js +1 -1
  326. package/dist/utils/get-ast-from-query.d.ts +3 -3
  327. package/dist/utils/get-ast-from-query.js +22 -28
  328. package/dist/utils/get-cache-headers.d.ts +4 -2
  329. package/dist/utils/get-cache-headers.js +21 -21
  330. package/dist/utils/get-cache-headers.test.d.ts +1 -0
  331. package/dist/utils/get-cache-key.d.ts +1 -1
  332. package/dist/utils/get-cache-key.js +2 -3
  333. package/dist/utils/get-collection-from-alias.d.ts +1 -1
  334. package/dist/utils/get-column-path.d.ts +2 -2
  335. package/dist/utils/get-column-path.js +3 -4
  336. package/dist/utils/get-column.d.ts +4 -4
  337. package/dist/utils/get-column.js +4 -5
  338. package/dist/utils/get-default-value.d.ts +2 -2
  339. package/dist/utils/get-default-value.js +1 -2
  340. package/dist/utils/get-graphql-query-and-variables.d.ts +1 -1
  341. package/dist/utils/get-graphql-query-and-variables.js +1 -2
  342. package/dist/utils/get-graphql-type.d.ts +2 -2
  343. package/dist/utils/get-graphql-type.js +1 -1
  344. package/dist/utils/get-ip-from-req.d.ts +1 -1
  345. package/dist/utils/get-local-type.d.ts +1 -1
  346. package/dist/utils/get-local-type.js +3 -3
  347. package/dist/utils/get-milliseconds.d.ts +4 -0
  348. package/dist/utils/get-milliseconds.js +14 -0
  349. package/dist/utils/get-milliseconds.test.d.ts +1 -0
  350. package/dist/utils/get-permissions.d.ts +1 -1
  351. package/dist/utils/get-permissions.js +1 -1
  352. package/dist/utils/get-relation-info.d.ts +1 -1
  353. package/dist/utils/get-relation-info.js +3 -5
  354. package/dist/utils/get-relation-type.d.ts +1 -1
  355. package/dist/utils/get-relation-type.js +3 -4
  356. package/dist/utils/get-schema.d.ts +2 -2
  357. package/dist/utils/get-schema.js +19 -21
  358. package/dist/utils/get-snapshot-diff.js +10 -7
  359. package/dist/utils/get-snapshot.d.ts +3 -3
  360. package/dist/utils/get-snapshot.js +35 -14
  361. package/dist/utils/get-versioned-hash.d.ts +1 -0
  362. package/dist/utils/get-versioned-hash.js +12 -0
  363. package/dist/utils/get-versioned-hash.test.d.ts +1 -0
  364. package/dist/utils/is-directus-jwt.js +1 -1
  365. package/dist/utils/job-queue.js +2 -0
  366. package/dist/utils/jwt.d.ts +1 -1
  367. package/dist/utils/map-values-deep.d.ts +1 -0
  368. package/dist/utils/map-values-deep.js +29 -0
  369. package/dist/utils/map-values-deep.test.d.ts +1 -0
  370. package/dist/utils/merge-permissions-for-share.d.ts +1 -1
  371. package/dist/utils/merge-permissions-for-share.js +3 -4
  372. package/dist/utils/merge-permissions.d.ts +3 -3
  373. package/dist/utils/redact-header-cookies.d.ts +1 -0
  374. package/dist/utils/redact-header-cookies.js +11 -0
  375. package/dist/utils/redact-header-cookies.test.d.ts +1 -0
  376. package/dist/utils/reduce-schema.d.ts +1 -1
  377. package/dist/utils/reduce-schema.js +12 -12
  378. package/dist/utils/sanitize-query.d.ts +1 -1
  379. package/dist/utils/sanitize-query.js +1 -1
  380. package/dist/utils/sanitize-schema.d.ts +30 -0
  381. package/dist/utils/sanitize-schema.js +80 -0
  382. package/dist/utils/sanitize-schema.test.d.ts +1 -0
  383. package/dist/utils/should-skip-cache.d.ts +7 -0
  384. package/dist/utils/should-skip-cache.js +21 -0
  385. package/dist/utils/should-skip-cache.test.d.ts +1 -0
  386. package/dist/utils/track.js +3 -3
  387. package/dist/utils/transformations.d.ts +1 -1
  388. package/dist/utils/transformations.js +2 -4
  389. package/dist/utils/url.js +9 -8
  390. package/dist/utils/url.test.d.ts +1 -0
  391. package/dist/utils/user-name.d.ts +1 -1
  392. package/dist/utils/validate-diff.d.ts +7 -0
  393. package/dist/utils/validate-diff.js +113 -0
  394. package/dist/utils/validate-diff.test.d.ts +1 -0
  395. package/dist/utils/validate-keys.d.ts +2 -2
  396. package/dist/utils/validate-keys.js +1 -1
  397. package/dist/utils/validate-query.d.ts +1 -1
  398. package/dist/utils/validate-query.js +3 -3
  399. package/dist/utils/validate-query.test.d.ts +1 -0
  400. package/dist/utils/validate-snapshot.d.ts +5 -0
  401. package/dist/utils/validate-snapshot.js +71 -0
  402. package/dist/utils/validate-snapshot.test.d.ts +1 -0
  403. package/dist/webhooks.js +4 -3
  404. package/package.json +62 -62
@@ -27,19 +27,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.RelationsService = void 0;
30
- const relations_1 = require("../database/system-data/relations");
31
- const exceptions_1 = require("../exceptions");
32
- const utils_1 = require("@directus/shared/utils");
33
- const items_1 = require("./items");
34
- const permissions_1 = require("./permissions");
35
30
  const schema_1 = __importDefault(require("@directus/schema"));
36
- const database_1 = __importStar(require("../database"));
37
- const get_default_index_name_1 = require("../utils/get-default-index-name");
31
+ const utils_1 = require("@directus/shared/utils");
38
32
  const cache_1 = require("../cache");
33
+ const database_1 = __importStar(require("../database"));
39
34
  const helpers_1 = require("../database/helpers");
35
+ const relations_1 = require("../database/system-data/relations");
40
36
  const emitter_1 = __importDefault(require("../emitter"));
37
+ const exceptions_1 = require("../exceptions");
38
+ const get_default_index_name_1 = require("../utils/get-default-index-name");
41
39
  const get_schema_1 = require("../utils/get-schema");
40
+ const items_1 = require("./items");
41
+ const permissions_1 = require("./permissions");
42
42
  class RelationsService {
43
+ knex;
44
+ permissionsService;
45
+ schemaInspector;
46
+ accountability;
47
+ schema;
48
+ relationsItemService;
49
+ systemCache;
50
+ helpers;
43
51
  constructor(options) {
44
52
  this.knex = options.knex || (0, database_1.default)();
45
53
  this.permissionsService = new permissions_1.PermissionsService(options);
@@ -83,12 +91,11 @@ class RelationsService {
83
91
  return await this.filterForbidden(results);
84
92
  }
85
93
  async readOne(collection, field) {
86
- var _a;
87
94
  if (this.accountability && this.accountability.admin !== true) {
88
95
  if (this.hasReadAccess === false) {
89
96
  throw new exceptions_1.ForbiddenException();
90
97
  }
91
- const permissions = (_a = this.accountability.permissions) === null || _a === void 0 ? void 0 : _a.find((permission) => {
98
+ const permissions = this.accountability.permissions?.find((permission) => {
92
99
  return permission.action === 'read' && permission.collection === collection;
93
100
  });
94
101
  if (!permissions || !permissions.fields)
@@ -155,6 +162,7 @@ class RelationsService {
155
162
  throw new exceptions_1.InvalidPayloadException(`Field "${relation.field}" in collection "${relation.collection}" already has an associated relationship`);
156
163
  }
157
164
  const runPostColumnChange = await this.helpers.schema.preColumnChange();
165
+ this.helpers.schema.preRelationChange(relation);
158
166
  const nestedActionEvents = [];
159
167
  try {
160
168
  const metaRow = {
@@ -166,13 +174,12 @@ class RelationsService {
166
174
  await this.knex.transaction(async (trx) => {
167
175
  if (relation.related_collection) {
168
176
  await trx.schema.alterTable(relation.collection, async (table) => {
169
- var _a;
170
177
  this.alterType(table, relation);
171
178
  const constraintName = (0, get_default_index_name_1.getDefaultIndexName)('foreign', relation.collection, relation.field);
172
179
  const builder = table
173
180
  .foreign(relation.field, constraintName)
174
181
  .references(`${relation.related_collection}.${this.schema.collections[relation.related_collection].primary}`);
175
- if ((_a = relation.schema) === null || _a === void 0 ? void 0 : _a.on_delete) {
182
+ if (relation.schema?.on_delete) {
176
183
  builder.onDelete(relation.schema.on_delete);
177
184
  }
178
185
  });
@@ -185,7 +192,7 @@ class RelationsService {
185
192
  // happens in `filterForbidden` down below
186
193
  });
187
194
  await relationsItemService.createOne(metaRow, {
188
- bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
195
+ bypassEmitAction: (params) => opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
189
196
  });
190
197
  });
191
198
  }
@@ -193,10 +200,10 @@ class RelationsService {
193
200
  if (runPostColumnChange) {
194
201
  await this.helpers.schema.postColumnChange();
195
202
  }
196
- if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
197
- await (0, cache_1.clearSystemCache)();
203
+ if (opts?.autoPurgeSystemCache !== false) {
204
+ await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
198
205
  }
199
- if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
206
+ if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
200
207
  const updatedSchema = await (0, get_schema_1.getSchema)();
201
208
  for (const nestedActionEvent of nestedActionEvents) {
202
209
  nestedActionEvent.context.schema = updatedSchema;
@@ -225,15 +232,15 @@ class RelationsService {
225
232
  throw new exceptions_1.InvalidPayloadException(`Field "${field}" in collection "${collection}" doesn't have a relationship.`);
226
233
  }
227
234
  const runPostColumnChange = await this.helpers.schema.preColumnChange();
235
+ this.helpers.schema.preRelationChange(relation);
228
236
  const nestedActionEvents = [];
229
237
  try {
230
238
  await this.knex.transaction(async (trx) => {
231
239
  if (existingRelation.related_collection) {
232
240
  await trx.schema.alterTable(collection, async (table) => {
233
- var _a;
234
241
  let constraintName = (0, get_default_index_name_1.getDefaultIndexName)('foreign', collection, field);
235
242
  // If the FK already exists in the DB, drop it first
236
- if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.schema) {
243
+ if (existingRelation?.schema) {
237
244
  constraintName = existingRelation.schema.constraint_name || constraintName;
238
245
  table.dropForeign(field, constraintName);
239
246
  constraintName = this.helpers.schema.constraintName(constraintName);
@@ -243,7 +250,7 @@ class RelationsService {
243
250
  const builder = table
244
251
  .foreign(field, constraintName || undefined)
245
252
  .references(`${existingRelation.related_collection}.${this.schema.collections[existingRelation.related_collection].primary}`);
246
- if ((_a = relation.schema) === null || _a === void 0 ? void 0 : _a.on_delete) {
253
+ if (relation.schema?.on_delete) {
247
254
  builder.onDelete(relation.schema.on_delete);
248
255
  }
249
256
  });
@@ -256,9 +263,9 @@ class RelationsService {
256
263
  // happens in `filterForbidden` down below
257
264
  });
258
265
  if (relation.meta) {
259
- if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.meta) {
266
+ if (existingRelation?.meta) {
260
267
  await relationsItemService.updateOne(existingRelation.meta.id, relation.meta, {
261
- bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
268
+ bypassEmitAction: (params) => opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
262
269
  });
263
270
  }
264
271
  else {
@@ -268,7 +275,7 @@ class RelationsService {
268
275
  many_field: relation.field,
269
276
  one_collection: existingRelation.related_collection || null,
270
277
  }, {
271
- bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
278
+ bypassEmitAction: (params) => opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
272
279
  });
273
280
  }
274
281
  }
@@ -278,10 +285,10 @@ class RelationsService {
278
285
  if (runPostColumnChange) {
279
286
  await this.helpers.schema.postColumnChange();
280
287
  }
281
- if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
282
- await (0, cache_1.clearSystemCache)();
288
+ if (opts?.autoPurgeSystemCache !== false) {
289
+ await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
283
290
  }
284
- if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
291
+ if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
285
292
  const updatedSchema = await (0, get_schema_1.getSchema)();
286
293
  for (const nestedActionEvent of nestedActionEvents) {
287
294
  nestedActionEvent.context.schema = updatedSchema;
@@ -311,10 +318,9 @@ class RelationsService {
311
318
  const nestedActionEvents = [];
312
319
  try {
313
320
  await this.knex.transaction(async (trx) => {
314
- var _a;
315
321
  const existingConstraints = await this.schemaInspector.foreignKeys();
316
322
  const constraintNames = existingConstraints.map((key) => key.constraint_name);
317
- if (((_a = existingRelation.schema) === null || _a === void 0 ? void 0 : _a.constraint_name) &&
323
+ if (existingRelation.schema?.constraint_name &&
318
324
  constraintNames.includes(existingRelation.schema.constraint_name)) {
319
325
  await trx.schema.alterTable(existingRelation.collection, (table) => {
320
326
  table.dropForeign(existingRelation.field, existingRelation.schema.constraint_name);
@@ -335,7 +341,7 @@ class RelationsService {
335
341
  accountability: this.accountability,
336
342
  },
337
343
  };
338
- if (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) {
344
+ if (opts?.bypassEmitAction) {
339
345
  opts.bypassEmitAction(actionEvent);
340
346
  }
341
347
  else {
@@ -347,10 +353,10 @@ class RelationsService {
347
353
  if (runPostColumnChange) {
348
354
  await this.helpers.schema.postColumnChange();
349
355
  }
350
- if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
351
- await (0, cache_1.clearSystemCache)();
356
+ if (opts?.autoPurgeSystemCache !== false) {
357
+ await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
352
358
  }
353
- if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
359
+ if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
354
360
  const updatedSchema = await (0, get_schema_1.getSchema)();
355
361
  for (const nestedActionEvent of nestedActionEvents) {
356
362
  nestedActionEvent.context.schema = updatedSchema;
@@ -363,10 +369,9 @@ class RelationsService {
363
369
  * Whether or not the current user has read access to relations
364
370
  */
365
371
  get hasReadAccess() {
366
- var _a, _b;
367
- return !!((_b = (_a = this.accountability) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.find((permission) => {
372
+ return !!this.accountability?.permissions?.find((permission) => {
368
373
  return permission.collection === 'directus_relations' && permission.action === 'read';
369
- }));
374
+ });
370
375
  }
371
376
  /**
372
377
  * Combine raw schema foreign key information with Directus relations meta rows to form final
@@ -398,11 +403,10 @@ class RelationsService {
398
403
  return !results.find((relation) => relation.meta === meta);
399
404
  })
400
405
  .map((meta) => {
401
- var _a;
402
406
  return {
403
407
  collection: meta.many_collection,
404
408
  field: meta.many_field,
405
- related_collection: (_a = meta.one_collection) !== null && _a !== void 0 ? _a : null,
409
+ related_collection: meta.one_collection ?? null,
406
410
  schema: null,
407
411
  meta: meta,
408
412
  };
@@ -415,16 +419,16 @@ class RelationsService {
415
419
  * permissions to
416
420
  */
417
421
  async filterForbidden(relations) {
418
- var _a, _b, _c;
419
- if (this.accountability === null || ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) === true)
422
+ if (this.accountability === null || this.accountability?.admin === true)
420
423
  return relations;
421
- const allowedCollections = (_c = (_b = this.accountability.permissions) === null || _b === void 0 ? void 0 : _b.filter((permission) => {
424
+ const allowedCollections = this.accountability.permissions
425
+ ?.filter((permission) => {
422
426
  return permission.action === 'read';
423
- }).map(({ collection }) => collection)) !== null && _c !== void 0 ? _c : [];
427
+ })
428
+ .map(({ collection }) => collection) ?? [];
424
429
  const allowedFields = this.permissionsService.getAllowedFields('read');
425
430
  relations = (0, utils_1.toArray)(relations);
426
431
  return relations.filter((relation) => {
427
- var _a, _b, _c;
428
432
  let collectionsAllowed = true;
429
433
  let fieldsAllowed = true;
430
434
  if (allowedCollections.includes(relation.collection) === false) {
@@ -433,8 +437,8 @@ class RelationsService {
433
437
  if (relation.related_collection && allowedCollections.includes(relation.related_collection) === false) {
434
438
  collectionsAllowed = false;
435
439
  }
436
- if (((_a = relation.meta) === null || _a === void 0 ? void 0 : _a.one_allowed_collections) &&
437
- ((_b = relation.meta) === null || _b === void 0 ? void 0 : _b.one_allowed_collections.every((collection) => allowedCollections.includes(collection))) === false) {
440
+ if (relation.meta?.one_allowed_collections &&
441
+ relation.meta?.one_allowed_collections.every((collection) => allowedCollections.includes(collection)) === false) {
438
442
  collectionsAllowed = false;
439
443
  }
440
444
  if (!allowedFields[relation.collection] ||
@@ -443,7 +447,7 @@ class RelationsService {
443
447
  fieldsAllowed = false;
444
448
  }
445
449
  if (relation.related_collection &&
446
- ((_c = relation.meta) === null || _c === void 0 ? void 0 : _c.one_field) &&
450
+ relation.meta?.one_field &&
447
451
  (!allowedFields[relation.related_collection] ||
448
452
  (allowedFields[relation.related_collection].includes('*') === false &&
449
453
  allowedFields[relation.related_collection].includes(relation.meta.one_field) === false))) {
@@ -1,4 +1,4 @@
1
- import { AbstractServiceOptions, PrimaryKey } from '../types';
1
+ import type { AbstractServiceOptions, PrimaryKey } from '../types';
2
2
  import { ItemsService } from './index';
3
3
  export declare class RevisionsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,5 @@
1
- import { AbstractServiceOptions, MutationOptions, PrimaryKey } from '../types';
2
- import { Query } from '@directus/shared/types';
1
+ import type { Query } from '@directus/shared/types';
2
+ import type { AbstractServiceOptions, MutationOptions, PrimaryKey } from '../types';
3
3
  import { ItemsService } from './items';
4
4
  export declare class RolesService extends ItemsService {
5
5
  constructor(options: AbstractServiceOptions);
@@ -18,7 +18,7 @@ class RolesService extends items_1.ItemsService {
18
18
  .whereNotIn('id', excludeKeys)
19
19
  .andWhere({ admin_access: true })
20
20
  .first();
21
- const otherAdminRolesCount = +((otherAdminRoles === null || otherAdminRoles === void 0 ? void 0 : otherAdminRoles.count) || 0);
21
+ const otherAdminRolesCount = +(otherAdminRoles?.count || 0);
22
22
  if (otherAdminRolesCount === 0)
23
23
  throw new exceptions_1.UnprocessableEntityException(`You can't delete the last admin role.`);
24
24
  }
@@ -49,15 +49,20 @@ class RolesService extends items_1.ItemsService {
49
49
  .andWhere({ 'directus_roles.admin_access': true })
50
50
  .leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
51
51
  .first();
52
- const otherAdminUsersCount = +((otherAdminUsers === null || otherAdminUsers === void 0 ? void 0 : otherAdminUsers.count) || 0);
52
+ const otherAdminUsersCount = +(otherAdminUsers?.count || 0);
53
53
  if (otherAdminUsersCount === 0) {
54
54
  throw new exceptions_1.UnprocessableEntityException(`You can't remove the last admin user from the admin role.`);
55
55
  }
56
56
  return;
57
57
  }
58
58
  async updateOne(key, data, opts) {
59
- if ('users' in data) {
60
- await this.checkForOtherAdminUsers(key, data.users);
59
+ try {
60
+ if ('users' in data) {
61
+ await this.checkForOtherAdminUsers(key, data.users);
62
+ }
63
+ }
64
+ catch (err) {
65
+ (opts || (opts = {})).preMutationException = err;
61
66
  }
62
67
  return super.updateOne(key, data, opts);
63
68
  }
@@ -65,14 +70,24 @@ class RolesService extends items_1.ItemsService {
65
70
  const primaryKeyField = this.schema.collections[this.collection].primary;
66
71
  const keys = data.map((item) => item[primaryKeyField]);
67
72
  const setsToNoAdmin = data.some((item) => item.admin_access === false);
68
- if (setsToNoAdmin) {
69
- await this.checkForOtherAdminRoles(keys);
73
+ try {
74
+ if (setsToNoAdmin) {
75
+ await this.checkForOtherAdminRoles(keys);
76
+ }
77
+ }
78
+ catch (err) {
79
+ (opts || (opts = {})).preMutationException = err;
70
80
  }
71
81
  return super.updateBatch(data, opts);
72
82
  }
73
83
  async updateMany(keys, data, opts) {
74
- if ('admin_access' in data && data.admin_access === false) {
75
- await this.checkForOtherAdminRoles(keys);
84
+ try {
85
+ if ('admin_access' in data && data.admin_access === false) {
86
+ await this.checkForOtherAdminRoles(keys);
87
+ }
88
+ }
89
+ catch (err) {
90
+ (opts || (opts = {})).preMutationException = err;
76
91
  }
77
92
  return super.updateMany(keys, data, opts);
78
93
  }
@@ -81,7 +96,13 @@ class RolesService extends items_1.ItemsService {
81
96
  return key;
82
97
  }
83
98
  async deleteMany(keys) {
84
- await this.checkForOtherAdminRoles(keys);
99
+ const opts = {};
100
+ try {
101
+ await this.checkForOtherAdminRoles(keys);
102
+ }
103
+ catch (err) {
104
+ opts.preMutationException = err;
105
+ }
85
106
  await this.knex.transaction(async (trx) => {
86
107
  const itemsService = new items_1.ItemsService('directus_roles', {
87
108
  knex: trx,
@@ -106,17 +127,17 @@ class RolesService extends items_1.ItemsService {
106
127
  // Delete permissions/presets for this role, suspend all remaining users in role
107
128
  await permissionsService.deleteByQuery({
108
129
  filter: { role: { _in: keys } },
109
- });
130
+ }, opts);
110
131
  await presetsService.deleteByQuery({
111
132
  filter: { role: { _in: keys } },
112
- });
133
+ }, opts);
113
134
  await usersService.updateByQuery({
114
135
  filter: { role: { _in: keys } },
115
136
  }, {
116
137
  status: 'suspended',
117
138
  role: null,
118
- });
119
- await itemsService.deleteMany(keys);
139
+ }, opts);
140
+ await itemsService.deleteMany(keys, opts);
120
141
  });
121
142
  return keys;
122
143
  }
@@ -0,0 +1,15 @@
1
+ import type { Accountability } from '@directus/shared/types';
2
+ import type { Knex } from 'knex';
3
+ import type { AbstractServiceOptions, Snapshot, SnapshotDiff, SnapshotDiffWithHash, SnapshotWithHash } from '../types';
4
+ export declare class SchemaService {
5
+ knex: Knex;
6
+ accountability: Accountability | null;
7
+ constructor(options: Omit<AbstractServiceOptions, 'schema'>);
8
+ snapshot(): Promise<Snapshot>;
9
+ apply(payload: SnapshotDiffWithHash): Promise<void>;
10
+ diff(snapshot: Snapshot, options?: {
11
+ currentSnapshot?: Snapshot;
12
+ force?: boolean;
13
+ }): Promise<SnapshotDiff | null>;
14
+ getHashedSnapshot(snapshot: Snapshot): SnapshotWithHash;
15
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SchemaService = void 0;
7
+ const database_1 = __importDefault(require("../database"));
8
+ const exceptions_1 = require("../exceptions");
9
+ const apply_diff_1 = require("../utils/apply-diff");
10
+ const get_snapshot_1 = require("../utils/get-snapshot");
11
+ const get_snapshot_diff_1 = require("../utils/get-snapshot-diff");
12
+ const get_versioned_hash_1 = require("../utils/get-versioned-hash");
13
+ const validate_diff_1 = require("../utils/validate-diff");
14
+ const validate_snapshot_1 = require("../utils/validate-snapshot");
15
+ class SchemaService {
16
+ knex;
17
+ accountability;
18
+ constructor(options) {
19
+ this.knex = options.knex ?? (0, database_1.default)();
20
+ this.accountability = options.accountability ?? null;
21
+ }
22
+ async snapshot() {
23
+ if (this.accountability?.admin !== true)
24
+ throw new exceptions_1.ForbiddenException();
25
+ const currentSnapshot = await (0, get_snapshot_1.getSnapshot)({ database: this.knex });
26
+ return currentSnapshot;
27
+ }
28
+ async apply(payload) {
29
+ if (this.accountability?.admin !== true)
30
+ throw new exceptions_1.ForbiddenException();
31
+ const currentSnapshot = await this.snapshot();
32
+ const snapshotWithHash = this.getHashedSnapshot(currentSnapshot);
33
+ if (!(0, validate_diff_1.validateApplyDiff)(payload, snapshotWithHash))
34
+ return;
35
+ await (0, apply_diff_1.applyDiff)(currentSnapshot, payload.diff, { database: this.knex });
36
+ }
37
+ async diff(snapshot, options) {
38
+ if (this.accountability?.admin !== true)
39
+ throw new exceptions_1.ForbiddenException();
40
+ (0, validate_snapshot_1.validateSnapshot)(snapshot, options?.force);
41
+ const currentSnapshot = options?.currentSnapshot ?? (await (0, get_snapshot_1.getSnapshot)({ database: this.knex }));
42
+ const diff = (0, get_snapshot_diff_1.getSnapshotDiff)(currentSnapshot, snapshot);
43
+ if (diff.collections.length === 0 && diff.fields.length === 0 && diff.relations.length === 0) {
44
+ return null;
45
+ }
46
+ return diff;
47
+ }
48
+ getHashedSnapshot(snapshot) {
49
+ const snapshotHash = (0, get_versioned_hash_1.getVersionedHash)(snapshot);
50
+ return {
51
+ ...snapshot,
52
+ hash: snapshotHash,
53
+ };
54
+ }
55
+ }
56
+ exports.SchemaService = SchemaService;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
- import { Knex } from 'knex';
2
- import { AbstractServiceOptions } from '../types';
3
- import { Accountability, SchemaOverview } from '@directus/shared/types';
1
+ import type { Knex } from 'knex';
2
+ import type { Accountability, SchemaOverview } from '@directus/shared/types';
3
+ import type { AbstractServiceOptions } from '../types';
4
4
  import { SettingsService } from './settings';
5
5
  export declare class ServerService {
6
6
  knex: Knex;
@@ -30,20 +30,25 @@ exports.ServerService = void 0;
30
30
  const lodash_1 = require("lodash");
31
31
  const os_1 = __importDefault(require("os"));
32
32
  const perf_hooks_1 = require("perf_hooks");
33
+ const utils_1 = require("@directus/shared/utils");
34
+ const node_stream_1 = require("node:stream");
33
35
  // @ts-ignore
34
36
  const package_json_1 = require("../../package.json");
35
37
  const cache_1 = require("../cache");
36
38
  const database_1 = __importStar(require("../database"));
37
39
  const env_1 = __importDefault(require("../env"));
38
40
  const logger_1 = __importDefault(require("../logger"));
39
- const rate_limiter_1 = require("../middleware/rate-limiter");
40
- const storage_1 = require("../storage");
41
- const utils_1 = require("@directus/shared/utils");
42
41
  const mailer_1 = __importDefault(require("../mailer"));
43
- const settings_1 = require("./settings");
42
+ const rate_limiter_global_1 = require("../middleware/rate-limiter-global");
43
+ const rate_limiter_ip_1 = require("../middleware/rate-limiter-ip");
44
+ const storage_1 = require("../storage");
44
45
  const get_os_info_1 = require("../utils/get-os-info");
45
- const node_stream_1 = require("node:stream");
46
+ const settings_1 = require("./settings");
46
47
  class ServerService {
48
+ knex;
49
+ accountability;
50
+ settingsService;
51
+ schema;
47
52
  constructor(options) {
48
53
  this.knex = options.knex || (0, database_1.default)();
49
54
  this.accountability = options.accountability || null;
@@ -51,7 +56,6 @@ class ServerService {
51
56
  this.settingsService = new settings_1.SettingsService({ knex: this.knex, schema: this.schema });
52
57
  }
53
58
  async serverInfo() {
54
- var _a, _b;
55
59
  const info = {};
56
60
  const projectInfo = await this.settingsService.readSingleton({
57
61
  fields: [
@@ -67,7 +71,7 @@ class ServerService {
67
71
  ],
68
72
  });
69
73
  info.project = projectInfo;
70
- if ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.user) {
74
+ if (this.accountability?.user) {
71
75
  if (env_1.default.RATE_LIMITER_ENABLED) {
72
76
  info.rateLimit = {
73
77
  points: env_1.default.RATE_LIMITER_POINTS,
@@ -77,11 +81,20 @@ class ServerService {
77
81
  else {
78
82
  info.rateLimit = false;
79
83
  }
84
+ if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED) {
85
+ info.rateLimitGlobal = {
86
+ points: env_1.default.RATE_LIMITER_GLOBAL_POINTS,
87
+ duration: env_1.default.RATE_LIMITER_GLOBAL_DURATION,
88
+ };
89
+ }
90
+ else {
91
+ info.rateLimitGlobal = false;
92
+ }
80
93
  info.flows = {
81
94
  execAllowedModules: env_1.default.FLOWS_EXEC_ALLOWED_MODULES ? (0, utils_1.toArray)(env_1.default.FLOWS_EXEC_ALLOWED_MODULES) : [],
82
95
  };
83
96
  }
84
- if (((_b = this.accountability) === null || _b === void 0 ? void 0 : _b.admin) === true) {
97
+ if (this.accountability?.admin === true) {
85
98
  const { osType, osVersion } = (0, get_os_info_1.getOSInfo)();
86
99
  info.directus = {
87
100
  version: package_json_1.version,
@@ -100,14 +113,20 @@ class ServerService {
100
113
  return info;
101
114
  }
102
115
  async health() {
103
- var _a;
104
116
  const { nanoid } = await import('nanoid');
105
117
  const checkID = nanoid(5);
106
118
  const data = {
107
119
  status: 'ok',
108
120
  releaseId: package_json_1.version,
109
121
  serviceId: env_1.default.KEY,
110
- checks: (0, lodash_1.merge)(...(await Promise.all([testDatabase(), testCache(), testRateLimiter(), testStorage(), testEmail()]))),
122
+ checks: (0, lodash_1.merge)(...(await Promise.all([
123
+ testDatabase(),
124
+ testCache(),
125
+ testRateLimiter(),
126
+ testRateLimiterGlobal(),
127
+ testStorage(),
128
+ testEmail(),
129
+ ]))),
111
130
  };
112
131
  for (const [service, healthData] of Object.entries(data.checks)) {
113
132
  for (const healthCheck of healthData) {
@@ -126,7 +145,7 @@ class ServerService {
126
145
  if (data.status === 'error')
127
146
  break;
128
147
  }
129
- if (((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
148
+ if (this.accountability?.admin !== true) {
130
149
  return { status: data.status };
131
150
  }
132
151
  else {
@@ -229,8 +248,8 @@ class ServerService {
229
248
  };
230
249
  const startTime = perf_hooks_1.performance.now();
231
250
  try {
232
- await rate_limiter_1.rateLimiter.consume(`health-${checkID}`, 1);
233
- await rate_limiter_1.rateLimiter.delete(`health-${checkID}`);
251
+ await rate_limiter_ip_1.rateLimiter.consume(`health-${checkID}`, 1);
252
+ await rate_limiter_ip_1.rateLimiter.delete(`health-${checkID}`);
234
253
  }
235
254
  catch (err) {
236
255
  checks['rateLimiter:responseTime'][0].status = 'error';
@@ -246,6 +265,43 @@ class ServerService {
246
265
  }
247
266
  return checks;
248
267
  }
268
+ async function testRateLimiterGlobal() {
269
+ if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED !== true) {
270
+ return {};
271
+ }
272
+ const checks = {
273
+ 'rateLimiterGlobal:responseTime': [
274
+ {
275
+ status: 'ok',
276
+ componentType: 'ratelimiter',
277
+ observedValue: 0,
278
+ observedUnit: 'ms',
279
+ threshold: env_1.default.RATE_LIMITER_GLOBAL_HEALTHCHECK_THRESHOLD
280
+ ? +env_1.default.RATE_LIMITER_GLOBAL_HEALTHCHECK_THRESHOLD
281
+ : 150,
282
+ },
283
+ ],
284
+ };
285
+ const startTime = perf_hooks_1.performance.now();
286
+ try {
287
+ await rate_limiter_global_1.rateLimiterGlobal.consume(`health-${checkID}`, 1);
288
+ await rate_limiter_global_1.rateLimiterGlobal.delete(`health-${checkID}`);
289
+ }
290
+ catch (err) {
291
+ checks['rateLimiterGlobal:responseTime'][0].status = 'error';
292
+ checks['rateLimiterGlobal:responseTime'][0].output = err;
293
+ }
294
+ finally {
295
+ const endTime = perf_hooks_1.performance.now();
296
+ checks['rateLimiterGlobal:responseTime'][0].observedValue = +(endTime - startTime).toFixed(3);
297
+ if (checks['rateLimiterGlobal:responseTime'][0].observedValue >
298
+ checks['rateLimiterGlobal:responseTime'][0].threshold &&
299
+ checks['rateLimiterGlobal:responseTime'][0].status !== 'error') {
300
+ checks['rateLimiterGlobal:responseTime'][0].status = 'warn';
301
+ }
302
+ }
303
+ return checks;
304
+ }
249
305
  async function testStorage() {
250
306
  const storage = await (0, storage_1.getStorage)();
251
307
  const checks = {};
@@ -1,4 +1,4 @@
1
- import { AbstractServiceOptions } from '../types';
1
+ import type { AbstractServiceOptions } from '../types';
2
2
  import { ItemsService } from './items';
3
3
  export declare class SettingsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,6 +1,6 @@
1
- import { AbstractServiceOptions, LoginResult, Item, PrimaryKey, MutationOptions } from '../types';
2
- import { ItemsService } from './items';
1
+ import type { AbstractServiceOptions, Item, LoginResult, MutationOptions, PrimaryKey } from '../types';
3
2
  import { AuthorizationService } from './authorization';
3
+ import { ItemsService } from './items';
4
4
  export declare class SharesService extends ItemsService {
5
5
  authorizationService: AuthorizationService;
6
6
  constructor(options: AbstractServiceOptions);