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
package/dist/logger.js CHANGED
@@ -27,13 +27,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.expressLogger = void 0;
30
+ const utils_1 = require("@directus/shared/utils");
31
+ const lodash_1 = require("lodash");
30
32
  const pino_1 = __importDefault(require("pino"));
31
33
  const pino_http_1 = __importStar(require("pino-http"));
32
- const get_config_from_env_1 = require("./utils/get-config-from-env");
33
34
  const url_1 = require("url");
34
35
  const env_1 = __importDefault(require("./env"));
35
- const utils_1 = require("@directus/shared/utils");
36
- const lodash_1 = require("lodash");
36
+ const get_config_from_env_1 = require("./utils/get-config-from-env");
37
+ const redact_header_cookies_1 = require("./utils/redact-header-cookies");
37
38
  const pinoOptions = {
38
39
  level: env_1.default.LOG_LEVEL || 'info',
39
40
  redact: {
@@ -104,8 +105,23 @@ exports.expressLogger = (0, pino_http_1.default)({
104
105
  req(request) {
105
106
  const output = pino_http_1.stdSerializers.req(request);
106
107
  output.url = redactQuery(output.url);
108
+ if (output.headers?.cookie) {
109
+ output.headers.cookie = (0, redact_header_cookies_1.redactHeaderCookie)(output.headers.cookie, [
110
+ 'access_token',
111
+ `${env_1.default.REFRESH_TOKEN_COOKIE_NAME}`,
112
+ ]);
113
+ }
107
114
  return output;
108
115
  },
116
+ res(response) {
117
+ if (response.headers?.['set-cookie']) {
118
+ response.headers['set-cookie'] = (0, redact_header_cookies_1.redactHeaderCookie)(response.headers['set-cookie'], [
119
+ 'access_token',
120
+ `${env_1.default.REFRESH_TOKEN_COOKIE_NAME}`,
121
+ ]);
122
+ }
123
+ return response;
124
+ },
109
125
  },
110
126
  });
111
127
  exports.default = logger;
package/dist/messenger.js CHANGED
@@ -9,12 +9,12 @@ const ioredis_1 = __importDefault(require("ioredis"));
9
9
  const env_1 = __importDefault(require("./env"));
10
10
  const get_config_from_env_1 = require("./utils/get-config-from-env");
11
11
  class MessengerMemory {
12
+ handlers;
12
13
  constructor() {
13
14
  this.handlers = {};
14
15
  }
15
16
  publish(channel, payload) {
16
- var _a, _b;
17
- (_b = (_a = this.handlers)[channel]) === null || _b === void 0 ? void 0 : _b.call(_a, payload);
17
+ this.handlers[channel]?.(payload);
18
18
  }
19
19
  subscribe(channel, callback) {
20
20
  this.handlers[channel] = callback;
@@ -25,12 +25,14 @@ class MessengerMemory {
25
25
  }
26
26
  exports.MessengerMemory = MessengerMemory;
27
27
  class MessengerRedis {
28
+ namespace;
29
+ pub;
30
+ sub;
28
31
  constructor() {
29
- var _a, _b, _c;
30
32
  const config = (0, get_config_from_env_1.getConfigFromEnv)('MESSENGER_REDIS');
31
- this.pub = new ioredis_1.default((_a = env_1.default.MESSENGER_REDIS) !== null && _a !== void 0 ? _a : config);
32
- this.sub = new ioredis_1.default((_b = env_1.default.MESSENGER_REDIS) !== null && _b !== void 0 ? _b : config);
33
- this.namespace = (_c = env_1.default.MESSENGER_NAMESPACE) !== null && _c !== void 0 ? _c : 'directus';
33
+ this.pub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
34
+ this.sub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
35
+ this.namespace = env_1.default.MESSENGER_NAMESPACE ?? 'directus';
34
36
  }
35
37
  publish(channel, payload) {
36
38
  this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
@@ -1,5 +1,5 @@
1
1
  /// <reference types="qs" />
2
- import { NextFunction, Request, Response } from 'express';
2
+ import type { NextFunction, Request, Response } from 'express';
3
3
  /**
4
4
  * Verify the passed JWT and assign the user ID and role to `req`
5
5
  */
@@ -23,9 +23,13 @@ const handler = async (req, res, next) => {
23
23
  admin: false,
24
24
  app: false,
25
25
  ip: (0, get_ip_from_req_1.getIPFromReq)(req),
26
- userAgent: req.get('user-agent'),
27
- origin: req.get('origin'),
28
26
  };
27
+ const userAgent = req.get('user-agent');
28
+ if (userAgent)
29
+ defaultAccountability.userAgent = userAgent;
30
+ const origin = req.get('origin');
31
+ if (origin)
32
+ defaultAccountability.origin = origin;
29
33
  const database = (0, database_1.default)();
30
34
  const customAccountability = await emitter_1.default.emitFilter('authenticate', defaultAccountability, {
31
35
  req,
@@ -42,12 +46,15 @@ const handler = async (req, res, next) => {
42
46
  if (req.token) {
43
47
  if ((0, is_directus_jwt_1.default)(req.token)) {
44
48
  const payload = (0, jwt_1.verifyAccessJWT)(req.token, env_1.default.SECRET);
45
- req.accountability.share = payload.share;
46
- req.accountability.share_scope = payload.share_scope;
47
- req.accountability.user = payload.id;
48
49
  req.accountability.role = payload.role;
49
50
  req.accountability.admin = payload.admin_access === true || payload.admin_access == 1;
50
51
  req.accountability.app = payload.app_access === true || payload.app_access == 1;
52
+ if (payload.share)
53
+ req.accountability.share = payload.share;
54
+ if (payload.share_scope)
55
+ req.accountability.share_scope = payload.share_scope;
56
+ if (payload.id)
57
+ req.accountability.user = payload.id;
51
58
  }
52
59
  else {
53
60
  // Try finding the user with the provided token
@@ -1,3 +1,3 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  declare const checkCacheMiddleware: RequestHandler;
3
3
  export default checkCacheMiddleware;
@@ -5,20 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const cache_1 = require("../cache");
7
7
  const env_1 = __importDefault(require("../env"));
8
+ const logger_1 = __importDefault(require("../logger"));
8
9
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
9
10
  const get_cache_headers_1 = require("../utils/get-cache-headers");
10
11
  const get_cache_key_1 = require("../utils/get-cache-key");
11
- const logger_1 = __importDefault(require("../logger"));
12
+ const should_skip_cache_1 = require("../utils/should-skip-cache");
12
13
  const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next) => {
13
- var _a, _b, _c, _d;
14
14
  const { cache } = (0, cache_1.getCache)();
15
- if (req.method.toLowerCase() !== 'get' && ((_a = req.originalUrl) === null || _a === void 0 ? void 0 : _a.startsWith('/graphql')) === false)
15
+ if (req.method.toLowerCase() !== 'get' && req.originalUrl?.startsWith('/graphql') === false)
16
16
  return next();
17
17
  if (env_1.default.CACHE_ENABLED !== true)
18
18
  return next();
19
19
  if (!cache)
20
20
  return next();
21
- if (((_b = req.headers['cache-control']) === null || _b === void 0 ? void 0 : _b.includes('no-store')) || ((_c = req.headers['Cache-Control']) === null || _c === void 0 ? void 0 : _c.includes('no-store'))) {
21
+ if ((0, should_skip_cache_1.shouldSkipCache)(req)) {
22
22
  if (env_1.default.CACHE_STATUS_HEADER)
23
23
  res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
24
24
  return next();
@@ -37,7 +37,7 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
37
37
  if (cachedData) {
38
38
  let cacheExpiryDate;
39
39
  try {
40
- cacheExpiryDate = (_d = (await (0, cache_1.getCacheValue)(cache, `${key}__expires_at`))) === null || _d === void 0 ? void 0 : _d.exp;
40
+ cacheExpiryDate = (await (0, cache_1.getCacheValue)(cache, `${key}__expires_at`))?.exp;
41
41
  }
42
42
  catch (err) {
43
43
  logger_1.default.warn(err, `[cache] Couldn't read key ${`${key}__expires_at`}. ${err.message}`);
@@ -45,8 +45,8 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
45
45
  res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
46
46
  return next();
47
47
  }
48
- const cacheTTL = cacheExpiryDate ? cacheExpiryDate - Date.now() : null;
49
- res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, cacheTTL));
48
+ const cacheTTL = cacheExpiryDate ? cacheExpiryDate - Date.now() : undefined;
49
+ res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, cacheTTL, true, true));
50
50
  res.setHeader('Vary', 'Origin, Cache-Control');
51
51
  if (env_1.default.CACHE_STATUS_HEADER)
52
52
  res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'HIT');
@@ -1,2 +1,2 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  export declare const checkIP: RequestHandler;
@@ -17,7 +17,7 @@ exports.checkIP = (0, async_handler_1.default)(async (req, _res, next) => {
17
17
  query.whereNull('id');
18
18
  }
19
19
  const role = await query.first();
20
- const ipAllowlist = ((role === null || role === void 0 ? void 0 : role.ip_access) || '').split(',').filter((ip) => ip);
20
+ const ipAllowlist = (role?.ip_access || '').split(',').filter((ip) => ip);
21
21
  if (ipAllowlist.length > 0 && ipAllowlist.includes(req.accountability.ip) === false)
22
22
  throw new exceptions_1.InvalidIPException();
23
23
  return next();
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Check if requested collection exists, and save it to req.collection
3
3
  */
4
- import { RequestHandler } from 'express';
4
+ import type { RequestHandler } from 'express';
5
5
  declare const collectionExists: RequestHandler;
6
6
  export default collectionExists;
@@ -18,9 +18,9 @@ const collectionExists = (0, async_handler_1.default)(async (req, res, next) =>
18
18
  req.collection = req.params.collection;
19
19
  if (req.collection.startsWith('directus_')) {
20
20
  const systemRow = collections_1.systemCollectionRows.find((collection) => {
21
- return (collection === null || collection === void 0 ? void 0 : collection.collection) === req.collection;
21
+ return collection?.collection === req.collection;
22
22
  });
23
- req.singleton = !!(systemRow === null || systemRow === void 0 ? void 0 : systemRow.singleton);
23
+ req.singleton = !!systemRow?.singleton;
24
24
  }
25
25
  else {
26
26
  req.singleton = req.schema.collections[req.collection].singleton;
@@ -1,3 +1,3 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  declare let corsMiddleware: RequestHandler;
3
3
  export default corsMiddleware;
@@ -1,3 +1,3 @@
1
- import { ErrorRequestHandler } from 'express';
1
+ import type { ErrorRequestHandler } from 'express';
2
2
  declare const errorHandler: ErrorRequestHandler;
3
3
  export default errorHandler;
@@ -3,22 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const exceptions_1 = require("@directus/shared/exceptions");
7
+ const utils_1 = require("@directus/shared/utils");
8
+ const database_1 = __importDefault(require("../database"));
6
9
  const emitter_1 = __importDefault(require("../emitter"));
7
10
  const env_1 = __importDefault(require("../env"));
8
- const exceptions_1 = require("../exceptions");
9
- const exceptions_2 = require("@directus/shared/exceptions");
11
+ const exceptions_2 = require("../exceptions");
10
12
  const logger_1 = __importDefault(require("../logger"));
11
- const utils_1 = require("@directus/shared/utils");
12
- const database_1 = __importDefault(require("../database"));
13
13
  // Note: keep all 4 parameters here. That's how Express recognizes it's the error handler, even if
14
14
  // we don't use next
15
15
  const errorHandler = (err, req, res, _next) => {
16
- var _a, _b;
17
16
  let payload = {
18
17
  errors: [],
19
18
  };
20
19
  const errors = (0, utils_1.toArray)(err);
21
- if (errors.some((err) => err instanceof exceptions_2.BaseException === false)) {
20
+ if (errors.some((err) => err instanceof exceptions_1.BaseException === false)) {
22
21
  res.status(500);
23
22
  }
24
23
  else {
@@ -39,7 +38,7 @@ const errorHandler = (err, req, res, _next) => {
39
38
  stack: err.stack,
40
39
  };
41
40
  }
42
- if (err instanceof exceptions_2.BaseException) {
41
+ if (err instanceof exceptions_1.BaseException) {
43
42
  logger_1.default.debug(err);
44
43
  res.status(err.status);
45
44
  payload.errors.push({
@@ -49,14 +48,14 @@ const errorHandler = (err, req, res, _next) => {
49
48
  ...err.extensions,
50
49
  },
51
50
  });
52
- if (err instanceof exceptions_1.MethodNotAllowedException) {
51
+ if (err instanceof exceptions_2.MethodNotAllowedException) {
53
52
  res.header('Allow', err.extensions.allow.join(', '));
54
53
  }
55
54
  }
56
55
  else {
57
56
  logger_1.default.error(err);
58
57
  res.status(500);
59
- if (((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.admin) === true) {
58
+ if (req.accountability?.admin === true) {
60
59
  payload = {
61
60
  errors: [
62
61
  {
@@ -87,7 +86,7 @@ const errorHandler = (err, req, res, _next) => {
87
86
  .emitFilter('request.error', payload.errors, {}, {
88
87
  database: (0, database_1.default)(),
89
88
  schema: req.schema,
90
- accountability: (_b = req.accountability) !== null && _b !== void 0 ? _b : null,
89
+ accountability: req.accountability ?? null,
91
90
  })
92
91
  .then(() => {
93
92
  return res.json(payload);
@@ -6,6 +6,6 @@
6
6
  *
7
7
  * and store in req.token
8
8
  */
9
- import { RequestHandler } from 'express';
9
+ import type { RequestHandler } from 'express';
10
10
  declare const extractToken: RequestHandler;
11
11
  export default extractToken;
@@ -1,3 +1,3 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  declare const getPermissions: RequestHandler;
3
3
  export default getPermissions;
@@ -1,2 +1,2 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  export declare const parseGraphQL: RequestHandler;
@@ -49,13 +49,13 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
49
49
  }
50
50
  const operationAST = (0, graphql_1.getOperationAST)(document, operationName);
51
51
  // You can only do `query` through GET
52
- if (req.method === 'GET' && (operationAST === null || operationAST === void 0 ? void 0 : operationAST.operation) !== 'query') {
53
- throw new exceptions_1.MethodNotAllowedException(`Can only perform a ${operationAST === null || operationAST === void 0 ? void 0 : operationAST.operation} from a POST request.`, {
52
+ if (req.method === 'GET' && operationAST?.operation !== 'query') {
53
+ throw new exceptions_1.MethodNotAllowedException(`Can only perform a ${operationAST?.operation} from a POST request.`, {
54
54
  allow: ['POST'],
55
55
  });
56
56
  }
57
57
  // Prevent caching responses when mutations are made
58
- if ((operationAST === null || operationAST === void 0 ? void 0 : operationAST.operation) === 'mutation') {
58
+ if (operationAST?.operation === 'mutation') {
59
59
  res.locals.cache = false;
60
60
  }
61
61
  res.locals.graphqlParams = { document, query, variables, operationName, contextValue: { req, res } };
@@ -0,0 +1,5 @@
1
+ import type { RequestHandler } from 'express';
2
+ import type { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
3
+ declare let checkRateLimit: RequestHandler;
4
+ export declare let rateLimiterGlobal: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
5
+ export default checkRateLimit;
@@ -0,0 +1,48 @@
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.rateLimiterGlobal = void 0;
7
+ const ms_1 = __importDefault(require("ms"));
8
+ const env_1 = __importDefault(require("../env"));
9
+ const index_1 = require("../exceptions/index");
10
+ const logger_1 = __importDefault(require("../logger"));
11
+ const rate_limiter_1 = require("../rate-limiter");
12
+ const async_handler_1 = __importDefault(require("../utils/async-handler"));
13
+ const validate_env_1 = require("../utils/validate-env");
14
+ const RATE_LIMITER_GLOBAL_KEY = 'global-rate-limit';
15
+ let checkRateLimit = (_req, _res, next) => next();
16
+ if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED === true) {
17
+ (0, validate_env_1.validateEnv)(['RATE_LIMITER_GLOBAL_STORE', 'RATE_LIMITER_GLOBAL_DURATION', 'RATE_LIMITER_GLOBAL_POINTS']);
18
+ validateConfiguration();
19
+ exports.rateLimiterGlobal = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER_GLOBAL');
20
+ checkRateLimit = (0, async_handler_1.default)(async (_req, res, next) => {
21
+ try {
22
+ await exports.rateLimiterGlobal.consume(RATE_LIMITER_GLOBAL_KEY, 1);
23
+ }
24
+ catch (rateLimiterRes) {
25
+ if (rateLimiterRes instanceof Error)
26
+ throw rateLimiterRes;
27
+ res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
28
+ throw new index_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
29
+ limit: +env_1.default.RATE_LIMITER_GLOBAL_POINTS,
30
+ reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
31
+ });
32
+ }
33
+ next();
34
+ });
35
+ }
36
+ exports.default = checkRateLimit;
37
+ function validateConfiguration() {
38
+ if (env_1.default.RATE_LIMITER_ENABLED !== true) {
39
+ logger_1.default.error(`The IP based rate limiter needs to be enabled when using the global rate limiter.`);
40
+ process.exit(1);
41
+ }
42
+ const globalPointsPerSec = Number(env_1.default.RATE_LIMITER_GLOBAL_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_GLOBAL_DURATION), 1);
43
+ const regularPointsPerSec = Number(env_1.default.RATE_LIMITER_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_DURATION), 1);
44
+ if (globalPointsPerSec <= regularPointsPerSec) {
45
+ logger_1.default.error(`The global rate limiter needs to allow more requests per second than the IP based rate limiter.`);
46
+ process.exit(1);
47
+ }
48
+ }
@@ -1,5 +1,5 @@
1
- import { RequestHandler } from 'express';
2
- import { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
1
+ import type { RequestHandler } from 'express';
2
+ import type { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
3
3
  declare let checkRateLimit: RequestHandler;
4
4
  export declare let rateLimiter: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
5
5
  export default checkRateLimit;
@@ -11,10 +11,10 @@ const rate_limiter_1 = require("../rate-limiter");
11
11
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
12
12
  const get_ip_from_req_1 = require("../utils/get-ip-from-req");
13
13
  const validate_env_1 = require("../utils/validate-env");
14
- let checkRateLimit = (req, res, next) => next();
14
+ let checkRateLimit = (_req, _res, next) => next();
15
15
  if (env_1.default.RATE_LIMITER_ENABLED === true) {
16
16
  (0, validate_env_1.validateEnv)(['RATE_LIMITER_STORE', 'RATE_LIMITER_DURATION', 'RATE_LIMITER_POINTS']);
17
- exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)();
17
+ exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER');
18
18
  checkRateLimit = (0, async_handler_1.default)(async (req, res, next) => {
19
19
  try {
20
20
  await exports.rateLimiter.consume((0, get_ip_from_req_1.getIPFromReq)(req), 1);
@@ -22,7 +22,7 @@ if (env_1.default.RATE_LIMITER_ENABLED === true) {
22
22
  catch (rateLimiterRes) {
23
23
  if (rateLimiterRes instanceof Error)
24
24
  throw rateLimiterRes;
25
- res.set('Retry-After', String(rateLimiterRes.msBeforeNext / 1000));
25
+ res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
26
26
  throw new exceptions_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
27
27
  limit: +env_1.default.RATE_LIMITER_POINTS,
28
28
  reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
@@ -1,2 +1,2 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  export declare const respond: RequestHandler;
@@ -4,19 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.respond = void 0;
7
- const ms_1 = __importDefault(require("ms"));
7
+ const bytes_1 = require("bytes");
8
8
  const cache_1 = require("../cache");
9
9
  const env_1 = __importDefault(require("../env"));
10
- const async_handler_1 = __importDefault(require("../utils/async-handler"));
11
- const get_cache_key_1 = require("../utils/get-cache-key");
12
- const get_cache_headers_1 = require("../utils/get-cache-headers");
13
10
  const logger_1 = __importDefault(require("../logger"));
14
11
  const services_1 = require("../services");
12
+ const async_handler_1 = __importDefault(require("../utils/async-handler"));
13
+ const get_cache_headers_1 = require("../utils/get-cache-headers");
14
+ const get_cache_key_1 = require("../utils/get-cache-key");
15
15
  const get_date_formatted_1 = require("../utils/get-date-formatted");
16
+ const get_milliseconds_1 = require("../utils/get-milliseconds");
16
17
  const get_string_byte_size_1 = require("../utils/get-string-byte-size");
17
- const bytes_1 = require("bytes");
18
18
  exports.respond = (0, async_handler_1.default)(async (req, res) => {
19
- var _a, _b, _c, _d;
20
19
  const { cache } = (0, cache_1.getCache)();
21
20
  let exceedsMaxSize = false;
22
21
  if (env_1.default.CACHE_VALUE_MAX_SIZE !== false) {
@@ -24,7 +23,7 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
24
23
  const maxSize = (0, bytes_1.parse)(env_1.default.CACHE_VALUE_MAX_SIZE);
25
24
  exceedsMaxSize = valueSize > maxSize;
26
25
  }
27
- if ((req.method.toLowerCase() === 'get' || ((_a = req.originalUrl) === null || _a === void 0 ? void 0 : _a.startsWith('/graphql'))) &&
26
+ if ((req.method.toLowerCase() === 'get' || req.originalUrl?.startsWith('/graphql')) &&
28
27
  env_1.default.CACHE_ENABLED === true &&
29
28
  cache &&
30
29
  !req.sanitizedQuery.export &&
@@ -32,13 +31,13 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
32
31
  exceedsMaxSize === false) {
33
32
  const key = (0, get_cache_key_1.getCacheKey)(req);
34
33
  try {
35
- await (0, cache_1.setCacheValue)(cache, key, res.locals.payload, (0, ms_1.default)(env_1.default.CACHE_TTL));
36
- await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0, ms_1.default)(env_1.default.CACHE_TTL) });
34
+ await (0, cache_1.setCacheValue)(cache, key, res.locals.payload, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL));
35
+ await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL, 0) });
37
36
  }
38
37
  catch (err) {
39
38
  logger_1.default.warn(err, `[cache] Couldn't set key ${key}. ${err}`);
40
39
  }
41
- res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, ms_1.default)(env_1.default.CACHE_TTL)));
40
+ res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL), true, true));
42
41
  res.setHeader('Vary', 'Origin, Cache-Control');
43
42
  }
44
43
  else {
@@ -47,7 +46,7 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
47
46
  res.setHeader('Vary', 'Origin, Cache-Control');
48
47
  }
49
48
  if (req.sanitizedQuery.export) {
50
- const exportService = new services_1.ExportService({ accountability: req.accountability, schema: req.schema });
49
+ const exportService = new services_1.ExportService({ accountability: req.accountability ?? null, schema: req.schema });
51
50
  let filename = '';
52
51
  if (req.collection) {
53
52
  filename += req.collection;
@@ -59,17 +58,22 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
59
58
  if (req.sanitizedQuery.export === 'json') {
60
59
  res.attachment(`${filename}.json`);
61
60
  res.set('Content-Type', 'application/json');
62
- return res.status(200).send(exportService.transform((_b = res.locals.payload) === null || _b === void 0 ? void 0 : _b.data, 'json'));
61
+ return res.status(200).send(exportService.transform(res.locals.payload?.data, 'json'));
63
62
  }
64
63
  if (req.sanitizedQuery.export === 'xml') {
65
64
  res.attachment(`${filename}.xml`);
66
65
  res.set('Content-Type', 'text/xml');
67
- return res.status(200).send(exportService.transform((_c = res.locals.payload) === null || _c === void 0 ? void 0 : _c.data, 'xml'));
66
+ return res.status(200).send(exportService.transform(res.locals.payload?.data, 'xml'));
68
67
  }
69
68
  if (req.sanitizedQuery.export === 'csv') {
70
69
  res.attachment(`${filename}.csv`);
71
70
  res.set('Content-Type', 'text/csv');
72
- return res.status(200).send(exportService.transform((_d = res.locals.payload) === null || _d === void 0 ? void 0 : _d.data, 'csv'));
71
+ return res.status(200).send(exportService.transform(res.locals.payload?.data, 'csv'));
72
+ }
73
+ if (req.sanitizedQuery.export === 'yaml') {
74
+ res.attachment(`${filename}.yaml`);
75
+ res.set('Content-Type', 'text/yaml');
76
+ return res.status(200).send(exportService.transform(res.locals.payload?.data, 'yaml'));
73
77
  }
74
78
  }
75
79
  if (Buffer.isBuffer(res.locals.payload)) {
@@ -2,6 +2,6 @@
2
2
  * Sanitize query parameters.
3
3
  * This ensures that query params are formatted and ready to go for the services.
4
4
  */
5
- import { RequestHandler } from 'express';
5
+ import type { RequestHandler } from 'express';
6
6
  declare const sanitizeQueryMiddleware: RequestHandler;
7
7
  export default sanitizeQueryMiddleware;
@@ -1,3 +1,3 @@
1
- import { RequestHandler } from 'express';
1
+ import type { RequestHandler } from 'express';
2
2
  declare const schema: RequestHandler;
3
3
  export default schema;
@@ -2,6 +2,6 @@
2
2
  * Set req.collection for use in other middleware. Used as an alternative on validate-collection for
3
3
  * system collections
4
4
  */
5
- import { RequestHandler } from 'express';
5
+ import type { RequestHandler } from 'express';
6
6
  declare const useCollection: (collection: string) => RequestHandler;
7
7
  export default useCollection;
@@ -1,4 +1,4 @@
1
- import { Filter } from '@directus/shared/types';
1
+ import type { Filter } from '@directus/shared/types';
2
2
  type Options = {
3
3
  filter: Filter;
4
4
  };
@@ -2,21 +2,32 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const vm2_1 = require("vm2");
5
+ const node_module_1 = require("node:module");
5
6
  exports.default = (0, utils_1.defineOperationApi)({
6
7
  id: 'exec',
7
8
  handler: async ({ code }, { data, env }) => {
8
- var _a;
9
9
  const allowedModules = env.FLOWS_EXEC_ALLOWED_MODULES ? (0, utils_1.toArray)(env.FLOWS_EXEC_ALLOWED_MODULES) : [];
10
- const allowedEnv = (_a = data.$env) !== null && _a !== void 0 ? _a : {};
10
+ const allowedModulesBuiltIn = [];
11
+ const allowedModulesExternal = [];
12
+ const allowedEnv = data.$env ?? {};
11
13
  const opts = {
12
14
  eval: false,
13
15
  wasm: false,
14
16
  env: allowedEnv,
15
17
  };
18
+ for (const module of allowedModules) {
19
+ if ((0, node_module_1.isBuiltin)(module)) {
20
+ allowedModulesBuiltIn.push(module);
21
+ }
22
+ else {
23
+ allowedModulesExternal.push(module);
24
+ }
25
+ }
16
26
  if (allowedModules.length > 0) {
17
27
  opts.require = {
28
+ builtin: allowedModulesBuiltIn,
18
29
  external: {
19
- modules: allowedModules,
30
+ modules: allowedModulesExternal,
20
31
  transitive: false,
21
32
  },
22
33
  };
@@ -6,7 +6,6 @@ const get_accountability_for_role_1 = require("../../utils/get-accountability-fo
6
6
  exports.default = (0, utils_1.defineOperationApi)({
7
7
  id: 'item-create',
8
8
  handler: async ({ collection, payload, emitEvents, permissions }, { accountability, database, getSchema }) => {
9
- var _a;
10
9
  const schema = await getSchema({ database });
11
10
  let customAccountability;
12
11
  if (!permissions || permissions === '$trigger') {
@@ -26,7 +25,7 @@ exports.default = (0, utils_1.defineOperationApi)({
26
25
  accountability: customAccountability,
27
26
  knex: database,
28
27
  });
29
- const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
28
+ const payloadObject = (0, utils_1.optionToObject)(payload) ?? null;
30
29
  let result;
31
30
  if (!payloadObject) {
32
31
  result = null;
@@ -1,4 +1,4 @@
1
- import { PrimaryKey } from '@directus/shared/types';
1
+ import type { PrimaryKey } from '@directus/shared/types';
2
2
  type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
@@ -1,4 +1,4 @@
1
- import { PrimaryKey } from '@directus/shared/types';
1
+ import type { PrimaryKey } from '@directus/shared/types';
2
2
  type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
@@ -1,4 +1,4 @@
1
- import { PrimaryKey } from '@directus/shared/types';
1
+ import type { PrimaryKey } from '@directus/shared/types';
2
2
  type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
@@ -7,7 +7,6 @@ const sanitize_query_1 = require("../../utils/sanitize-query");
7
7
  exports.default = (0, utils_1.defineOperationApi)({
8
8
  id: 'item-update',
9
9
  handler: async ({ collection, key, payload, query, emitEvents, permissions }, { accountability, database, getSchema }) => {
10
- var _a;
11
10
  const schema = await getSchema({ database });
12
11
  let customAccountability;
13
12
  if (!permissions || permissions === '$trigger') {
@@ -27,7 +26,7 @@ exports.default = (0, utils_1.defineOperationApi)({
27
26
  accountability: customAccountability,
28
27
  knex: database,
29
28
  });
30
- const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
29
+ const payloadObject = (0, utils_1.optionToObject)(payload) ?? null;
31
30
  const queryObject = query ? (0, utils_1.optionToObject)(query) : {};
32
31
  const sanitizedQueryObject = (0, sanitize_query_1.sanitizeQuery)(queryObject, customAccountability);
33
32
  if (!payloadObject) {