@directus/api 21.0.0-rc.0 → 21.0.1

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 (286) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/auth/drivers/ldap.js +4 -4
  3. package/dist/auth/drivers/local.js +4 -4
  4. package/dist/auth/drivers/oauth2.js +4 -4
  5. package/dist/auth/drivers/openid.js +4 -2
  6. package/dist/cache.d.ts +2 -3
  7. package/dist/cache.js +9 -27
  8. package/dist/cli/commands/bootstrap/index.js +2 -8
  9. package/dist/cli/commands/init/index.js +10 -9
  10. package/dist/cli/utils/defaults.d.ts +11 -4
  11. package/dist/cli/utils/defaults.js +1 -7
  12. package/dist/constants.d.ts +1 -1
  13. package/dist/controllers/auth.js +16 -5
  14. package/dist/controllers/permissions.js +2 -14
  15. package/dist/controllers/roles.js +1 -22
  16. package/dist/controllers/tus.js +27 -13
  17. package/dist/controllers/users.js +55 -0
  18. package/dist/database/helpers/fn/types.d.ts +1 -2
  19. package/dist/database/helpers/fn/types.js +1 -1
  20. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  21. package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
  22. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  23. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  24. package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
  25. package/dist/database/helpers/geometry/types.d.ts +1 -1
  26. package/dist/database/helpers/geometry/types.js +2 -4
  27. package/dist/database/index.js +11 -8
  28. package/dist/database/migrations/20240305A-change-useragent-type.js +1 -1
  29. package/dist/database/migrations/20240716A-update-files-date-fields.js +33 -0
  30. package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
  31. package/dist/database/run-ast.js +458 -0
  32. package/dist/flows.js +4 -3
  33. package/dist/logger/index.js +1 -1
  34. package/dist/middleware/authenticate.js +7 -2
  35. package/dist/middleware/cache.js +1 -1
  36. package/dist/middleware/check-ip.d.ts +2 -0
  37. package/dist/middleware/check-ip.js +37 -0
  38. package/dist/middleware/error-handler.d.ts +2 -2
  39. package/dist/middleware/error-handler.js +54 -51
  40. package/dist/middleware/get-permissions.d.ts +3 -0
  41. package/dist/middleware/get-permissions.js +10 -0
  42. package/dist/middleware/respond.js +2 -1
  43. package/dist/request/is-denied-ip.js +7 -1
  44. package/dist/services/activity.js +10 -22
  45. package/dist/services/assets.d.ts +3 -2
  46. package/dist/services/assets.js +7 -15
  47. package/dist/services/authentication.js +18 -18
  48. package/dist/services/authorization.d.ts +17 -0
  49. package/dist/services/authorization.js +456 -0
  50. package/dist/services/collections.js +17 -18
  51. package/dist/services/fields.d.ts +4 -0
  52. package/dist/services/fields.js +53 -58
  53. package/dist/services/files/lib/get-sharp-instance.d.ts +2 -0
  54. package/dist/services/files/lib/get-sharp-instance.js +10 -0
  55. package/dist/services/files/utils/get-metadata.js +7 -6
  56. package/dist/services/files.js +8 -10
  57. package/dist/services/graphql/index.d.ts +3 -3
  58. package/dist/services/graphql/index.js +22 -126
  59. package/dist/services/graphql/subscription.js +4 -2
  60. package/dist/services/import-export.js +4 -18
  61. package/dist/services/index.d.ts +2 -3
  62. package/dist/services/index.js +2 -3
  63. package/dist/services/items.js +44 -115
  64. package/dist/services/mail/index.d.ts +1 -1
  65. package/dist/services/mail/index.js +9 -1
  66. package/dist/services/meta.js +23 -60
  67. package/dist/services/notifications.js +6 -14
  68. package/dist/services/payload.d.ts +10 -9
  69. package/dist/services/payload.js +3 -18
  70. package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
  71. package/dist/services/{permissions.js → permissions/index.js} +54 -30
  72. package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  73. package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
  74. package/dist/services/relations.d.ts +9 -1
  75. package/dist/services/relations.js +56 -31
  76. package/dist/services/roles.d.ts +12 -4
  77. package/dist/services/roles.js +424 -57
  78. package/dist/services/shares.d.ts +2 -0
  79. package/dist/services/shares.js +8 -12
  80. package/dist/services/specifications.d.ts +2 -2
  81. package/dist/services/specifications.js +27 -39
  82. package/dist/services/tus/data-store.js +4 -5
  83. package/dist/services/tus/server.d.ts +1 -1
  84. package/dist/services/tus/server.js +9 -2
  85. package/dist/services/users.d.ts +5 -1
  86. package/dist/services/users.js +161 -78
  87. package/dist/services/utils.js +7 -11
  88. package/dist/services/versions.d.ts +2 -0
  89. package/dist/services/versions.js +10 -34
  90. package/dist/telemetry/lib/get-report.js +2 -2
  91. package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
  92. package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
  93. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
  94. package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
  95. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
  96. package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
  97. package/dist/telemetry/utils/get-user-count.d.ts +8 -0
  98. package/dist/telemetry/utils/get-user-count.js +33 -0
  99. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
  100. package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
  101. package/dist/types/ast.d.ts +1 -43
  102. package/dist/types/items.d.ts +0 -11
  103. package/dist/utils/apply-query.d.ts +3 -4
  104. package/dist/utils/apply-query.js +16 -39
  105. package/dist/utils/get-accountability-for-role.js +25 -16
  106. package/dist/utils/get-accountability-for-token.js +16 -17
  107. package/dist/utils/get-ast-from-query.d.ts +13 -0
  108. package/dist/utils/get-ast-from-query.js +297 -0
  109. package/dist/utils/get-cache-key.d.ts +1 -1
  110. package/dist/utils/get-cache-key.js +1 -12
  111. package/dist/utils/get-column.d.ts +1 -2
  112. package/dist/utils/get-column.js +0 -1
  113. package/dist/utils/get-permissions.d.ts +2 -0
  114. package/dist/utils/get-permissions.js +150 -0
  115. package/dist/utils/get-schema.js +22 -27
  116. package/dist/utils/get-service.js +1 -5
  117. package/dist/utils/merge-permissions-for-share.d.ts +4 -0
  118. package/dist/utils/merge-permissions-for-share.js +109 -0
  119. package/dist/utils/merge-permissions.d.ts +3 -0
  120. package/dist/utils/merge-permissions.js +95 -0
  121. package/dist/utils/reduce-schema.d.ts +6 -4
  122. package/dist/utils/reduce-schema.js +32 -16
  123. package/dist/websocket/authenticate.d.ts +2 -0
  124. package/dist/websocket/authenticate.js +12 -0
  125. package/dist/websocket/controllers/graphql.js +4 -1
  126. package/dist/websocket/controllers/hooks.js +0 -4
  127. package/dist/websocket/controllers/rest.js +2 -0
  128. package/dist/websocket/handlers/subscribe.js +2 -0
  129. package/dist/websocket/utils/items.d.ts +1 -1
  130. package/package.json +35 -36
  131. package/dist/controllers/access.d.ts +0 -2
  132. package/dist/controllers/access.js +0 -148
  133. package/dist/controllers/policies.d.ts +0 -2
  134. package/dist/controllers/policies.js +0 -169
  135. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
  136. package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
  137. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
  138. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
  139. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
  140. package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
  141. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
  142. package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
  143. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
  144. package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
  145. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
  146. package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
  147. package/dist/database/migrations/20240710A-permissions-policies.js +0 -169
  148. package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
  149. package/dist/database/run-ast/lib/get-db-query.js +0 -208
  150. package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
  151. package/dist/database/run-ast/lib/parse-current-level.js +0 -41
  152. package/dist/database/run-ast/run-ast.d.ts +0 -7
  153. package/dist/database/run-ast/run-ast.js +0 -107
  154. package/dist/database/run-ast/types.js +0 -1
  155. package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
  156. package/dist/database/run-ast/utils/apply-case-when.js +0 -26
  157. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
  158. package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
  159. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
  160. package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
  161. package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
  162. package/dist/database/run-ast/utils/get-field-alias.js +0 -4
  163. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
  164. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
  165. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
  166. package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
  167. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
  168. package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
  169. package/dist/permissions/cache.d.ts +0 -2
  170. package/dist/permissions/cache.js +0 -23
  171. package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
  172. package/dist/permissions/lib/fetch-permissions.js +0 -55
  173. package/dist/permissions/lib/fetch-policies.d.ts +0 -7
  174. package/dist/permissions/lib/fetch-policies.js +0 -28
  175. package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
  176. package/dist/permissions/lib/fetch-roles-tree.js +0 -28
  177. package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
  178. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
  179. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
  180. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
  181. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
  182. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
  183. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
  184. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
  185. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
  186. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
  187. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
  188. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
  189. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
  190. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
  191. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
  192. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
  193. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
  194. package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
  195. package/dist/permissions/modules/fetch-global-access/types.js +0 -1
  196. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
  197. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
  198. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
  199. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
  200. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
  201. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
  202. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
  203. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
  204. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
  205. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
  206. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
  207. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
  208. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
  209. package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
  210. package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
  211. package/dist/permissions/modules/process-ast/process-ast.js +0 -39
  212. package/dist/permissions/modules/process-ast/types.d.ts +0 -24
  213. package/dist/permissions/modules/process-ast/types.js +0 -1
  214. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
  215. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
  216. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
  217. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
  218. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
  219. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
  220. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
  221. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
  222. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
  223. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -34
  224. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
  225. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
  226. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
  227. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
  228. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
  229. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
  230. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
  231. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
  232. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
  233. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
  234. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
  235. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
  236. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
  237. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
  238. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
  239. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
  240. package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
  241. package/dist/permissions/modules/process-payload/process-payload.js +0 -77
  242. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
  243. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
  244. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
  245. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
  246. package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
  247. package/dist/permissions/modules/validate-access/validate-access.js +0 -28
  248. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
  249. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
  250. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
  251. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
  252. package/dist/permissions/types.d.ts +0 -6
  253. package/dist/permissions/types.js +0 -1
  254. package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
  255. package/dist/permissions/utils/create-default-accountability.js +0 -11
  256. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
  257. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
  258. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
  259. package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
  260. package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
  261. package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
  262. package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
  263. package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
  264. package/dist/permissions/utils/process-permissions.d.ts +0 -7
  265. package/dist/permissions/utils/process-permissions.js +0 -9
  266. package/dist/permissions/utils/with-cache.d.ts +0 -10
  267. package/dist/permissions/utils/with-cache.js +0 -25
  268. package/dist/services/access.d.ts +0 -10
  269. package/dist/services/access.js +0 -43
  270. package/dist/services/policies.d.ts +0 -12
  271. package/dist/services/policies.js +0 -87
  272. package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
  273. package/dist/telemetry/utils/check-user-limits.js +0 -19
  274. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
  275. package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
  276. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
  277. package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
  278. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
  279. package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
  280. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
  281. package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
  282. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
  283. package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
  284. package/dist/utils/validate-user-count-integrity.d.ts +0 -13
  285. package/dist/utils/validate-user-count-integrity.js +0 -29
  286. /package/dist/database/migrations/{20240710A-permissions-policies.d.ts → 20240716A-update-files-date-fields.d.ts} +0 -0
@@ -4,7 +4,7 @@ import { systemCollectionRows } from '@directus/system-data';
4
4
  import { parseJSON, toArray } from '@directus/utils';
5
5
  import { mapValues } from 'lodash-es';
6
6
  import { useBus } from '../bus/index.js';
7
- import { getSchemaCache, setSchemaCache } from '../cache.js';
7
+ import { getLocalSchemaCache, setLocalSchemaCache } from '../cache.js';
8
8
  import { ALIAS_TYPES } from '../constants.js';
9
9
  import getDatabase from '../database/index.js';
10
10
  import { useLock } from '../lock/index.js';
@@ -17,18 +17,18 @@ const logger = useLogger();
17
17
  export async function getSchema(options, attempt = 0) {
18
18
  const MAX_ATTEMPTS = 3;
19
19
  const env = useEnv();
20
- if (attempt >= MAX_ATTEMPTS) {
21
- throw new Error(`Failed to get Schema information: hit infinite loop`);
22
- }
23
20
  if (options?.bypassCache || env['CACHE_SCHEMA'] === false) {
24
21
  const database = options?.database || getDatabase();
25
22
  const schemaInspector = createInspector(database);
26
23
  return await getDatabaseSchema(database, schemaInspector);
27
24
  }
28
- const cached = await getSchemaCache();
25
+ const cached = await getLocalSchemaCache();
29
26
  if (cached) {
30
27
  return cached;
31
28
  }
29
+ if (attempt >= MAX_ATTEMPTS) {
30
+ throw new Error(`Failed to get Schema information: hit infinite loop`);
31
+ }
32
32
  const lock = useLock();
33
33
  const bus = useBus();
34
34
  const lockKey = 'schemaCache--preparing';
@@ -40,39 +40,34 @@ export async function getSchema(options, attempt = 0) {
40
40
  const currentProcessShouldHandleOperation = processId === 1;
41
41
  if (currentProcessShouldHandleOperation === false) {
42
42
  logger.trace('Schema cache is prepared in another process, waiting for result.');
43
- return new Promise((resolve, reject) => {
44
- const TIMEOUT = 10000;
45
- const timeout = setTimeout(() => {
46
- logger.trace('Did not receive schema callback message in time. Pulling schema...');
47
- callback().catch(reject);
48
- }, TIMEOUT);
49
- bus.subscribe(messageKey, callback);
50
- async function callback() {
51
- try {
52
- if (timeout)
53
- clearTimeout(timeout);
54
- const schema = await getSchema(options, attempt + 1);
55
- resolve(schema);
56
- }
57
- catch (error) {
58
- reject(error);
59
- }
60
- finally {
61
- bus.unsubscribe(messageKey, callback);
43
+ const timeout = new Promise((_, reject) => setTimeout(reject, env['CACHE_SCHEMA_SYNC_TIMEOUT']));
44
+ const subscription = new Promise((resolve, reject) => {
45
+ bus.subscribe(messageKey, busListener).catch(reject);
46
+ function busListener(options) {
47
+ if (options.schema === null) {
48
+ return reject();
62
49
  }
50
+ cleanup();
51
+ setLocalSchemaCache(options.schema).catch(reject);
52
+ resolve(options.schema);
53
+ }
54
+ function cleanup() {
55
+ bus.unsubscribe(messageKey, busListener).catch(reject);
63
56
  }
64
57
  });
58
+ return Promise.race([timeout, subscription]).catch(() => getSchema(options, attempt + 1));
65
59
  }
60
+ let schema = null;
66
61
  try {
67
62
  const database = options?.database || getDatabase();
68
63
  const schemaInspector = createInspector(database);
69
- const schema = await getDatabaseSchema(database, schemaInspector);
70
- await setSchemaCache(schema);
64
+ schema = await getDatabaseSchema(database, schemaInspector);
65
+ await setLocalSchemaCache(schema);
71
66
  return schema;
72
67
  }
73
68
  finally {
69
+ await bus.publish(messageKey, { schema });
74
70
  await lock.delete(lockKey);
75
- bus.publish(messageKey, { ready: true });
76
71
  }
77
72
  }
78
73
  async function getDatabaseSchema(database, schemaInspector) {
@@ -1,13 +1,11 @@
1
1
  import { ForbiddenError } from '@directus/errors';
2
- import { AccessService, ActivityService, DashboardsService, FilesService, FlowsService, FoldersService, ItemsService, NotificationsService, OperationsService, PanelsService, PermissionsService, PoliciesService, PresetsService, RevisionsService, RolesService, SettingsService, SharesService, TranslationsService, UsersService, VersionsService, WebhooksService, } from '../services/index.js';
2
+ import { ActivityService, DashboardsService, FilesService, FlowsService, FoldersService, ItemsService, NotificationsService, OperationsService, PanelsService, PermissionsService, PresetsService, RevisionsService, RolesService, SettingsService, SharesService, TranslationsService, UsersService, VersionsService, WebhooksService, } from '../services/index.js';
3
3
  /**
4
4
  * Select the correct service for the given collection. This allows the individual services to run
5
5
  * their custom checks (f.e. it allows `UsersService` to prevent updating TFA secret from outside).
6
6
  */
7
7
  export function getService(collection, opts) {
8
8
  switch (collection) {
9
- case 'directus_access':
10
- return new AccessService(opts);
11
9
  case 'directus_activity':
12
10
  return new ActivityService(opts);
13
11
  case 'directus_dashboards':
@@ -28,8 +26,6 @@ export function getService(collection, opts) {
28
26
  return new PermissionsService(opts);
29
27
  case 'directus_presets':
30
28
  return new PresetsService(opts);
31
- case 'directus_policies':
32
- return new PoliciesService(opts);
33
29
  case 'directus_revisions':
34
30
  return new RevisionsService(opts);
35
31
  case 'directus_roles':
@@ -0,0 +1,4 @@
1
+ import type { Accountability, Filter, Permission, SchemaOverview } from '@directus/types';
2
+ export declare function mergePermissionsForShare(currentPermissions: Permission[], accountability: Accountability, schema: SchemaOverview): Permission[];
3
+ export declare function traverse(schema: SchemaOverview, rootItemPrimaryKeyField: string, rootItemPrimaryKey: string, currentCollection: string, parentCollections?: string[], path?: string[]): Partial<Permission>[];
4
+ export declare function getFilterForPath(type: 'o2m' | 'm2o' | 'a2o', path: string[], rootPrimaryKeyField: string, rootPrimaryKey: string): Filter;
@@ -0,0 +1,109 @@
1
+ import { assign, set, uniq } from 'lodash-es';
2
+ import { schemaPermissions } from '@directus/system-data';
3
+ import { mergePermissions } from './merge-permissions.js';
4
+ import { reduceSchema } from './reduce-schema.js';
5
+ export function mergePermissionsForShare(currentPermissions, accountability, schema) {
6
+ const defaults = {
7
+ action: 'read',
8
+ role: accountability.role,
9
+ collection: '',
10
+ permissions: {},
11
+ validation: null,
12
+ presets: null,
13
+ fields: null,
14
+ };
15
+ const { collection, item } = accountability.share_scope;
16
+ const parentPrimaryKeyField = schema.collections[collection].primary;
17
+ const reducedSchema = reduceSchema(schema, currentPermissions, ['read']);
18
+ const relationalPermissions = traverse(reducedSchema, parentPrimaryKeyField, item, collection);
19
+ const parentCollectionPermission = assign({}, defaults, {
20
+ collection,
21
+ permissions: {
22
+ [parentPrimaryKeyField]: {
23
+ _eq: item,
24
+ },
25
+ },
26
+ });
27
+ // All permissions that will be merged into the original permissions set
28
+ const allGeneratedPermissions = [
29
+ parentCollectionPermission,
30
+ ...relationalPermissions.map((generated) => assign({}, defaults, generated)),
31
+ ...schemaPermissions,
32
+ ];
33
+ // All the collections that are touched through the relational tree from the current root collection, and the schema collections
34
+ const allowedCollections = uniq(allGeneratedPermissions.map(({ collection }) => collection));
35
+ const generatedPermissions = [];
36
+ // Merge all the permissions that relate to the same collection with an _or (this allows you to properly retrieve)
37
+ // the items of a collection if you entered that collection from multiple angles
38
+ for (const collection of allowedCollections) {
39
+ const permissionsForCollection = allGeneratedPermissions.filter((permission) => permission.collection === collection);
40
+ if (permissionsForCollection.length > 0) {
41
+ generatedPermissions.push(...mergePermissions('or', permissionsForCollection));
42
+ }
43
+ else {
44
+ generatedPermissions.push(...permissionsForCollection);
45
+ }
46
+ }
47
+ // Explicitly filter out permissions to collections unrelated to the root parent item.
48
+ const limitedPermissions = currentPermissions.filter(({ action, collection }) => allowedCollections.includes(collection) && action === 'read');
49
+ return mergePermissions('and', limitedPermissions, generatedPermissions);
50
+ }
51
+ export function traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, currentCollection, parentCollections = [], path = []) {
52
+ const permissions = [];
53
+ // If there's already a permissions rule for the collection we're currently checking, we'll shortcircuit.
54
+ // This prevents infinite loop in recursive relationships, like articles->related_articles->articles, or
55
+ // articles.author->users.avatar->files.created_by->users.avatar->files.created_by->🔁
56
+ if (parentCollections.includes(currentCollection)) {
57
+ return permissions;
58
+ }
59
+ const relationsInCollection = schema.relations.filter((relation) => {
60
+ return relation.collection === currentCollection || relation.related_collection === currentCollection;
61
+ });
62
+ for (const relation of relationsInCollection) {
63
+ let type;
64
+ if (relation.related_collection === currentCollection) {
65
+ type = 'o2m';
66
+ }
67
+ else if (!relation.related_collection) {
68
+ type = 'a2o';
69
+ }
70
+ else {
71
+ type = 'm2o';
72
+ }
73
+ if (type === 'o2m') {
74
+ permissions.push({
75
+ collection: relation.collection,
76
+ permissions: getFilterForPath(type, [...path, relation.field], rootItemPrimaryKeyField, rootItemPrimaryKey),
77
+ });
78
+ permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.collection, [...parentCollections, currentCollection], [...path, relation.field]));
79
+ }
80
+ if (type === 'a2o' && relation.meta?.one_allowed_collections) {
81
+ for (const collection of relation.meta.one_allowed_collections) {
82
+ permissions.push({
83
+ collection,
84
+ permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field},${relation.meta.one_collection_field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
85
+ });
86
+ }
87
+ }
88
+ if (type === 'm2o') {
89
+ permissions.push({
90
+ collection: relation.related_collection,
91
+ permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
92
+ });
93
+ if (relation.meta?.one_field) {
94
+ permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.related_collection, [...parentCollections, currentCollection], [...path, relation.meta?.one_field]));
95
+ }
96
+ }
97
+ }
98
+ return permissions;
99
+ }
100
+ export function getFilterForPath(type, path, rootPrimaryKeyField, rootPrimaryKey) {
101
+ const filter = {};
102
+ if (type === 'm2o' || type === 'a2o') {
103
+ set(filter, path.reverse(), { [rootPrimaryKeyField]: { _eq: rootPrimaryKey } });
104
+ }
105
+ else {
106
+ set(filter, path.reverse(), { _eq: rootPrimaryKey });
107
+ }
108
+ return filter;
109
+ }
@@ -0,0 +1,3 @@
1
+ import type { Permission } from '@directus/types';
2
+ export declare function mergePermissions(strategy: 'and' | 'or', ...permissions: Permission[][]): Permission[];
3
+ export declare function mergePermission(strategy: 'and' | 'or', currentPerm: Permission, newPerm: Permission): Omit<Permission, 'id' | 'system'>;
@@ -0,0 +1,95 @@
1
+ import { flatten, intersection, isEqual, merge, omit } from 'lodash-es';
2
+ export function mergePermissions(strategy, ...permissions) {
3
+ const allPermissions = flatten(permissions);
4
+ const mergedPermissions = allPermissions
5
+ .reduce((acc, val) => {
6
+ const key = `${val.collection}__${val.action}__${val.role || '$PUBLIC'}`;
7
+ const current = acc.get(key);
8
+ acc.set(key, current ? mergePermission(strategy, current, val) : val);
9
+ return acc;
10
+ }, new Map())
11
+ .values();
12
+ return Array.from(mergedPermissions);
13
+ }
14
+ export function mergePermission(strategy, currentPerm, newPerm) {
15
+ const logicalKey = `_${strategy}`;
16
+ let permissions = currentPerm.permissions;
17
+ let validation = currentPerm.validation;
18
+ let fields = currentPerm.fields;
19
+ let presets = currentPerm.presets;
20
+ if (newPerm.permissions) {
21
+ if (currentPerm.permissions && Object.keys(currentPerm.permissions)[0] === logicalKey) {
22
+ permissions = {
23
+ [logicalKey]: [
24
+ ...currentPerm.permissions[logicalKey],
25
+ newPerm.permissions,
26
+ ],
27
+ };
28
+ }
29
+ else if (currentPerm.permissions) {
30
+ // Empty {} supersedes other permissions in _OR merge
31
+ if (strategy === 'or' && (isEqual(currentPerm.permissions, {}) || isEqual(newPerm.permissions, {}))) {
32
+ permissions = {};
33
+ }
34
+ else {
35
+ permissions = {
36
+ [logicalKey]: [currentPerm.permissions, newPerm.permissions],
37
+ };
38
+ }
39
+ }
40
+ else {
41
+ permissions = {
42
+ [logicalKey]: [newPerm.permissions],
43
+ };
44
+ }
45
+ }
46
+ if (newPerm.validation) {
47
+ if (currentPerm.validation && Object.keys(currentPerm.validation)[0] === logicalKey) {
48
+ validation = {
49
+ [logicalKey]: [
50
+ ...currentPerm.validation[logicalKey],
51
+ newPerm.validation,
52
+ ],
53
+ };
54
+ }
55
+ else if (currentPerm.validation) {
56
+ // Empty {} supersedes other validations in _OR merge
57
+ if (strategy === 'or' && (isEqual(currentPerm.validation, {}) || isEqual(newPerm.validation, {}))) {
58
+ validation = {};
59
+ }
60
+ else {
61
+ validation = {
62
+ [logicalKey]: [currentPerm.validation, newPerm.validation],
63
+ };
64
+ }
65
+ }
66
+ else {
67
+ validation = {
68
+ [logicalKey]: [newPerm.validation],
69
+ };
70
+ }
71
+ }
72
+ if (newPerm.fields) {
73
+ if (Array.isArray(currentPerm.fields) && strategy === 'or') {
74
+ fields = [...new Set([...currentPerm.fields, ...newPerm.fields])];
75
+ }
76
+ else if (Array.isArray(currentPerm.fields) && strategy === 'and') {
77
+ fields = intersection(currentPerm.fields, newPerm.fields);
78
+ }
79
+ else {
80
+ fields = newPerm.fields;
81
+ }
82
+ if (fields.includes('*'))
83
+ fields = ['*'];
84
+ }
85
+ if (newPerm.presets) {
86
+ presets = merge({}, presets, newPerm.presets);
87
+ }
88
+ return omit({
89
+ ...currentPerm,
90
+ permissions,
91
+ validation,
92
+ fields,
93
+ presets,
94
+ }, ['id', 'system']);
95
+ }
@@ -1,7 +1,9 @@
1
- import type { SchemaOverview } from '@directus/types';
2
- import type { FieldMap } from '../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
1
+ import type { Permission, PermissionsAction, SchemaOverview } from '@directus/types';
3
2
  /**
4
3
  * Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
5
- * the allowed collections/fields/relations included based on the passed field map.
4
+ * the allowed collections/fields/relations included based on the permissions.
5
+ * @param schema The full project schema
6
+ * @param actions Array of permissions actions (crud)
7
+ * @returns Reduced schema
6
8
  */
7
- export declare function reduceSchema(schema: SchemaOverview, fieldMap: FieldMap): SchemaOverview;
9
+ export declare function reduceSchema(schema: SchemaOverview, permissions: Permission[] | null, actions?: PermissionsAction[]): SchemaOverview;
@@ -1,24 +1,40 @@
1
+ import { uniq } from 'lodash-es';
1
2
  /**
2
3
  * Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
3
- * the allowed collections/fields/relations included based on the passed field map.
4
+ * the allowed collections/fields/relations included based on the permissions.
5
+ * @param schema The full project schema
6
+ * @param actions Array of permissions actions (crud)
7
+ * @returns Reduced schema
4
8
  */
5
- export function reduceSchema(schema, fieldMap) {
9
+ export function reduceSchema(schema, permissions, actions = ['create', 'read', 'update', 'delete']) {
6
10
  const reduced = {
7
11
  collections: {},
8
12
  relations: [],
9
13
  };
14
+ const allowedFieldsInCollection = permissions
15
+ ?.filter((permission) => actions.includes(permission.action))
16
+ .reduce((acc, permission) => {
17
+ if (!acc[permission.collection]) {
18
+ acc[permission.collection] = [];
19
+ }
20
+ if (permission.fields) {
21
+ acc[permission.collection] = uniq([...acc[permission.collection], ...permission.fields]);
22
+ }
23
+ return acc;
24
+ }, {}) ?? {};
10
25
  for (const [collectionName, collection] of Object.entries(schema.collections)) {
11
- if (!fieldMap[collectionName]) {
12
- // Collection is not allowed at all
26
+ if (!permissions?.some((permission) => permission.collection === collectionName && actions.includes(permission.action))) {
13
27
  continue;
14
28
  }
15
29
  const fields = {};
16
30
  for (const [fieldName, field] of Object.entries(schema.collections[collectionName].fields)) {
17
- if (!fieldMap[collectionName]?.includes('*') && !fieldMap[collectionName]?.includes(fieldName)) {
31
+ if (!allowedFieldsInCollection[collectionName]?.includes('*') &&
32
+ !allowedFieldsInCollection[collectionName]?.includes(fieldName)) {
18
33
  continue;
19
34
  }
20
35
  const o2mRelation = schema.relations.find((relation) => relation.related_collection === collectionName && relation.meta?.one_field === fieldName);
21
- if (o2mRelation && !fieldMap[collectionName]) {
36
+ if (o2mRelation &&
37
+ !permissions?.some((permission) => permission.collection === o2mRelation.collection && actions.includes(permission.action))) {
22
38
  continue;
23
39
  }
24
40
  fields[fieldName] = field;
@@ -31,29 +47,29 @@ export function reduceSchema(schema, fieldMap) {
31
47
  reduced.relations = schema.relations.filter((relation) => {
32
48
  let collectionsAllowed = true;
33
49
  let fieldsAllowed = true;
34
- if (Object.keys(fieldMap).includes(relation.collection) === false) {
50
+ if (Object.keys(allowedFieldsInCollection).includes(relation.collection) === false) {
35
51
  collectionsAllowed = false;
36
52
  }
37
53
  if (relation.related_collection &&
38
- (Object.keys(fieldMap).includes(relation.related_collection) === false ||
54
+ (Object.keys(allowedFieldsInCollection).includes(relation.related_collection) === false ||
39
55
  // Ignore legacy permissions with an empty fields array
40
- fieldMap[relation.related_collection]?.length === 0)) {
56
+ allowedFieldsInCollection[relation.related_collection]?.length === 0)) {
41
57
  collectionsAllowed = false;
42
58
  }
43
59
  if (relation.meta?.one_allowed_collections &&
44
- relation.meta.one_allowed_collections.every((collection) => Object.keys(fieldMap).includes(collection)) === false) {
60
+ relation.meta.one_allowed_collections.every((collection) => Object.keys(allowedFieldsInCollection).includes(collection)) === false) {
45
61
  collectionsAllowed = false;
46
62
  }
47
- if (!fieldMap[relation.collection] ||
48
- (fieldMap[relation.collection]?.includes('*') === false &&
49
- fieldMap[relation.collection]?.includes(relation.field) === false)) {
63
+ if (!allowedFieldsInCollection[relation.collection] ||
64
+ (allowedFieldsInCollection[relation.collection]?.includes('*') === false &&
65
+ allowedFieldsInCollection[relation.collection]?.includes(relation.field) === false)) {
50
66
  fieldsAllowed = false;
51
67
  }
52
68
  if (relation.related_collection &&
53
69
  relation.meta?.one_field &&
54
- (!fieldMap[relation.related_collection] ||
55
- (fieldMap[relation.related_collection]?.includes('*') === false &&
56
- fieldMap[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
70
+ (!allowedFieldsInCollection[relation.related_collection] ||
71
+ (allowedFieldsInCollection[relation.related_collection]?.includes('*') === false &&
72
+ allowedFieldsInCollection[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
57
73
  fieldsAllowed = false;
58
74
  }
59
75
  return collectionsAllowed && fieldsAllowed;
@@ -1,4 +1,6 @@
1
+ import type { Accountability } from '@directus/types';
1
2
  import type { BasicAuthMessage } from './messages.js';
2
3
  import type { AuthenticationState } from './types.js';
3
4
  export declare function authenticateConnection(message: BasicAuthMessage & Record<string, any>): Promise<AuthenticationState>;
5
+ export declare function refreshAccountability(accountability: Accountability | null | undefined): Promise<Accountability>;
4
6
  export declare function authenticationSuccess(uid?: string | number, refresh_token?: string): string;
@@ -1,6 +1,7 @@
1
1
  import { DEFAULT_AUTH_PROVIDER } from '../constants.js';
2
2
  import { AuthenticationService } from '../services/index.js';
3
3
  import { getAccountabilityForToken } from '../utils/get-accountability-for-token.js';
4
+ import { getPermissions } from '../utils/get-permissions.js';
4
5
  import { getSchema } from '../utils/get-schema.js';
5
6
  import { WebSocketError } from './errors.js';
6
7
  import { getExpiresAtForToken } from './utils/get-expires-at-for-token.js';
@@ -32,6 +33,17 @@ export async function authenticateConnection(message) {
32
33
  throw new WebSocketError('auth', 'AUTH_FAILED', 'Authentication failed.', message['uid']);
33
34
  }
34
35
  }
36
+ export async function refreshAccountability(accountability) {
37
+ accountability = accountability ?? {
38
+ role: null,
39
+ user: null,
40
+ admin: false,
41
+ app: false,
42
+ };
43
+ const schema = await getSchema();
44
+ const permissions = await getPermissions(accountability, schema);
45
+ return { ...accountability, permissions };
46
+ }
35
47
  export function authenticationSuccess(uid, refresh_token) {
36
48
  const message = {
37
49
  type: 'auth',
@@ -4,7 +4,7 @@ import { useLogger } from '../../logger/index.js';
4
4
  import { bindPubSub } from '../../services/graphql/subscription.js';
5
5
  import { GraphQLService } from '../../services/index.js';
6
6
  import { getSchema } from '../../utils/get-schema.js';
7
- import { authenticateConnection } from '../authenticate.js';
7
+ import { authenticateConnection, refreshAccountability } from '../authenticate.js';
8
8
  import { handleWebSocketError } from '../errors.js';
9
9
  import { ConnectionParams, WebSocketMessage } from '../messages.js';
10
10
  import { getMessageType } from '../utils/message.js';
@@ -64,6 +64,9 @@ export class GraphQLSubscriptionController extends SocketController {
64
64
  client.close(CloseCode.Forbidden, 'Forbidden');
65
65
  return;
66
66
  }
67
+ else {
68
+ client.accountability = await refreshAccountability(client.accountability);
69
+ }
67
70
  await cb(JSON.stringify(message));
68
71
  }
69
72
  catch (error) {
@@ -7,23 +7,19 @@ export function registerWebSocketEvents() {
7
7
  actionsRegistered = true;
8
8
  registerActionHooks([
9
9
  'items',
10
- 'access',
11
10
  'activity',
12
11
  'collections',
13
12
  'dashboards',
14
- 'flows',
15
13
  'folders',
16
14
  'notifications',
17
15
  'operations',
18
16
  'panels',
19
17
  'permissions',
20
- 'policies',
21
18
  'presets',
22
19
  'revisions',
23
20
  'roles',
24
21
  'settings',
25
22
  'shares',
26
- 'translations',
27
23
  'users',
28
24
  'versions',
29
25
  'webhooks',
@@ -2,6 +2,7 @@ import { useEnv } from '@directus/env';
2
2
  import { parseJSON } from '@directus/utils';
3
3
  import emitter from '../../emitter.js';
4
4
  import { useLogger } from '../../logger/index.js';
5
+ import { refreshAccountability } from '../authenticate.js';
5
6
  import { WebSocketError, handleWebSocketError } from '../errors.js';
6
7
  import { WebSocketMessage } from '../messages.js';
7
8
  import SocketController from './base.js';
@@ -19,6 +20,7 @@ export class WebSocketController extends SocketController {
19
20
  client.on('parsed-message', async (message) => {
20
21
  try {
21
22
  message = WebSocketMessage.parse(await emitter.emitFilter('websocket.message', message, { client }));
23
+ client.accountability = await refreshAccountability(client.accountability);
22
24
  emitter.emitAction('websocket.message', { message, client });
23
25
  }
24
26
  catch (error) {
@@ -4,6 +4,7 @@ import { useBus } from '../../bus/index.js';
4
4
  import emitter from '../../emitter.js';
5
5
  import { getSchema } from '../../utils/get-schema.js';
6
6
  import { sanitizeQuery } from '../../utils/sanitize-query.js';
7
+ import { refreshAccountability } from '../authenticate.js';
7
8
  import { WebSocketError, handleWebSocketError } from '../errors.js';
8
9
  import { WebSocketSubscribeMessage } from '../messages.js';
9
10
  import { getPayload } from '../utils/items.js';
@@ -111,6 +112,7 @@ export class SubscribeHandler {
111
112
  continue;
112
113
  }
113
114
  try {
115
+ client.accountability = await refreshAccountability(client.accountability);
114
116
  const result = await getPayload(subscription, client.accountability, schema, event);
115
117
  if (Array.isArray(result?.['data']) && result?.['data']?.length === 0)
116
118
  continue;
@@ -39,5 +39,5 @@ export declare function getFieldsPayload(subscription: PSubscription, accountabi
39
39
  * @param event Event data
40
40
  * @returns the fetched data
41
41
  */
42
- export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number | (string | number)[] | import("@directus/types").Item | import("@directus/types").Item[]>;
42
+ export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number | import("@directus/types").Item | (string | number)[] | import("@directus/types").Item[]>;
43
43
  export {};