@directus/api 11.0.1 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/app.js +3 -4
  2. package/dist/auth/auth.d.ts +4 -4
  3. package/dist/auth/auth.js +2 -2
  4. package/dist/auth/drivers/ldap.js +20 -17
  5. package/dist/auth/drivers/local.js +5 -5
  6. package/dist/auth/drivers/oauth2.js +16 -16
  7. package/dist/auth/drivers/openid.js +18 -17
  8. package/dist/auth/drivers/saml.js +6 -7
  9. package/dist/auth.js +3 -2
  10. package/dist/cache.js +3 -13
  11. package/dist/cli/utils/create-env/env-stub.liquid +5 -7
  12. package/dist/controllers/activity.js +7 -6
  13. package/dist/controllers/assets.js +25 -12
  14. package/dist/controllers/auth.js +8 -7
  15. package/dist/controllers/collections.js +4 -3
  16. package/dist/controllers/dashboards.js +5 -4
  17. package/dist/controllers/extensions.js +3 -3
  18. package/dist/controllers/fields.js +9 -8
  19. package/dist/controllers/files.js +11 -11
  20. package/dist/controllers/flows.js +5 -4
  21. package/dist/controllers/folders.js +5 -4
  22. package/dist/controllers/items.js +14 -13
  23. package/dist/controllers/not-found.js +2 -2
  24. package/dist/controllers/notifications.js +5 -4
  25. package/dist/controllers/operations.js +5 -4
  26. package/dist/controllers/panels.js +5 -4
  27. package/dist/controllers/permissions.js +5 -4
  28. package/dist/controllers/presets.js +5 -4
  29. package/dist/controllers/relations.js +6 -5
  30. package/dist/controllers/roles.js +5 -4
  31. package/dist/controllers/schema.js +8 -8
  32. package/dist/controllers/server.js +2 -2
  33. package/dist/controllers/settings.js +3 -2
  34. package/dist/controllers/shares.js +7 -6
  35. package/dist/controllers/translations.js +6 -5
  36. package/dist/controllers/users.js +22 -21
  37. package/dist/controllers/utils.js +10 -10
  38. package/dist/controllers/webhooks.js +5 -4
  39. package/dist/{exceptions/database → database/errors}/dialects/mssql.js +8 -18
  40. package/dist/{exceptions/database → database/errors}/dialects/mysql.js +9 -19
  41. package/dist/{exceptions/database → database/errors}/dialects/oracle.js +2 -2
  42. package/dist/{exceptions/database → database/errors}/dialects/postgres.js +7 -18
  43. package/dist/{exceptions/database → database/errors}/dialects/sqlite.js +7 -10
  44. package/dist/{exceptions/database → database/errors}/translate.js +1 -1
  45. package/dist/database/migrations/run.js +10 -1
  46. package/dist/emitter.d.ts +3 -2
  47. package/dist/emitter.js +12 -4
  48. package/dist/env.js +21 -17
  49. package/dist/errors/codes.d.ts +29 -0
  50. package/dist/errors/codes.js +30 -0
  51. package/dist/errors/contains-null-values.d.ts +7 -0
  52. package/dist/errors/contains-null-values.js +4 -0
  53. package/dist/errors/content-too-large.d.ts +1 -0
  54. package/dist/errors/content-too-large.js +3 -0
  55. package/dist/errors/forbidden.d.ts +1 -0
  56. package/dist/errors/forbidden.js +3 -0
  57. package/dist/errors/hit-rate-limit.d.ts +6 -0
  58. package/dist/errors/hit-rate-limit.js +8 -0
  59. package/dist/errors/illegal-asset-transformation.d.ts +4 -0
  60. package/dist/errors/illegal-asset-transformation.js +3 -0
  61. package/dist/errors/index.d.ts +28 -0
  62. package/dist/errors/index.js +28 -0
  63. package/dist/errors/invalid-credentials.d.ts +1 -0
  64. package/dist/errors/invalid-credentials.js +3 -0
  65. package/dist/errors/invalid-foreign-key.d.ts +6 -0
  66. package/dist/errors/invalid-foreign-key.js +14 -0
  67. package/dist/errors/invalid-ip.d.ts +1 -0
  68. package/dist/errors/invalid-ip.js +3 -0
  69. package/dist/errors/invalid-otp.d.ts +1 -0
  70. package/dist/errors/invalid-otp.js +3 -0
  71. package/dist/errors/invalid-payload.d.ts +5 -0
  72. package/dist/errors/invalid-payload.js +4 -0
  73. package/dist/errors/invalid-provider-config.d.ts +5 -0
  74. package/dist/errors/invalid-provider-config.js +3 -0
  75. package/dist/errors/invalid-provider.d.ts +1 -0
  76. package/dist/errors/invalid-provider.js +3 -0
  77. package/dist/errors/invalid-query.d.ts +5 -0
  78. package/dist/errors/invalid-query.js +4 -0
  79. package/dist/errors/invalid-token.d.ts +1 -0
  80. package/dist/errors/invalid-token.js +3 -0
  81. package/dist/errors/method-not-allowed.d.ts +6 -0
  82. package/dist/errors/method-not-allowed.js +6 -0
  83. package/dist/errors/not-null-violation.d.ts +6 -0
  84. package/dist/errors/not-null-violation.js +14 -0
  85. package/dist/errors/range-not-satisfiable.d.ts +7 -0
  86. package/dist/errors/range-not-satisfiable.js +7 -0
  87. package/dist/errors/record-not-unique.d.ts +6 -0
  88. package/dist/errors/record-not-unique.js +14 -0
  89. package/dist/errors/route-not-found.d.ts +5 -0
  90. package/dist/errors/route-not-found.js +4 -0
  91. package/dist/errors/service-unavailable.d.ts +7 -0
  92. package/dist/errors/service-unavailable.js +4 -0
  93. package/dist/errors/token-expired.d.ts +1 -0
  94. package/dist/errors/token-expired.js +3 -0
  95. package/dist/errors/unexpected-response.d.ts +1 -0
  96. package/dist/errors/unexpected-response.js +3 -0
  97. package/dist/errors/unprocessable-content.d.ts +5 -0
  98. package/dist/errors/unprocessable-content.js +4 -0
  99. package/dist/errors/unsupported-media-type.d.ts +6 -0
  100. package/dist/errors/unsupported-media-type.js +4 -0
  101. package/dist/errors/user-suspended.d.ts +1 -0
  102. package/dist/errors/user-suspended.js +3 -0
  103. package/dist/errors/value-out-of-range.d.ts +6 -0
  104. package/dist/errors/value-out-of-range.js +14 -0
  105. package/dist/errors/value-too-long.d.ts +6 -0
  106. package/dist/errors/value-too-long.js +14 -0
  107. package/dist/extensions.js +0 -4
  108. package/dist/flows.js +6 -8
  109. package/dist/index.d.ts +0 -2
  110. package/dist/index.js +0 -2
  111. package/dist/messenger.d.ts +3 -3
  112. package/dist/messenger.js +18 -9
  113. package/dist/middleware/authenticate.js +2 -38
  114. package/dist/middleware/check-ip.js +2 -2
  115. package/dist/middleware/collection-exists.js +2 -2
  116. package/dist/middleware/error-handler.js +7 -7
  117. package/dist/middleware/graphql.js +11 -9
  118. package/dist/middleware/rate-limiter-global.d.ts +2 -2
  119. package/dist/middleware/rate-limiter-global.js +2 -3
  120. package/dist/middleware/rate-limiter-ip.d.ts +2 -2
  121. package/dist/middleware/rate-limiter-ip.js +2 -3
  122. package/dist/middleware/validate-batch.js +3 -4
  123. package/dist/rate-limiter.js +2 -9
  124. package/dist/server.js +10 -0
  125. package/dist/services/activity.js +3 -2
  126. package/dist/services/assets.js +9 -10
  127. package/dist/services/authentication.js +12 -11
  128. package/dist/services/authorization.d.ts +1 -1
  129. package/dist/services/authorization.js +16 -16
  130. package/dist/services/collections.js +17 -16
  131. package/dist/services/fields.js +16 -14
  132. package/dist/services/files.js +7 -6
  133. package/dist/services/graphql/errors/execution.d.ts +6 -0
  134. package/dist/services/graphql/errors/execution.js +2 -0
  135. package/dist/services/graphql/errors/index.d.ts +2 -0
  136. package/dist/services/graphql/errors/index.js +2 -0
  137. package/dist/services/graphql/errors/validation.d.ts +6 -0
  138. package/dist/services/graphql/errors/validation.js +2 -0
  139. package/dist/services/graphql/index.d.ts +2 -8
  140. package/dist/services/graphql/index.js +125 -66
  141. package/dist/services/graphql/subscription.d.ts +16 -0
  142. package/dist/services/graphql/subscription.js +77 -0
  143. package/dist/services/graphql/utils/process-error.js +3 -3
  144. package/dist/services/import-export.js +7 -7
  145. package/dist/services/index.d.ts +1 -0
  146. package/dist/services/index.js +1 -0
  147. package/dist/services/items.js +14 -13
  148. package/dist/services/mail/index.js +3 -3
  149. package/dist/services/meta.js +3 -3
  150. package/dist/services/payload.js +11 -7
  151. package/dist/services/relations.js +32 -22
  152. package/dist/services/revisions.js +3 -3
  153. package/dist/services/roles.js +10 -9
  154. package/dist/services/schema.js +5 -5
  155. package/dist/services/server.js +24 -0
  156. package/dist/services/shares.js +4 -4
  157. package/dist/services/tfa.js +6 -6
  158. package/dist/services/translations.d.ts +2 -2
  159. package/dist/services/translations.js +4 -4
  160. package/dist/services/users.js +26 -29
  161. package/dist/services/utils.js +4 -4
  162. package/dist/services/websocket.d.ts +14 -0
  163. package/dist/services/websocket.js +26 -0
  164. package/dist/synchronization.js +3 -3
  165. package/dist/types/items.d.ts +2 -2
  166. package/dist/utils/apply-diff.js +13 -4
  167. package/dist/utils/apply-query.js +22 -13
  168. package/dist/utils/get-accountability-for-role.js +1 -2
  169. package/dist/utils/get-accountability-for-token.d.ts +2 -0
  170. package/dist/utils/get-accountability-for-token.js +50 -0
  171. package/dist/utils/get-column-path.js +5 -3
  172. package/dist/utils/get-column.js +3 -3
  173. package/dist/utils/get-service.d.ts +7 -0
  174. package/dist/utils/get-service.js +49 -0
  175. package/dist/utils/jwt.js +5 -5
  176. package/dist/utils/redact.d.ts +4 -0
  177. package/dist/utils/redact.js +15 -1
  178. package/dist/utils/to-boolean.d.ts +4 -0
  179. package/dist/utils/to-boolean.js +6 -0
  180. package/dist/utils/validate-diff.js +23 -9
  181. package/dist/utils/validate-keys.js +3 -3
  182. package/dist/utils/validate-query.d.ts +2 -0
  183. package/dist/utils/validate-query.js +27 -21
  184. package/dist/utils/validate-snapshot.js +11 -5
  185. package/dist/websocket/authenticate.d.ts +6 -0
  186. package/dist/websocket/authenticate.js +59 -0
  187. package/dist/websocket/controllers/base.d.ts +42 -0
  188. package/dist/websocket/controllers/base.js +279 -0
  189. package/dist/websocket/controllers/graphql.d.ts +12 -0
  190. package/dist/websocket/controllers/graphql.js +102 -0
  191. package/dist/websocket/controllers/hooks.d.ts +1 -0
  192. package/dist/websocket/controllers/hooks.js +122 -0
  193. package/dist/websocket/controllers/index.d.ts +10 -0
  194. package/dist/websocket/controllers/index.js +31 -0
  195. package/dist/websocket/controllers/rest.d.ts +9 -0
  196. package/dist/websocket/controllers/rest.js +47 -0
  197. package/dist/websocket/errors.d.ts +16 -0
  198. package/dist/websocket/errors.js +55 -0
  199. package/dist/websocket/handlers/heartbeat.d.ts +11 -0
  200. package/dist/websocket/handlers/heartbeat.js +72 -0
  201. package/dist/websocket/handlers/index.d.ts +4 -0
  202. package/dist/websocket/handlers/index.js +11 -0
  203. package/dist/websocket/handlers/items.d.ts +6 -0
  204. package/dist/websocket/handlers/items.js +103 -0
  205. package/dist/websocket/handlers/subscribe.d.ts +43 -0
  206. package/dist/websocket/handlers/subscribe.js +278 -0
  207. package/dist/websocket/messages.d.ts +311 -0
  208. package/dist/websocket/messages.js +96 -0
  209. package/dist/websocket/types.d.ts +34 -0
  210. package/dist/websocket/types.js +1 -0
  211. package/dist/websocket/utils/get-expires-at-for-token.d.ts +1 -0
  212. package/dist/websocket/utils/get-expires-at-for-token.js +8 -0
  213. package/dist/websocket/utils/message.d.ts +4 -0
  214. package/dist/websocket/utils/message.js +27 -0
  215. package/dist/websocket/utils/wait-for-message.d.ts +4 -0
  216. package/dist/websocket/utils/wait-for-message.js +45 -0
  217. package/package.json +21 -16
  218. package/dist/exceptions/content-too-large.d.ts +0 -4
  219. package/dist/exceptions/content-too-large.js +0 -6
  220. package/dist/exceptions/database/contains-null-values.d.ts +0 -9
  221. package/dist/exceptions/database/contains-null-values.js +0 -6
  222. package/dist/exceptions/database/invalid-foreign-key.d.ts +0 -10
  223. package/dist/exceptions/database/invalid-foreign-key.js +0 -11
  224. package/dist/exceptions/database/not-null-violation.d.ts +0 -9
  225. package/dist/exceptions/database/not-null-violation.js +0 -6
  226. package/dist/exceptions/database/record-not-unique.d.ts +0 -10
  227. package/dist/exceptions/database/record-not-unique.js +0 -11
  228. package/dist/exceptions/database/value-out-of-range.d.ts +0 -10
  229. package/dist/exceptions/database/value-out-of-range.js +0 -11
  230. package/dist/exceptions/database/value-too-long.d.ts +0 -9
  231. package/dist/exceptions/database/value-too-long.js +0 -11
  232. package/dist/exceptions/forbidden.d.ts +0 -6
  233. package/dist/exceptions/forbidden.js +0 -13
  234. package/dist/exceptions/graphql-validation.d.ts +0 -4
  235. package/dist/exceptions/graphql-validation.js +0 -6
  236. package/dist/exceptions/hit-rate-limit.d.ts +0 -9
  237. package/dist/exceptions/hit-rate-limit.js +0 -6
  238. package/dist/exceptions/illegal-asset-transformation.d.ts +0 -4
  239. package/dist/exceptions/illegal-asset-transformation.js +0 -6
  240. package/dist/exceptions/index.d.ts +0 -21
  241. package/dist/exceptions/index.js +0 -21
  242. package/dist/exceptions/invalid-config.d.ts +0 -4
  243. package/dist/exceptions/invalid-config.js +0 -6
  244. package/dist/exceptions/invalid-credentials.d.ts +0 -4
  245. package/dist/exceptions/invalid-credentials.js +0 -6
  246. package/dist/exceptions/invalid-ip.d.ts +0 -4
  247. package/dist/exceptions/invalid-ip.js +0 -6
  248. package/dist/exceptions/invalid-otp.d.ts +0 -4
  249. package/dist/exceptions/invalid-otp.js +0 -6
  250. package/dist/exceptions/invalid-payload.d.ts +0 -4
  251. package/dist/exceptions/invalid-payload.js +0 -6
  252. package/dist/exceptions/invalid-provider.d.ts +0 -4
  253. package/dist/exceptions/invalid-provider.js +0 -6
  254. package/dist/exceptions/invalid-query.d.ts +0 -4
  255. package/dist/exceptions/invalid-query.js +0 -6
  256. package/dist/exceptions/invalid-token.d.ts +0 -4
  257. package/dist/exceptions/invalid-token.js +0 -6
  258. package/dist/exceptions/method-not-allowed.d.ts +0 -8
  259. package/dist/exceptions/method-not-allowed.js +0 -6
  260. package/dist/exceptions/range-not-satisfiable.d.ts +0 -5
  261. package/dist/exceptions/range-not-satisfiable.js +0 -9
  262. package/dist/exceptions/route-not-found.d.ts +0 -4
  263. package/dist/exceptions/route-not-found.js +0 -6
  264. package/dist/exceptions/service-unavailable.d.ts +0 -9
  265. package/dist/exceptions/service-unavailable.js +0 -6
  266. package/dist/exceptions/token-expired.d.ts +0 -4
  267. package/dist/exceptions/token-expired.js +0 -6
  268. package/dist/exceptions/unexpected-response.d.ts +0 -4
  269. package/dist/exceptions/unexpected-response.js +0 -6
  270. package/dist/exceptions/unprocessable-entity.d.ts +0 -4
  271. package/dist/exceptions/unprocessable-entity.js +0 -6
  272. package/dist/exceptions/unsupported-media-type.d.ts +0 -4
  273. package/dist/exceptions/unsupported-media-type.js +0 -6
  274. package/dist/exceptions/user-suspended.d.ts +0 -4
  275. package/dist/exceptions/user-suspended.js +0 -6
  276. /package/dist/{exceptions/database → database/errors}/dialects/mssql.d.ts +0 -0
  277. /package/dist/{exceptions/database → database/errors}/dialects/mysql.d.ts +0 -0
  278. /package/dist/{exceptions/database → database/errors}/dialects/oracle.d.ts +0 -0
  279. /package/dist/{exceptions/database → database/errors}/dialects/postgres.d.ts +0 -0
  280. /package/dist/{exceptions/database → database/errors}/dialects/sqlite.d.ts +0 -0
  281. /package/dist/{exceptions/database → database/errors}/dialects/types.d.ts +0 -0
  282. /package/dist/{exceptions/database → database/errors}/dialects/types.js +0 -0
  283. /package/dist/{exceptions/database → database/errors}/translate.d.ts +0 -0
@@ -3,7 +3,7 @@ import Busboy from 'busboy';
3
3
  import { Router } from 'express';
4
4
  import Joi from 'joi';
5
5
  import { flushCaches } from '../cache.js';
6
- import { ForbiddenException, InvalidPayloadException, InvalidQueryException, UnsupportedMediaTypeException, } from '../exceptions/index.js';
6
+ import { ForbiddenError, InvalidPayloadError, InvalidQueryError, UnsupportedMediaTypeError } from '../errors/index.js';
7
7
  import collectionExists from '../middleware/collection-exists.js';
8
8
  import { respond } from '../middleware/respond.js';
9
9
  import { ExportService, ImportService } from '../services/import-export.js';
@@ -16,24 +16,24 @@ const router = Router();
16
16
  router.get('/random/string', asyncHandler(async (req, res) => {
17
17
  const { nanoid } = await import('nanoid');
18
18
  if (req.query && req.query['length'] && Number(req.query['length']) > 500) {
19
- throw new InvalidQueryException(`"length" can't be more than 500 characters`);
19
+ throw new InvalidQueryError({ reason: `"length" can't be more than 500 characters` });
20
20
  }
21
21
  const string = nanoid(req.query?.['length'] ? Number(req.query['length']) : 32);
22
22
  return res.json({ data: string });
23
23
  }));
24
24
  router.post('/hash/generate', asyncHandler(async (req, res) => {
25
25
  if (!req.body?.string) {
26
- throw new InvalidPayloadException(`"string" is required`);
26
+ throw new InvalidPayloadError({ reason: `"string" is required` });
27
27
  }
28
28
  const hash = await generateHash(req.body.string);
29
29
  return res.json({ data: hash });
30
30
  }));
31
31
  router.post('/hash/verify', asyncHandler(async (req, res) => {
32
32
  if (!req.body?.string) {
33
- throw new InvalidPayloadException(`"string" is required`);
33
+ throw new InvalidPayloadError({ reason: `"string" is required` });
34
34
  }
35
35
  if (!req.body?.hash) {
36
- throw new InvalidPayloadException(`"hash" is required`);
36
+ throw new InvalidPayloadError({ reason: `"hash" is required` });
37
37
  }
38
38
  const result = await argon2.verify(req.body.hash, req.body.string);
39
39
  return res.json({ data: result });
@@ -45,7 +45,7 @@ const SortSchema = Joi.object({
45
45
  router.post('/sort/:collection', collectionExists, asyncHandler(async (req, res) => {
46
46
  const { error } = SortSchema.validate(req.body);
47
47
  if (error)
48
- throw new InvalidPayloadException(error.message);
48
+ throw new InvalidPayloadError({ reason: error.message });
49
49
  const service = new UtilsService({
50
50
  accountability: req.accountability,
51
51
  schema: req.schema,
@@ -63,7 +63,7 @@ router.post('/revert/:revision', asyncHandler(async (req, _res, next) => {
63
63
  }), respond);
64
64
  router.post('/import/:collection', collectionExists, asyncHandler(async (req, res, next) => {
65
65
  if (req.is('multipart/form-data') === false) {
66
- throw new UnsupportedMediaTypeException(`Unsupported Content-Type header`);
66
+ throw new UnsupportedMediaTypeError({ mediaType: req.headers['content-type'], where: 'Content-Type header' });
67
67
  }
68
68
  const service = new ImportService({
69
69
  accountability: req.accountability,
@@ -94,10 +94,10 @@ router.post('/import/:collection', collectionExists, asyncHandler(async (req, re
94
94
  }));
95
95
  router.post('/export/:collection', collectionExists, asyncHandler(async (req, _res, next) => {
96
96
  if (!req.body.query) {
97
- throw new InvalidPayloadException(`"query" is required.`);
97
+ throw new InvalidPayloadError({ reason: `"query" is required` });
98
98
  }
99
99
  if (!req.body.format) {
100
- throw new InvalidPayloadException(`"format" is required.`);
100
+ throw new InvalidPayloadError({ reason: `"format" is required` });
101
101
  }
102
102
  const service = new ExportService({
103
103
  accountability: req.accountability,
@@ -112,7 +112,7 @@ router.post('/export/:collection', collectionExists, asyncHandler(async (req, _r
112
112
  }), respond);
113
113
  router.post('/cache/clear', asyncHandler(async (req, res) => {
114
114
  if (req.accountability?.admin !== true) {
115
- throw new ForbiddenException();
115
+ throw new ForbiddenError();
116
116
  }
117
117
  await flushCaches(true);
118
118
  res.status(200).end();
@@ -1,5 +1,6 @@
1
+ import { isDirectusError } from '@directus/errors';
1
2
  import express from 'express';
2
- import { ForbiddenException } from '../exceptions/index.js';
3
+ import { ErrorCode } from '../errors/index.js';
3
4
  import { respond } from '../middleware/respond.js';
4
5
  import useCollection from '../middleware/use-collection.js';
5
6
  import { validateBatch } from '../middleware/validate-batch.js';
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
34
35
  }
35
36
  }
36
37
  catch (error) {
37
- if (error instanceof ForbiddenException) {
38
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
38
39
  return next();
39
40
  }
40
41
  throw error;
@@ -84,7 +85,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
84
85
  res.locals['payload'] = { data: result };
85
86
  }
86
87
  catch (error) {
87
- if (error instanceof ForbiddenException) {
88
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
88
89
  return next();
89
90
  }
90
91
  throw error;
@@ -102,7 +103,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
102
103
  res.locals['payload'] = { data: item || null };
103
104
  }
104
105
  catch (error) {
105
- if (error instanceof ForbiddenException) {
106
+ if (isDirectusError(error, ErrorCode.Forbidden)) {
106
107
  return next();
107
108
  }
108
109
  throw error;
@@ -1,10 +1,5 @@
1
- import getDatabase from '../../../database/index.js';
2
- import { ContainsNullValuesException } from '../contains-null-values.js';
3
- import { InvalidForeignKeyException } from '../invalid-foreign-key.js';
4
- import { NotNullViolationException } from '../not-null-violation.js';
5
- import { RecordNotUniqueException } from '../record-not-unique.js';
6
- import { ValueOutOfRangeException } from '../value-out-of-range.js';
7
- import { ValueTooLongException } from '../value-too-long.js';
1
+ import { ContainsNullValuesError, InvalidForeignKeyError, NotNullViolationError, RecordNotUniqueError, ValueOutOfRangeError, ValueTooLongError, } from '../../../errors/index.js';
2
+ import getDatabase from '../../index.js';
8
3
  var MSSQLErrorCodes;
9
4
  (function (MSSQLErrorCodes) {
10
5
  MSSQLErrorCodes[MSSQLErrorCodes["FOREIGN_KEY_VIOLATION"] = 547] = "FOREIGN_KEY_VIOLATION";
@@ -70,11 +65,9 @@ async function uniqueViolation(error) {
70
65
  collection = constraintUsage?.collection;
71
66
  field = constraintUsage?.field;
72
67
  }
73
- const invalid = parenMatches[parenMatches.length - 1]?.slice(1, -1);
74
- return new RecordNotUniqueException(field, {
68
+ return new RecordNotUniqueError({
75
69
  collection,
76
70
  field,
77
- invalid,
78
71
  });
79
72
  }
80
73
  function numericValueOutOfRange(error) {
@@ -92,12 +85,9 @@ function numericValueOutOfRange(error) {
92
85
  * - Arithmetic overflow error for data type tinyint, value = 50000.
93
86
  */
94
87
  const field = null;
95
- const parts = error.message.split(' ');
96
- const invalid = parts[parts.length - 1].slice(0, -1);
97
- return new ValueOutOfRangeException(field, {
88
+ return new ValueOutOfRangeError({
98
89
  collection,
99
90
  field,
100
- invalid,
101
91
  });
102
92
  }
103
93
  function valueLimitViolation(error) {
@@ -109,7 +99,7 @@ function valueLimitViolation(error) {
109
99
  return error;
110
100
  const collection = bracketMatches[0].slice(1, -1);
111
101
  const field = quoteMatches[1].slice(1, -1);
112
- return new ValueTooLongException(field, {
102
+ return new ValueTooLongError({
113
103
  collection,
114
104
  field,
115
105
  });
@@ -124,9 +114,9 @@ function notNullViolation(error) {
124
114
  const collection = bracketMatches[0].slice(1, -1);
125
115
  const field = quoteMatches[0].slice(1, -1);
126
116
  if (error.message.includes('Cannot insert the value NULL into column')) {
127
- return new ContainsNullValuesException(field, { collection, field });
117
+ return new ContainsNullValuesError({ collection, field });
128
118
  }
129
- return new NotNullViolationException(field, {
119
+ return new NotNullViolationError({
130
120
  collection,
131
121
  field,
132
122
  });
@@ -145,7 +135,7 @@ function foreignKeyViolation(error) {
145
135
  const underscoreParts = underscoreMatches[0].split('__');
146
136
  const collection = underscoreParts[1];
147
137
  const field = underscoreParts[2];
148
- return new InvalidForeignKeyException(field, {
138
+ return new InvalidForeignKeyError({
149
139
  collection,
150
140
  field,
151
141
  });
@@ -1,9 +1,4 @@
1
- import { ContainsNullValuesException } from '../contains-null-values.js';
2
- import { InvalidForeignKeyException } from '../invalid-foreign-key.js';
3
- import { NotNullViolationException } from '../not-null-violation.js';
4
- import { RecordNotUniqueException } from '../record-not-unique.js';
5
- import { ValueOutOfRangeException } from '../value-out-of-range.js';
6
- import { ValueTooLongException } from '../value-too-long.js';
1
+ import { ContainsNullValuesError, InvalidForeignKeyError, NotNullViolationError, RecordNotUniqueError, ValueOutOfRangeError, ValueTooLongError, } from '../../../errors/index.js';
7
2
  var MySQLErrorCodes;
8
3
  (function (MySQLErrorCodes) {
9
4
  MySQLErrorCodes["UNIQUE_VIOLATION"] = "ER_DUP_ENTRY";
@@ -51,11 +46,9 @@ function uniqueViolation(error) {
51
46
  if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) {
52
47
  field = indexName?.slice(collection.length + 1, -7);
53
48
  }
54
- const invalid = matches[0]?.slice(1, -1);
55
- return new RecordNotUniqueException(field, {
49
+ return new RecordNotUniqueError({
56
50
  collection,
57
51
  field,
58
- invalid,
59
52
  });
60
53
  }
61
54
  else {
@@ -66,11 +59,9 @@ function uniqueViolation(error) {
66
59
  if (indexName?.startsWith(`${collection}_`) && indexName.endsWith('_unique')) {
67
60
  field = indexName?.slice(collection.length + 1, -7);
68
61
  }
69
- const invalid = matches[0]?.slice(1, -1);
70
- return new RecordNotUniqueException(field, {
62
+ return new RecordNotUniqueError({
71
63
  collection,
72
64
  field,
73
- invalid,
74
65
  });
75
66
  }
76
67
  }
@@ -83,7 +74,7 @@ function numericValueOutOfRange(error) {
83
74
  return error;
84
75
  const collection = tickMatches[0]?.slice(1, -1);
85
76
  const field = quoteMatches[0]?.slice(1, -1);
86
- return new ValueOutOfRangeException(field, {
77
+ return new ValueOutOfRangeError({
87
78
  collection,
88
79
  field,
89
80
  });
@@ -97,7 +88,7 @@ function valueLimitViolation(error) {
97
88
  return error;
98
89
  const collection = tickMatches[0]?.slice(1, -1);
99
90
  const field = quoteMatches[0]?.slice(1, -1);
100
- return new ValueTooLongException(field, {
91
+ return new ValueTooLongError({
101
92
  collection,
102
93
  field,
103
94
  });
@@ -111,7 +102,7 @@ function notNullViolation(error) {
111
102
  return error;
112
103
  const collection = tickMatches[0]?.slice(1, -1);
113
104
  const field = quoteMatches[0]?.slice(1, -1);
114
- return new NotNullViolationException(field, {
105
+ return new NotNullViolationError({
115
106
  collection,
116
107
  field,
117
108
  });
@@ -125,11 +116,9 @@ function foreignKeyViolation(error) {
125
116
  return error;
126
117
  const collection = tickMatches[1].slice(1, -1);
127
118
  const field = tickMatches[3].slice(1, -1);
128
- const invalid = parenMatches[1].slice(1, -1);
129
- return new InvalidForeignKeyException(field, {
119
+ return new InvalidForeignKeyError({
130
120
  collection,
131
121
  field,
132
- invalid,
133
122
  });
134
123
  }
135
124
  function containsNullValues(error) {
@@ -139,6 +128,7 @@ function containsNullValues(error) {
139
128
  const tickMatches = error.sql.match(betweenTicks);
140
129
  if (!tickMatches)
141
130
  return error;
131
+ const collection = tickMatches[0].slice(1, -1);
142
132
  const field = tickMatches[1].slice(1, -1);
143
- return new ContainsNullValuesException(field);
133
+ return new ContainsNullValuesError({ collection, field });
144
134
  }
@@ -1,4 +1,4 @@
1
- import { ContainsNullValuesException } from '../contains-null-values.js';
1
+ import { ContainsNullValuesError } from '../../../errors/index.js';
2
2
  var OracleErrorCodes;
3
3
  (function (OracleErrorCodes) {
4
4
  OracleErrorCodes[OracleErrorCodes["CONTAINS_NULL_VALUES"] = 2296] = "CONTAINS_NULL_VALUES";
@@ -19,5 +19,5 @@ function containsNullValues(error) {
19
19
  return error;
20
20
  const collection = matches[0].slice(1, -1);
21
21
  const field = matches[1].slice(1, -1);
22
- return new ContainsNullValuesException(field, { collection, field });
22
+ return new ContainsNullValuesError({ collection, field });
23
23
  }
@@ -1,9 +1,4 @@
1
- import { ContainsNullValuesException } from '../contains-null-values.js';
2
- import { InvalidForeignKeyException } from '../invalid-foreign-key.js';
3
- import { NotNullViolationException } from '../not-null-violation.js';
4
- import { RecordNotUniqueException } from '../record-not-unique.js';
5
- import { ValueOutOfRangeException } from '../value-out-of-range.js';
6
- import { ValueTooLongException } from '../value-too-long.js';
1
+ import { ContainsNullValuesError, InvalidForeignKeyError, NotNullViolationError, RecordNotUniqueError, ValueOutOfRangeError, ValueTooLongError, } from '../../../errors/index.js';
7
2
  var PostgresErrorCodes;
8
3
  (function (PostgresErrorCodes) {
9
4
  PostgresErrorCodes["FOREIGN_KEY_VIOLATION"] = "23503";
@@ -36,11 +31,9 @@ function uniqueViolation(error) {
36
31
  return error;
37
32
  const collection = table;
38
33
  const field = matches[0].slice(1, -1);
39
- const invalid = matches[1].slice(1, -1);
40
- return new RecordNotUniqueException(field, {
34
+ return new RecordNotUniqueError({
41
35
  collection,
42
36
  field,
43
- invalid,
44
37
  });
45
38
  }
46
39
  function numericValueOutOfRange(error) {
@@ -50,11 +43,9 @@ function numericValueOutOfRange(error) {
50
43
  return error;
51
44
  const collection = matches[0].slice(1, -1);
52
45
  const field = null;
53
- const invalid = matches[2].slice(1, -1);
54
- return new ValueOutOfRangeException(field, {
46
+ return new ValueOutOfRangeError({
55
47
  collection,
56
48
  field,
57
- invalid,
58
49
  });
59
50
  }
60
51
  function valueLimitViolation(error) {
@@ -68,7 +59,7 @@ function valueLimitViolation(error) {
68
59
  return error;
69
60
  const collection = matches[0].slice(1, -1);
70
61
  const field = null;
71
- return new ValueTooLongException(field, {
62
+ return new ValueTooLongError({
72
63
  collection,
73
64
  field,
74
65
  });
@@ -78,9 +69,9 @@ function notNullViolation(error) {
78
69
  if (!column)
79
70
  return error;
80
71
  if (error.message.endsWith('contains null values')) {
81
- return new ContainsNullValuesException(column, { collection: table, field: column });
72
+ return new ContainsNullValuesError({ collection: table, field: column });
82
73
  }
83
- return new NotNullViolationException(column, {
74
+ return new NotNullViolationError({
84
75
  collection: table,
85
76
  field: column,
86
77
  });
@@ -93,10 +84,8 @@ function foreignKeyViolation(error) {
93
84
  return error;
94
85
  const collection = table;
95
86
  const field = matches[0].slice(1, -1);
96
- const invalid = matches[1].slice(1, -1);
97
- return new InvalidForeignKeyException(field, {
87
+ return new InvalidForeignKeyError({
98
88
  collection,
99
89
  field,
100
- invalid,
101
90
  });
102
91
  }
@@ -1,10 +1,7 @@
1
- import { ContainsNullValuesException } from '../contains-null-values.js';
2
- import { InvalidForeignKeyException } from '../invalid-foreign-key.js';
3
- import { NotNullViolationException } from '../not-null-violation.js';
4
- import { RecordNotUniqueException } from '../record-not-unique.js';
1
+ import { ContainsNullValuesError, InvalidForeignKeyError, NotNullViolationError, RecordNotUniqueError, } from '../../../errors/index.js';
5
2
  // NOTE:
6
- // - Sqlite doesn't have varchar with length support, so no ValueTooLongException
7
- // - Sqlite doesn't have a max range for numbers, so no ValueOutOfRangeException
3
+ // - Sqlite doesn't have varchar with length support, so no ValueTooLongError
4
+ // - Sqlite doesn't have a max range for numbers, so no ValueOutOfRangeError
8
5
  export function extractError(error) {
9
6
  if (error.message.includes('SQLITE_CONSTRAINT: NOT NULL')) {
10
7
  return notNullConstraint(error);
@@ -14,7 +11,7 @@ export function extractError(error) {
14
11
  const [table, column] = errorParts[errorParts.length - 1].split('.');
15
12
  if (!table || !column)
16
13
  return error;
17
- return new RecordNotUniqueException(column, {
14
+ return new RecordNotUniqueError({
18
15
  collection: table,
19
16
  field: column,
20
17
  });
@@ -25,7 +22,7 @@ export function extractError(error) {
25
22
  * SQLite doesn't return any useful information in it's foreign key constraint failed error, so
26
23
  * we can't extract the table/column/value accurately
27
24
  */
28
- return new InvalidForeignKeyException(null);
25
+ return new InvalidForeignKeyError({ collection: null, field: null });
29
26
  }
30
27
  return error;
31
28
  }
@@ -40,9 +37,9 @@ function notNullConstraint(error) {
40
37
  // start with _knex_temp. The best we can do in this case is check for that, and use it to
41
38
  // decide between NotNullViolation and ContainsNullValues
42
39
  if (table.startsWith('_knex_temp_alter')) {
43
- return new ContainsNullValuesException(column);
40
+ return new ContainsNullValuesError({ collection: table, field: column });
44
41
  }
45
- return new NotNullViolationException(column, {
42
+ return new NotNullViolationError({
46
43
  collection: table,
47
44
  field: column,
48
45
  });
@@ -1,4 +1,4 @@
1
- import getDatabase, { getDatabaseClient } from '../../database/index.js';
1
+ import getDatabase, { getDatabaseClient } from '../index.js';
2
2
  import emitter from '../../emitter.js';
3
3
  import { extractError as mssql } from './dialects/mssql.js';
4
4
  import { extractError as mysql } from './dialects/mysql.js';
@@ -14,7 +14,7 @@ export default async function run(database, direction, log = true) {
14
14
  const customMigrationsPath = path.resolve(env['EXTENSIONS_PATH'], 'migrations');
15
15
  let customMigrationFiles = ((await fse.pathExists(customMigrationsPath)) && (await fse.readdir(customMigrationsPath))) || [];
16
16
  migrationFiles = migrationFiles.filter((file) => /^[0-9]+[A-Z]-[^.]+\.(?:js|ts)$/.test(file));
17
- customMigrationFiles = customMigrationFiles.filter((file) => /\.(c|m)?js$/.test(file));
17
+ customMigrationFiles = customMigrationFiles.filter((file) => file.includes('-') && /\.(c|m)?js$/.test(file));
18
18
  const completedMigrations = await database.select('*').from('directus_migrations').orderBy('version');
19
19
  const migrations = [
20
20
  ...migrationFiles.map((path) => parseFilePath(path)),
@@ -56,6 +56,9 @@ export default async function run(database, direction, log = true) {
56
56
  throw Error('Nothing to upgrade');
57
57
  }
58
58
  const { up } = await import(`file://${nextVersion.file}`);
59
+ if (!up) {
60
+ logger.warn(`Couldn't find the "up" function from migration ${nextVersion.file}`);
61
+ }
59
62
  if (log) {
60
63
  logger.info(`Applying ${nextVersion.name}...`);
61
64
  }
@@ -73,6 +76,9 @@ export default async function run(database, direction, log = true) {
73
76
  throw new Error("Couldn't find migration");
74
77
  }
75
78
  const { down } = await import(`file://${migration.file}`);
79
+ if (!down) {
80
+ logger.warn(`Couldn't find the "down" function from migration ${migration.file}`);
81
+ }
76
82
  if (log) {
77
83
  logger.info(`Undoing ${migration.name}...`);
78
84
  }
@@ -86,6 +92,9 @@ export default async function run(database, direction, log = true) {
86
92
  if (migration.completed === false) {
87
93
  needsCacheFlush = true;
88
94
  const { up } = getModuleDefault(await import(`file://${migration.file}`));
95
+ if (!up) {
96
+ logger.warn(`Couldn't find the "up" function from migration ${migration.file}`);
97
+ }
89
98
  if (log) {
90
99
  logger.info(`Applying ${migration.name}...`);
91
100
  }
package/dist/emitter.d.ts CHANGED
@@ -4,8 +4,9 @@ export declare class Emitter {
4
4
  private actionEmitter;
5
5
  private initEmitter;
6
6
  constructor();
7
- emitFilter<T>(event: string | string[], payload: T, meta: Record<string, any>, context: EventContext): Promise<T>;
8
- emitAction(event: string | string[], meta: Record<string, any>, context: EventContext): void;
7
+ private getDefaultContext;
8
+ emitFilter<T>(event: string | string[], payload: T, meta: Record<string, any>, context?: EventContext | null): Promise<T>;
9
+ emitAction(event: string | string[], meta: Record<string, any>, context?: EventContext | null): void;
9
10
  emitInit(event: string, meta: Record<string, any>): Promise<void>;
10
11
  onFilter(event: string, handler: FilterHandler): void;
11
12
  onAction(event: string, handler: ActionHandler): void;
package/dist/emitter.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import ee2 from 'eventemitter2';
2
2
  import logger from './logger.js';
3
+ import getDatabase from './database/index.js';
3
4
  export class Emitter {
4
5
  filterEmitter;
5
6
  actionEmitter;
@@ -16,7 +17,14 @@ export class Emitter {
16
17
  this.actionEmitter = new ee2.EventEmitter2(emitterOptions);
17
18
  this.initEmitter = new ee2.EventEmitter2(emitterOptions);
18
19
  }
19
- async emitFilter(event, payload, meta, context) {
20
+ getDefaultContext() {
21
+ return {
22
+ database: getDatabase(),
23
+ accountability: null,
24
+ schema: null,
25
+ };
26
+ }
27
+ async emitFilter(event, payload, meta, context = null) {
20
28
  const events = Array.isArray(event) ? event : [event];
21
29
  const eventListeners = events.map((event) => ({
22
30
  event,
@@ -25,7 +33,7 @@ export class Emitter {
25
33
  let updatedPayload = payload;
26
34
  for (const { event, listeners } of eventListeners) {
27
35
  for (const listener of listeners) {
28
- const result = await listener(updatedPayload, { event, ...meta }, context);
36
+ const result = await listener(updatedPayload, { event, ...meta }, context ?? this.getDefaultContext());
29
37
  if (result !== undefined) {
30
38
  updatedPayload = result;
31
39
  }
@@ -33,10 +41,10 @@ export class Emitter {
33
41
  }
34
42
  return updatedPayload;
35
43
  }
36
- emitAction(event, meta, context) {
44
+ emitAction(event, meta, context = null) {
37
45
  const events = Array.isArray(event) ? event : [event];
38
46
  for (const event of events) {
39
- this.actionEmitter.emitAsync(event, { event, ...meta }, context).catch((err) => {
47
+ this.actionEmitter.emitAsync(event, { event, ...meta }, context ?? this.getDefaultContext()).catch((err) => {
40
48
  logger.warn(`An error was thrown while executing action "${event}"`);
41
49
  logger.warn(err);
42
50
  });
package/dist/env.js CHANGED
@@ -6,9 +6,10 @@ import { parseJSON, toArray } from '@directus/utils';
6
6
  import dotenv from 'dotenv';
7
7
  import fs from 'fs';
8
8
  import { clone, toNumber, toString } from 'lodash-es';
9
+ import { createRequire } from 'node:module';
9
10
  import path from 'path';
10
11
  import { requireYAML } from './utils/require-yaml.js';
11
- import { createRequire } from 'node:module';
12
+ import { toBoolean } from './utils/to-boolean.js';
12
13
  const require = createRequire(import.meta.url);
13
14
  // keeping this here for now to prevent a circular import to constants.ts
14
15
  const allowedEnvironmentVars = [
@@ -41,6 +42,12 @@ const allowedEnvironmentVars = [
41
42
  'REFRESH_TOKEN_COOKIE_SECURE',
42
43
  'REFRESH_TOKEN_COOKIE_SAME_SITE',
43
44
  'REFRESH_TOKEN_COOKIE_NAME',
45
+ 'REDIS',
46
+ 'REDIS_HOST',
47
+ 'REDIS_PORT',
48
+ 'REDIS_USERNAME',
49
+ 'REDIS_PASSWORD',
50
+ 'REDIS_DB',
44
51
  'LOGIN_STALL_TIME',
45
52
  'PASSWORD_RESET_URL_ALLOW_LIST',
46
53
  'USER_INVITE_URL_ALLOW_LIST',
@@ -75,11 +82,6 @@ const allowedEnvironmentVars = [
75
82
  'CACHE_NAMESPACE',
76
83
  'CACHE_STORE',
77
84
  'CACHE_STATUS_HEADER',
78
- 'CACHE_REDIS',
79
- 'CACHE_REDIS_HOST',
80
- 'CACHE_REDIS_PORT',
81
- 'CACHE_REDIS_PASSWORD',
82
- 'CACHE_MEMCACHE',
83
85
  'CACHE_VALUE_MAX_SIZE',
84
86
  'CACHE_SKIP_ALLOWED',
85
87
  'CACHE_HEALTHCHECK_THRESHOLD',
@@ -157,17 +159,9 @@ const allowedEnvironmentVars = [
157
159
  // messenger
158
160
  'MESSENGER_STORE',
159
161
  'MESSENGER_NAMESPACE',
160
- 'MESSENGER_REDIS',
161
- 'MESSENGER_REDIS_HOST',
162
- 'MESSENGER_REDIS_PORT',
163
- 'MESSENGER_REDIS_PASSWORD',
164
162
  // synchronization
165
163
  'SYNCHRONIZATION_STORE',
166
164
  'SYNCHRONIZATION_NAMESPACE',
167
- 'SYNCHRONIZATION_REDIS',
168
- 'SYNCHRONIZATION_REDIS_HOST',
169
- 'SYNCHRONIZATION_REDIS_PORT',
170
- 'SYNCHRONIZATION_REDIS_PASSWORD',
171
165
  // emails
172
166
  'EMAIL_FROM',
173
167
  'EMAIL_TRANSPORT',
@@ -200,6 +194,8 @@ const allowedEnvironmentVars = [
200
194
  // flows
201
195
  'FLOWS_EXEC_ALLOWED_MODULES',
202
196
  'FLOWS_ENV_ALLOW_LIST',
197
+ // websockets
198
+ 'WEBSOCKETS_.+',
203
199
  ].map((name) => new RegExp(`^${name}$`));
204
200
  const acceptedEnvTypes = ['string', 'number', 'regex', 'array', 'json'];
205
201
  const defaults = {
@@ -275,6 +271,17 @@ const defaults = {
275
271
  EXPORT_BATCH_SIZE: 5000,
276
272
  FILE_METADATA_ALLOW_LIST: 'ifd0.Make,ifd0.Model,exif.FNumber,exif.ExposureTime,exif.FocalLength,exif.ISO',
277
273
  GRAPHQL_INTROSPECTION: true,
274
+ WEBSOCKETS_ENABLED: false,
275
+ WEBSOCKETS_REST_ENABLED: true,
276
+ WEBSOCKETS_REST_AUTH: 'handshake',
277
+ WEBSOCKETS_REST_AUTH_TIMEOUT: 10,
278
+ WEBSOCKETS_REST_PATH: '/websocket',
279
+ WEBSOCKETS_GRAPHQL_ENABLED: true,
280
+ WEBSOCKETS_GRAPHQL_AUTH: 'handshake',
281
+ WEBSOCKETS_GRAPHQL_AUTH_TIMEOUT: 10,
282
+ WEBSOCKETS_GRAPHQL_PATH: '/graphql',
283
+ WEBSOCKETS_HEARTBEAT_ENABLED: true,
284
+ WEBSOCKETS_HEARTBEAT_PERIOD: 30,
278
285
  FLOWS_EXEC_ALLOWED_MODULES: false,
279
286
  FLOWS_ENV_ALLOW_LIST: false,
280
287
  PRESSURE_LIMITER_ENABLED: true,
@@ -484,6 +491,3 @@ function tryJSON(value) {
484
491
  return value;
485
492
  }
486
493
  }
487
- function toBoolean(value) {
488
- return value === 'true' || value === true || value === '1' || value === 1;
489
- }
@@ -0,0 +1,29 @@
1
+ export declare enum ErrorCode {
2
+ ContainsNullValues = "CONTAINS_NULL_VALUES",
3
+ ContentTooLarge = "CONTENT_TOO_LARGE",
4
+ Forbidden = "FORBIDDEN",
5
+ IllegalAssetTransformation = "ILLEGAL_ASSET_TRANSFORMATION",
6
+ InvalidCredentials = "INVALID_CREDENTIALS",
7
+ InvalidForeignKey = "INVALID_FOREIGN_KEY",
8
+ InvalidIp = "INVALID_IP",
9
+ InvalidOtp = "INVALID_OTP",
10
+ InvalidPayload = "INVALID_PAYLOAD",
11
+ InvalidProvider = "INVALID_PROVIDER",
12
+ InvalidProviderConfig = "INVALID_PROVIDER_CONFIG",
13
+ InvalidQuery = "INVALID_QUERY",
14
+ InvalidToken = "INVALID_TOKEN",
15
+ MethodNotAllowed = "METHOD_NOT_ALLOWED",
16
+ NotNullViolation = "NOT_NULL_VIOLATION",
17
+ RangeNotSatisfiable = "RANGE_NOT_SATISFIABLE",
18
+ RecordNotUnique = "RECORD_NOT_UNIQUE",
19
+ RequestsExceeded = "REQUESTS_EXCEEDED",
20
+ RouteNotFound = "ROUTE_NOT_FOUND",
21
+ ServiceUnavailable = "SERVICE_UNAVAILABLE",
22
+ TokenExpired = "TOKEN_EXPIRED",
23
+ UnexpectedResponse = "UNEXPECTED_RESPONSE",
24
+ UnprocessableContent = "UNPROCESSABLE_CONTENT",
25
+ UnsupportedMediaType = "UNSUPPORTED_MEDIA_TYPE",
26
+ UserSuspended = "USER_SUSPENDED",
27
+ ValueOutOfRange = "VALUE_OUT_OF_RANGE",
28
+ ValueTooLong = "VALUE_TOO_LONG"
29
+ }
@@ -0,0 +1,30 @@
1
+ export var ErrorCode;
2
+ (function (ErrorCode) {
3
+ ErrorCode["ContainsNullValues"] = "CONTAINS_NULL_VALUES";
4
+ ErrorCode["ContentTooLarge"] = "CONTENT_TOO_LARGE";
5
+ ErrorCode["Forbidden"] = "FORBIDDEN";
6
+ ErrorCode["IllegalAssetTransformation"] = "ILLEGAL_ASSET_TRANSFORMATION";
7
+ ErrorCode["InvalidCredentials"] = "INVALID_CREDENTIALS";
8
+ ErrorCode["InvalidForeignKey"] = "INVALID_FOREIGN_KEY";
9
+ ErrorCode["InvalidIp"] = "INVALID_IP";
10
+ ErrorCode["InvalidOtp"] = "INVALID_OTP";
11
+ ErrorCode["InvalidPayload"] = "INVALID_PAYLOAD";
12
+ ErrorCode["InvalidProvider"] = "INVALID_PROVIDER";
13
+ ErrorCode["InvalidProviderConfig"] = "INVALID_PROVIDER_CONFIG";
14
+ ErrorCode["InvalidQuery"] = "INVALID_QUERY";
15
+ ErrorCode["InvalidToken"] = "INVALID_TOKEN";
16
+ ErrorCode["MethodNotAllowed"] = "METHOD_NOT_ALLOWED";
17
+ ErrorCode["NotNullViolation"] = "NOT_NULL_VIOLATION";
18
+ ErrorCode["RangeNotSatisfiable"] = "RANGE_NOT_SATISFIABLE";
19
+ ErrorCode["RecordNotUnique"] = "RECORD_NOT_UNIQUE";
20
+ ErrorCode["RequestsExceeded"] = "REQUESTS_EXCEEDED";
21
+ ErrorCode["RouteNotFound"] = "ROUTE_NOT_FOUND";
22
+ ErrorCode["ServiceUnavailable"] = "SERVICE_UNAVAILABLE";
23
+ ErrorCode["TokenExpired"] = "TOKEN_EXPIRED";
24
+ ErrorCode["UnexpectedResponse"] = "UNEXPECTED_RESPONSE";
25
+ ErrorCode["UnprocessableContent"] = "UNPROCESSABLE_CONTENT";
26
+ ErrorCode["UnsupportedMediaType"] = "UNSUPPORTED_MEDIA_TYPE";
27
+ ErrorCode["UserSuspended"] = "USER_SUSPENDED";
28
+ ErrorCode["ValueOutOfRange"] = "VALUE_OUT_OF_RANGE";
29
+ ErrorCode["ValueTooLong"] = "VALUE_TOO_LONG";
30
+ })(ErrorCode || (ErrorCode = {}));
@@ -0,0 +1,7 @@
1
+ interface ContainsNullValuesErrorExtensions {
2
+ collection: string;
3
+ field: string;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: ContainsNullValuesErrorExtensions) => string;
6
+ export declare const ContainsNullValuesError: import("@directus/errors").DirectusErrorConstructor<ContainsNullValuesErrorExtensions>;
7
+ export {};
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => `Field "${field}" in collection "${collection}" contains null values.`;
4
+ export const ContainsNullValuesError = createError(ErrorCode.ContainsNullValues, messageConstructor, 400);