@directus/api 11.1.0 → 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 (246) 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/env.js +6 -13
  47. package/dist/errors/codes.d.ts +29 -0
  48. package/dist/errors/codes.js +30 -0
  49. package/dist/errors/contains-null-values.d.ts +7 -0
  50. package/dist/errors/contains-null-values.js +4 -0
  51. package/dist/errors/content-too-large.d.ts +1 -0
  52. package/dist/errors/content-too-large.js +3 -0
  53. package/dist/errors/forbidden.d.ts +1 -0
  54. package/dist/errors/forbidden.js +3 -0
  55. package/dist/errors/hit-rate-limit.d.ts +6 -0
  56. package/dist/errors/hit-rate-limit.js +8 -0
  57. package/dist/errors/illegal-asset-transformation.d.ts +4 -0
  58. package/dist/errors/illegal-asset-transformation.js +3 -0
  59. package/dist/errors/index.d.ts +28 -0
  60. package/dist/errors/index.js +28 -0
  61. package/dist/errors/invalid-credentials.d.ts +1 -0
  62. package/dist/errors/invalid-credentials.js +3 -0
  63. package/dist/errors/invalid-foreign-key.d.ts +6 -0
  64. package/dist/errors/invalid-foreign-key.js +14 -0
  65. package/dist/errors/invalid-ip.d.ts +1 -0
  66. package/dist/errors/invalid-ip.js +3 -0
  67. package/dist/errors/invalid-otp.d.ts +1 -0
  68. package/dist/errors/invalid-otp.js +3 -0
  69. package/dist/errors/invalid-payload.d.ts +5 -0
  70. package/dist/errors/invalid-payload.js +4 -0
  71. package/dist/errors/invalid-provider-config.d.ts +5 -0
  72. package/dist/errors/invalid-provider-config.js +3 -0
  73. package/dist/errors/invalid-provider.d.ts +1 -0
  74. package/dist/errors/invalid-provider.js +3 -0
  75. package/dist/errors/invalid-query.d.ts +5 -0
  76. package/dist/errors/invalid-query.js +4 -0
  77. package/dist/errors/invalid-token.d.ts +1 -0
  78. package/dist/errors/invalid-token.js +3 -0
  79. package/dist/errors/method-not-allowed.d.ts +6 -0
  80. package/dist/errors/method-not-allowed.js +6 -0
  81. package/dist/errors/not-null-violation.d.ts +6 -0
  82. package/dist/errors/not-null-violation.js +14 -0
  83. package/dist/errors/range-not-satisfiable.d.ts +7 -0
  84. package/dist/errors/range-not-satisfiable.js +7 -0
  85. package/dist/errors/record-not-unique.d.ts +6 -0
  86. package/dist/errors/record-not-unique.js +14 -0
  87. package/dist/errors/route-not-found.d.ts +5 -0
  88. package/dist/errors/route-not-found.js +4 -0
  89. package/dist/errors/service-unavailable.d.ts +7 -0
  90. package/dist/errors/service-unavailable.js +4 -0
  91. package/dist/errors/token-expired.d.ts +1 -0
  92. package/dist/errors/token-expired.js +3 -0
  93. package/dist/errors/unexpected-response.d.ts +1 -0
  94. package/dist/errors/unexpected-response.js +3 -0
  95. package/dist/errors/unprocessable-content.d.ts +5 -0
  96. package/dist/errors/unprocessable-content.js +4 -0
  97. package/dist/errors/unsupported-media-type.d.ts +6 -0
  98. package/dist/errors/unsupported-media-type.js +4 -0
  99. package/dist/errors/user-suspended.d.ts +1 -0
  100. package/dist/errors/user-suspended.js +3 -0
  101. package/dist/errors/value-out-of-range.d.ts +6 -0
  102. package/dist/errors/value-out-of-range.js +14 -0
  103. package/dist/errors/value-too-long.d.ts +6 -0
  104. package/dist/errors/value-too-long.js +14 -0
  105. package/dist/extensions.js +0 -4
  106. package/dist/flows.js +6 -8
  107. package/dist/index.d.ts +0 -2
  108. package/dist/index.js +0 -2
  109. package/dist/messenger.js +4 -4
  110. package/dist/middleware/authenticate.js +1 -1
  111. package/dist/middleware/check-ip.js +2 -2
  112. package/dist/middleware/collection-exists.js +2 -2
  113. package/dist/middleware/error-handler.js +7 -7
  114. package/dist/middleware/graphql.js +11 -9
  115. package/dist/middleware/rate-limiter-global.d.ts +2 -2
  116. package/dist/middleware/rate-limiter-global.js +2 -3
  117. package/dist/middleware/rate-limiter-ip.d.ts +2 -2
  118. package/dist/middleware/rate-limiter-ip.js +2 -3
  119. package/dist/middleware/validate-batch.js +3 -4
  120. package/dist/rate-limiter.js +2 -9
  121. package/dist/services/activity.js +3 -2
  122. package/dist/services/assets.js +9 -10
  123. package/dist/services/authentication.js +12 -11
  124. package/dist/services/authorization.d.ts +1 -1
  125. package/dist/services/authorization.js +16 -16
  126. package/dist/services/collections.js +17 -16
  127. package/dist/services/fields.js +16 -14
  128. package/dist/services/files.js +7 -6
  129. package/dist/services/graphql/errors/execution.d.ts +6 -0
  130. package/dist/services/graphql/errors/execution.js +2 -0
  131. package/dist/services/graphql/errors/index.d.ts +2 -0
  132. package/dist/services/graphql/errors/index.js +2 -0
  133. package/dist/services/graphql/errors/validation.d.ts +6 -0
  134. package/dist/services/graphql/errors/validation.js +2 -0
  135. package/dist/services/graphql/index.d.ts +2 -2
  136. package/dist/services/graphql/index.js +30 -12
  137. package/dist/services/graphql/utils/process-error.js +3 -3
  138. package/dist/services/import-export.js +7 -7
  139. package/dist/services/index.d.ts +1 -0
  140. package/dist/services/index.js +1 -0
  141. package/dist/services/items.js +14 -13
  142. package/dist/services/mail/index.js +3 -3
  143. package/dist/services/meta.js +3 -3
  144. package/dist/services/payload.js +11 -7
  145. package/dist/services/relations.js +32 -22
  146. package/dist/services/revisions.js +3 -3
  147. package/dist/services/roles.js +10 -9
  148. package/dist/services/schema.js +5 -5
  149. package/dist/services/shares.js +4 -4
  150. package/dist/services/tfa.js +6 -6
  151. package/dist/services/translations.d.ts +2 -2
  152. package/dist/services/translations.js +4 -4
  153. package/dist/services/users.js +26 -29
  154. package/dist/services/utils.js +4 -4
  155. package/dist/synchronization.js +3 -3
  156. package/dist/types/items.d.ts +2 -2
  157. package/dist/utils/apply-diff.js +2 -2
  158. package/dist/utils/apply-query.js +17 -7
  159. package/dist/utils/get-accountability-for-role.js +1 -2
  160. package/dist/utils/get-accountability-for-token.js +3 -3
  161. package/dist/utils/get-column-path.js +5 -3
  162. package/dist/utils/get-column.js +3 -3
  163. package/dist/utils/get-service.d.ts +1 -1
  164. package/dist/utils/get-service.js +1 -1
  165. package/dist/utils/jwt.js +5 -5
  166. package/dist/utils/validate-diff.js +23 -9
  167. package/dist/utils/validate-keys.js +3 -3
  168. package/dist/utils/validate-query.d.ts +2 -0
  169. package/dist/utils/validate-query.js +27 -21
  170. package/dist/utils/validate-snapshot.js +11 -5
  171. package/dist/websocket/authenticate.js +12 -15
  172. package/dist/websocket/controllers/base.js +18 -15
  173. package/dist/websocket/controllers/graphql.js +2 -2
  174. package/dist/websocket/controllers/index.js +3 -7
  175. package/dist/websocket/controllers/rest.js +3 -3
  176. package/dist/websocket/{exceptions.d.ts → errors.d.ts} +5 -5
  177. package/dist/websocket/{exceptions.js → errors.js} +10 -10
  178. package/dist/websocket/handlers/items.js +5 -5
  179. package/dist/websocket/handlers/subscribe.js +8 -8
  180. package/package.json +15 -15
  181. package/dist/exceptions/content-too-large.d.ts +0 -4
  182. package/dist/exceptions/content-too-large.js +0 -6
  183. package/dist/exceptions/database/contains-null-values.d.ts +0 -9
  184. package/dist/exceptions/database/contains-null-values.js +0 -6
  185. package/dist/exceptions/database/invalid-foreign-key.d.ts +0 -10
  186. package/dist/exceptions/database/invalid-foreign-key.js +0 -11
  187. package/dist/exceptions/database/not-null-violation.d.ts +0 -9
  188. package/dist/exceptions/database/not-null-violation.js +0 -6
  189. package/dist/exceptions/database/record-not-unique.d.ts +0 -10
  190. package/dist/exceptions/database/record-not-unique.js +0 -11
  191. package/dist/exceptions/database/value-out-of-range.d.ts +0 -10
  192. package/dist/exceptions/database/value-out-of-range.js +0 -11
  193. package/dist/exceptions/database/value-too-long.d.ts +0 -9
  194. package/dist/exceptions/database/value-too-long.js +0 -11
  195. package/dist/exceptions/forbidden.d.ts +0 -6
  196. package/dist/exceptions/forbidden.js +0 -13
  197. package/dist/exceptions/graphql-validation.d.ts +0 -4
  198. package/dist/exceptions/graphql-validation.js +0 -6
  199. package/dist/exceptions/hit-rate-limit.d.ts +0 -9
  200. package/dist/exceptions/hit-rate-limit.js +0 -6
  201. package/dist/exceptions/illegal-asset-transformation.d.ts +0 -4
  202. package/dist/exceptions/illegal-asset-transformation.js +0 -6
  203. package/dist/exceptions/index.d.ts +0 -21
  204. package/dist/exceptions/index.js +0 -21
  205. package/dist/exceptions/invalid-config.d.ts +0 -4
  206. package/dist/exceptions/invalid-config.js +0 -6
  207. package/dist/exceptions/invalid-credentials.d.ts +0 -4
  208. package/dist/exceptions/invalid-credentials.js +0 -6
  209. package/dist/exceptions/invalid-ip.d.ts +0 -4
  210. package/dist/exceptions/invalid-ip.js +0 -6
  211. package/dist/exceptions/invalid-otp.d.ts +0 -4
  212. package/dist/exceptions/invalid-otp.js +0 -6
  213. package/dist/exceptions/invalid-payload.d.ts +0 -4
  214. package/dist/exceptions/invalid-payload.js +0 -6
  215. package/dist/exceptions/invalid-provider.d.ts +0 -4
  216. package/dist/exceptions/invalid-provider.js +0 -6
  217. package/dist/exceptions/invalid-query.d.ts +0 -4
  218. package/dist/exceptions/invalid-query.js +0 -6
  219. package/dist/exceptions/invalid-token.d.ts +0 -4
  220. package/dist/exceptions/invalid-token.js +0 -6
  221. package/dist/exceptions/method-not-allowed.d.ts +0 -8
  222. package/dist/exceptions/method-not-allowed.js +0 -6
  223. package/dist/exceptions/range-not-satisfiable.d.ts +0 -5
  224. package/dist/exceptions/range-not-satisfiable.js +0 -9
  225. package/dist/exceptions/route-not-found.d.ts +0 -4
  226. package/dist/exceptions/route-not-found.js +0 -6
  227. package/dist/exceptions/service-unavailable.d.ts +0 -9
  228. package/dist/exceptions/service-unavailable.js +0 -6
  229. package/dist/exceptions/token-expired.d.ts +0 -4
  230. package/dist/exceptions/token-expired.js +0 -6
  231. package/dist/exceptions/unexpected-response.d.ts +0 -4
  232. package/dist/exceptions/unexpected-response.js +0 -6
  233. package/dist/exceptions/unprocessable-entity.d.ts +0 -4
  234. package/dist/exceptions/unprocessable-entity.js +0 -6
  235. package/dist/exceptions/unsupported-media-type.d.ts +0 -4
  236. package/dist/exceptions/unsupported-media-type.js +0 -6
  237. package/dist/exceptions/user-suspended.d.ts +0 -4
  238. package/dist/exceptions/user-suspended.js +0 -6
  239. /package/dist/{exceptions/database → database/errors}/dialects/mssql.d.ts +0 -0
  240. /package/dist/{exceptions/database → database/errors}/dialects/mysql.d.ts +0 -0
  241. /package/dist/{exceptions/database → database/errors}/dialects/oracle.d.ts +0 -0
  242. /package/dist/{exceptions/database → database/errors}/dialects/postgres.d.ts +0 -0
  243. /package/dist/{exceptions/database → database/errors}/dialects/sqlite.d.ts +0 -0
  244. /package/dist/{exceptions/database → database/errors}/dialects/types.d.ts +0 -0
  245. /package/dist/{exceptions/database → database/errors}/dialects/types.js +0 -0
  246. /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/env.js CHANGED
@@ -42,6 +42,12 @@ const allowedEnvironmentVars = [
42
42
  'REFRESH_TOKEN_COOKIE_SECURE',
43
43
  'REFRESH_TOKEN_COOKIE_SAME_SITE',
44
44
  'REFRESH_TOKEN_COOKIE_NAME',
45
+ 'REDIS',
46
+ 'REDIS_HOST',
47
+ 'REDIS_PORT',
48
+ 'REDIS_USERNAME',
49
+ 'REDIS_PASSWORD',
50
+ 'REDIS_DB',
45
51
  'LOGIN_STALL_TIME',
46
52
  'PASSWORD_RESET_URL_ALLOW_LIST',
47
53
  'USER_INVITE_URL_ALLOW_LIST',
@@ -76,11 +82,6 @@ const allowedEnvironmentVars = [
76
82
  'CACHE_NAMESPACE',
77
83
  'CACHE_STORE',
78
84
  'CACHE_STATUS_HEADER',
79
- 'CACHE_REDIS',
80
- 'CACHE_REDIS_HOST',
81
- 'CACHE_REDIS_PORT',
82
- 'CACHE_REDIS_PASSWORD',
83
- 'CACHE_MEMCACHE',
84
85
  'CACHE_VALUE_MAX_SIZE',
85
86
  'CACHE_SKIP_ALLOWED',
86
87
  'CACHE_HEALTHCHECK_THRESHOLD',
@@ -158,17 +159,9 @@ const allowedEnvironmentVars = [
158
159
  // messenger
159
160
  'MESSENGER_STORE',
160
161
  'MESSENGER_NAMESPACE',
161
- 'MESSENGER_REDIS',
162
- 'MESSENGER_REDIS_HOST',
163
- 'MESSENGER_REDIS_PORT',
164
- 'MESSENGER_REDIS_PASSWORD',
165
162
  // synchronization
166
163
  'SYNCHRONIZATION_STORE',
167
164
  'SYNCHRONIZATION_NAMESPACE',
168
- 'SYNCHRONIZATION_REDIS',
169
- 'SYNCHRONIZATION_REDIS_HOST',
170
- 'SYNCHRONIZATION_REDIS_PORT',
171
- 'SYNCHRONIZATION_REDIS_PASSWORD',
172
165
  // emails
173
166
  'EMAIL_FROM',
174
167
  'EMAIL_TRANSPORT',
@@ -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);
@@ -0,0 +1 @@
1
+ export declare const ContentTooLargeError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const ContentTooLargeError = createError(ErrorCode.ContentTooLarge, 'Uploaded content is too large.', 413);
@@ -0,0 +1 @@
1
+ export declare const ForbiddenError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const ForbiddenError = createError(ErrorCode.Forbidden, `You don't have permission to access this.`, 403);
@@ -0,0 +1,6 @@
1
+ export interface HitRateLimitErrorExtensions {
2
+ limit: number;
3
+ reset: Date;
4
+ }
5
+ export declare const messageConstructor: (extensions: HitRateLimitErrorExtensions) => string;
6
+ export declare const HitRateLimitError: import("@directus/errors").DirectusErrorConstructor<HitRateLimitErrorExtensions>;
@@ -0,0 +1,8 @@
1
+ import { createError } from '@directus/errors';
2
+ import ms from 'ms';
3
+ import { ErrorCode } from './codes.js';
4
+ export const messageConstructor = (extensions) => {
5
+ const msBeforeNext = extensions.reset.getTime() - Date.now();
6
+ return `Too many requests, retry after ${ms(msBeforeNext)}.`;
7
+ };
8
+ export const HitRateLimitError = createError(ErrorCode.RequestsExceeded, messageConstructor, 429);
@@ -0,0 +1,4 @@
1
+ export interface IllegalAssetTransformationErrorExtensions {
2
+ invalidTransformations: string[];
3
+ }
4
+ export declare const IllegalAssetTransformationError: import("@directus/errors").DirectusErrorConstructor<IllegalAssetTransformationErrorExtensions>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const IllegalAssetTransformationError = createError(ErrorCode.IllegalAssetTransformation, 'Illegal asset transformation.', 400);
@@ -0,0 +1,28 @@
1
+ export { ErrorCode } from './codes.js';
2
+ export { ContainsNullValuesError } from './contains-null-values.js';
3
+ export { ContentTooLargeError } from './content-too-large.js';
4
+ export { ForbiddenError } from './forbidden.js';
5
+ export { HitRateLimitError } from './hit-rate-limit.js';
6
+ export { IllegalAssetTransformationError } from './illegal-asset-transformation.js';
7
+ export { InvalidCredentialsError } from './invalid-credentials.js';
8
+ export { InvalidForeignKeyError } from './invalid-foreign-key.js';
9
+ export { InvalidIpError } from './invalid-ip.js';
10
+ export { InvalidOtpError } from './invalid-otp.js';
11
+ export { InvalidPayloadError } from './invalid-payload.js';
12
+ export { InvalidProviderError } from './invalid-provider.js';
13
+ export { InvalidProviderConfigError } from './invalid-provider-config.js';
14
+ export { InvalidQueryError } from './invalid-query.js';
15
+ export { InvalidTokenError } from './invalid-token.js';
16
+ export { MethodNotAllowedError } from './method-not-allowed.js';
17
+ export { NotNullViolationError } from './not-null-violation.js';
18
+ export { RangeNotSatisfiableError } from './range-not-satisfiable.js';
19
+ export { RecordNotUniqueError } from './record-not-unique.js';
20
+ export { RouteNotFoundError } from './route-not-found.js';
21
+ export { ServiceUnavailableError } from './service-unavailable.js';
22
+ export { TokenExpiredError } from './token-expired.js';
23
+ export { UnexpectedResponseError } from './unexpected-response.js';
24
+ export { UnprocessableContentError } from './unprocessable-content.js';
25
+ export { UnsupportedMediaTypeError } from './unsupported-media-type.js';
26
+ export { UserSuspendedError } from './user-suspended.js';
27
+ export { ValueOutOfRangeError } from './value-out-of-range.js';
28
+ export { ValueTooLongError } from './value-too-long.js';