@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
@@ -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';
@@ -0,0 +1 @@
1
+ export declare const InvalidCredentialsError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidCredentialsError = createError(ErrorCode.InvalidCredentials, 'Invalid user credentials.', 401);
@@ -0,0 +1,6 @@
1
+ export interface InvalidForeignKeyErrorExtensions {
2
+ collection: string | null;
3
+ field: string | null;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: InvalidForeignKeyErrorExtensions) => string;
6
+ export declare const InvalidForeignKeyError: import("@directus/errors").DirectusErrorConstructor<InvalidForeignKeyErrorExtensions>;
@@ -0,0 +1,14 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => {
4
+ let message = 'Invalid foreign key';
5
+ if (field) {
6
+ message += ` for field "${field}"`;
7
+ }
8
+ if (collection) {
9
+ message += ` in collection "${collection}"`;
10
+ }
11
+ message += `.`;
12
+ return message;
13
+ };
14
+ export const InvalidForeignKeyError = createError(ErrorCode.InvalidForeignKey, messageConstructor, 400);
@@ -0,0 +1 @@
1
+ export declare const InvalidIpError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidIpError = createError(ErrorCode.InvalidIp, 'Invalid IP address.', 401);
@@ -0,0 +1 @@
1
+ export declare const InvalidOtpError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidOtpError = createError(ErrorCode.InvalidOtp, 'Invalid user OTP.', 401);
@@ -0,0 +1,5 @@
1
+ export interface InvalidPayloadErrorExtensions {
2
+ reason: string;
3
+ }
4
+ export declare const messageConstructor: ({ reason }: InvalidPayloadErrorExtensions) => string;
5
+ export declare const InvalidPayloadError: import("@directus/errors").DirectusErrorConstructor<InvalidPayloadErrorExtensions>;
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ reason }) => `Invalid payload. ${reason}.`;
4
+ export const InvalidPayloadError = createError(ErrorCode.InvalidPayload, messageConstructor, 400);
@@ -0,0 +1,5 @@
1
+ export interface InvalidProviderConfigErrorExtensions {
2
+ provider: string;
3
+ reason?: string;
4
+ }
5
+ export declare const InvalidProviderConfigError: import("@directus/errors").DirectusErrorConstructor<InvalidProviderConfigErrorExtensions>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidProviderConfigError = createError(ErrorCode.InvalidProviderConfig, 'Invalid config.', 503);
@@ -0,0 +1 @@
1
+ export declare const InvalidProviderError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidProviderError = createError(ErrorCode.InvalidProvider, 'Invalid provider.', 403);
@@ -0,0 +1,5 @@
1
+ export interface InvalidQueryErrorExtensions {
2
+ reason: string;
3
+ }
4
+ export declare const messageConstructor: ({ reason }: InvalidQueryErrorExtensions) => string;
5
+ export declare const InvalidQueryError: import("@directus/errors").DirectusErrorConstructor<InvalidQueryErrorExtensions>;
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ reason }) => `Invalid query. ${reason}.`;
4
+ export const InvalidQueryError = createError(ErrorCode.InvalidQuery, messageConstructor, 400);
@@ -0,0 +1 @@
1
+ export declare const InvalidTokenError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const InvalidTokenError = createError(ErrorCode.InvalidToken, 'Invalid token.', 403);
@@ -0,0 +1,6 @@
1
+ export interface MethodNotAllowedErrorExtensions {
2
+ allowed: string[];
3
+ current: string;
4
+ }
5
+ export declare const messageConstructor: (extensions: MethodNotAllowedErrorExtensions) => string;
6
+ export declare const MethodNotAllowedError: import("@directus/errors").DirectusErrorConstructor<MethodNotAllowedErrorExtensions>;
@@ -0,0 +1,6 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = (extensions) => `Invalid method "${extensions.current}" used. Should be one of ${extensions.allowed
4
+ .map((method) => `"${method}"`)
5
+ .join(', ')}.`;
6
+ export const MethodNotAllowedError = createError(ErrorCode.MethodNotAllowed, messageConstructor, 405);
@@ -0,0 +1,6 @@
1
+ export interface NotNullViolationErrorExtensions {
2
+ collection: string | null;
3
+ field: string | null;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: NotNullViolationErrorExtensions) => string;
6
+ export declare const NotNullViolationError: import("@directus/errors").DirectusErrorConstructor<NotNullViolationErrorExtensions>;
@@ -0,0 +1,14 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => {
4
+ let message = 'Value ';
5
+ if (field) {
6
+ message += `for field "${field}" `;
7
+ }
8
+ if (collection) {
9
+ message += `in collection "${collection}" `;
10
+ }
11
+ message += `can't be null.`;
12
+ return message;
13
+ };
14
+ export const NotNullViolationError = createError(ErrorCode.NotNullViolation, messageConstructor, 400);
@@ -0,0 +1,7 @@
1
+ import type { Range } from '@directus/storage';
2
+ interface RangeNotSatisfiableErrorExtensions {
3
+ range: Range;
4
+ }
5
+ export declare const messageConstructor: ({ range }: RangeNotSatisfiableErrorExtensions) => string;
6
+ export declare const RangeNotSatisfiableError: import("@directus/errors").DirectusErrorConstructor<RangeNotSatisfiableErrorExtensions>;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ range }) => {
4
+ const rangeString = `"${range.start ?? ''}-${range.end ?? ''}"`;
5
+ return `Range ${rangeString} is invalid or the file's size doesn't match the requested range.`;
6
+ };
7
+ export const RangeNotSatisfiableError = createError(ErrorCode.RangeNotSatisfiable, messageConstructor, 416);
@@ -0,0 +1,6 @@
1
+ export interface RecordNotUniqueErrorExtensions {
2
+ collection: string | null;
3
+ field: string | null;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: RecordNotUniqueErrorExtensions) => string;
6
+ export declare const RecordNotUniqueError: import("@directus/errors").DirectusErrorConstructor<RecordNotUniqueErrorExtensions>;
@@ -0,0 +1,14 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => {
4
+ let message = 'Value ';
5
+ if (field) {
6
+ message += `for field "${field}" `;
7
+ }
8
+ if (collection) {
9
+ message += `in collection "${collection}" `;
10
+ }
11
+ message += `has to be unique.`;
12
+ return message;
13
+ };
14
+ export const RecordNotUniqueError = createError(ErrorCode.RecordNotUnique, messageConstructor, 400);
@@ -0,0 +1,5 @@
1
+ export interface RouteNotFoundErrorExtensions {
2
+ path: string;
3
+ }
4
+ export declare const messageConstructor: ({ path }: RouteNotFoundErrorExtensions) => string;
5
+ export declare const RouteNotFoundError: import("@directus/errors").DirectusErrorConstructor<RouteNotFoundErrorExtensions>;
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ path }) => `Route ${path} doesn't exist.`;
4
+ export const RouteNotFoundError = createError(ErrorCode.RouteNotFound, messageConstructor, 404);
@@ -0,0 +1,7 @@
1
+ interface ServiceUnavailableErrorExtensions {
2
+ service: string;
3
+ reason: string;
4
+ }
5
+ export declare const messageConstructor: ({ service, reason }: ServiceUnavailableErrorExtensions) => string;
6
+ export declare const ServiceUnavailableError: import("@directus/errors").DirectusErrorConstructor<ServiceUnavailableErrorExtensions>;
7
+ export {};
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ service, reason }) => `Service "${service}" is unavailable. ${reason}.`;
4
+ export const ServiceUnavailableError = createError(ErrorCode.ServiceUnavailable, messageConstructor, 503);
@@ -0,0 +1 @@
1
+ export declare const TokenExpiredError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const TokenExpiredError = createError(ErrorCode.TokenExpired, 'Token expired.', 401);
@@ -0,0 +1 @@
1
+ export declare const UnexpectedResponseError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const UnexpectedResponseError = createError(ErrorCode.UnexpectedResponse, 'Received an unexpected response.', 503);
@@ -0,0 +1,5 @@
1
+ interface UnprocessableContentErrorExtensions {
2
+ reason: string;
3
+ }
4
+ export declare const UnprocessableContentError: import("@directus/errors").DirectusErrorConstructor<UnprocessableContentErrorExtensions>;
5
+ export {};
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ const messageConstructor = (extensions) => `Can't process content. ${extensions.reason}.`;
4
+ export const UnprocessableContentError = createError(ErrorCode.UnprocessableContent, messageConstructor, 422);
@@ -0,0 +1,6 @@
1
+ export interface UnsupportedMediaTypeErrorExtensions {
2
+ mediaType: string;
3
+ where: string;
4
+ }
5
+ export declare const messageConstructor: (extensions: UnsupportedMediaTypeErrorExtensions) => string;
6
+ export declare const UnsupportedMediaTypeError: import("@directus/errors").DirectusErrorConstructor<UnsupportedMediaTypeErrorExtensions>;
@@ -0,0 +1,4 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = (extensions) => `Unsupported media type "${extensions.mediaType}" in ${extensions.where}.`;
4
+ export const UnsupportedMediaTypeError = createError(ErrorCode.UnsupportedMediaType, messageConstructor, 415);
@@ -0,0 +1 @@
1
+ export declare const UserSuspendedError: import("@directus/errors").DirectusErrorConstructor<void>;
@@ -0,0 +1,3 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const UserSuspendedError = createError(ErrorCode.UserSuspended, 'User suspended.', 401);
@@ -0,0 +1,6 @@
1
+ export interface ValueOutOfRangeErrorExtensions {
2
+ collection: string | null;
3
+ field: string | null;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: ValueOutOfRangeErrorExtensions) => string;
6
+ export declare const ValueOutOfRangeError: import("@directus/errors").DirectusErrorConstructor<ValueOutOfRangeErrorExtensions>;
@@ -0,0 +1,14 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => {
4
+ let message = 'Numeric value ';
5
+ if (field) {
6
+ message += `for field "${field}" `;
7
+ }
8
+ if (collection) {
9
+ message += `in collection "${collection}" `;
10
+ }
11
+ message += `is out of range.`;
12
+ return message;
13
+ };
14
+ export const ValueOutOfRangeError = createError(ErrorCode.ValueOutOfRange, messageConstructor, 400);
@@ -0,0 +1,6 @@
1
+ export interface ValueTooLongErrorExtensions {
2
+ collection: string | null;
3
+ field: string | null;
4
+ }
5
+ export declare const messageConstructor: ({ collection, field }: ValueTooLongErrorExtensions) => string;
6
+ export declare const ValueTooLongError: import("@directus/errors").DirectusErrorConstructor<ValueTooLongErrorExtensions>;
@@ -0,0 +1,14 @@
1
+ import { createError } from '@directus/errors';
2
+ import { ErrorCode } from './codes.js';
3
+ export const messageConstructor = ({ collection, field }) => {
4
+ let message = 'Value ';
5
+ if (field) {
6
+ message += `for field "${field}" `;
7
+ }
8
+ if (collection) {
9
+ message += `in collection "${collection}" `;
10
+ }
11
+ message += `is too long.`;
12
+ return message;
13
+ };
14
+ export const ValueTooLongError = createError(ErrorCode.ValueTooLong, messageConstructor, 400);
@@ -1,5 +1,4 @@
1
1
  import { APP_EXTENSION_TYPES, APP_SHARED_DEPS, HYBRID_EXTENSION_TYPES, JAVASCRIPT_FILE_EXTS, NESTED_EXTENSION_TYPES, } from '@directus/constants';
2
- import * as sharedExceptions from '@directus/exceptions';
3
2
  import { isIn, isTypeIn, pluralize } from '@directus/utils';
4
3
  import { ensureExtensionDirs, generateExtensionsEntrypoint, getLocalExtensions, getPackageExtensions, pathToRelativeUrl, resolvePackage, resolvePackageExtensions, } from '@directus/utils/node';
5
4
  import aliasDefault from '@rollup/plugin-alias';
@@ -17,7 +16,6 @@ import { rollup } from 'rollup';
17
16
  import getDatabase from './database/index.js';
18
17
  import emitter, { Emitter } from './emitter.js';
19
18
  import env from './env.js';
20
- import * as exceptions from './exceptions/index.js';
21
19
  import { getFlowManager } from './flows.js';
22
20
  import logger from './logger.js';
23
21
  import * as services from './services/index.js';
@@ -435,7 +433,6 @@ class ExtensionManager {
435
433
  };
436
434
  register(registerFunctions, {
437
435
  services,
438
- exceptions: { ...exceptions, ...sharedExceptions },
439
436
  env,
440
437
  database: getDatabase(),
441
438
  emitter: this.apiEmitter,
@@ -450,7 +447,6 @@ class ExtensionManager {
450
447
  this.endpointRouter.use(`/${routeName}`, scopedRouter);
451
448
  register(scopedRouter, {
452
449
  services,
453
- exceptions: { ...exceptions, ...sharedExceptions },
454
450
  env,
455
451
  database: getDatabase(),
456
452
  emitter: this.apiEmitter,
package/dist/flows.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { Action, REDACTED_TEXT } from '@directus/constants';
2
- import * as sharedExceptions from '@directus/exceptions';
3
2
  import { applyOptionsData, isValidJSON, parseJSON, toArray } from '@directus/utils';
4
3
  import { omit, pick } from 'lodash-es';
5
4
  import { get } from 'micromustache';
6
5
  import getDatabase from './database/index.js';
7
6
  import emitter from './emitter.js';
8
7
  import env from './env.js';
9
- import * as exceptions from './exceptions/index.js';
8
+ import { ForbiddenError } from './errors/index.js';
10
9
  import logger from './logger.js';
11
10
  import { getMessenger } from './messenger.js';
12
11
  import { ActivityService } from './services/activity.js';
@@ -82,7 +81,7 @@ class FlowManager {
82
81
  async runWebhookFlow(id, data, context) {
83
82
  if (!(id in this.webhookFlowHandlers)) {
84
83
  logger.warn(`Couldn't find webhook or manual triggered flow with id "${id}"`);
85
- throw new exceptions.ForbiddenException();
84
+ throw new ForbiddenError();
86
85
  }
87
86
  const handler = this.webhookFlowHandlers[id];
88
87
  return handler(data, context);
@@ -186,15 +185,15 @@ class FlowManager {
186
185
  const targetCollection = data?.['body'].collection;
187
186
  if (!targetCollection) {
188
187
  logger.warn(`Manual trigger requires "collection" to be specified in the payload`);
189
- throw new exceptions.ForbiddenException();
188
+ throw new ForbiddenError();
190
189
  }
191
190
  if (enabledCollections.length === 0) {
192
191
  logger.warn(`There is no collections configured for this manual trigger`);
193
- throw new exceptions.ForbiddenException();
192
+ throw new ForbiddenError();
194
193
  }
195
194
  if (!enabledCollections.includes(targetCollection)) {
196
195
  logger.warn(`Specified collection must be one of: ${enabledCollections.join(', ')}.`);
197
- throw new exceptions.ForbiddenException();
196
+ throw new ForbiddenError();
198
197
  }
199
198
  if (flow.options['async']) {
200
199
  this.executeFlow(flow, data, context);
@@ -310,7 +309,6 @@ class FlowManager {
310
309
  try {
311
310
  let result = await handler(options, {
312
311
  services,
313
- exceptions: { ...exceptions, ...sharedExceptions },
314
312
  env,
315
313
  database: getDatabase(),
316
314
  logger,
@@ -331,7 +329,7 @@ class FlowManager {
331
329
  catch (error) {
332
330
  let data;
333
331
  if (error instanceof Error) {
334
- // make sure we dont expose the stack trace
332
+ // make sure we don't expose the stack trace
335
333
  data = sanitizeError(error);
336
334
  }
337
335
  else if (typeof error === 'string') {
package/dist/index.d.ts CHANGED
@@ -1,3 +1 @@
1
1
  export { default as createApp } from './app.js';
2
- export * from './services/index.js';
3
- export * from './exceptions/index.js';
package/dist/index.js CHANGED
@@ -1,3 +1 @@
1
1
  export { default as createApp } from './app.js';
2
- export * from './services/index.js';
3
- export * from './exceptions/index.js';
package/dist/messenger.js CHANGED
@@ -29,11 +29,11 @@ export class MessengerRedis {
29
29
  pub;
30
30
  sub;
31
31
  constructor() {
32
- const config = getConfigFromEnv('MESSENGER_REDIS');
32
+ const config = getConfigFromEnv('REDIS');
33
33
  const env = getEnv();
34
- this.pub = new Redis(env['MESSENGER_REDIS'] ?? config);
35
- this.sub = new Redis(env['MESSENGER_REDIS'] ?? config);
36
- this.namespace = env['MESSENGER_NAMESPACE'] ?? 'directus';
34
+ this.pub = new Redis(env['REDIS'] ?? config);
35
+ this.sub = new Redis(env['REDIS'] ?? config);
36
+ this.namespace = env['MESSENGER_NAMESPACE'] ?? 'directus-messenger';
37
37
  }
38
38
  publish(channel, payload) {
39
39
  this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
@@ -2,8 +2,8 @@ import { isEqual } from 'lodash-es';
2
2
  import getDatabase from '../database/index.js';
3
3
  import emitter from '../emitter.js';
4
4
  import asyncHandler from '../utils/async-handler.js';
5
- import { getIPFromReq } from '../utils/get-ip-from-req.js';
6
5
  import { getAccountabilityForToken } from '../utils/get-accountability-for-token.js';
6
+ import { getIPFromReq } from '../utils/get-ip-from-req.js';
7
7
  /**
8
8
  * Verify the passed JWT and assign the user ID and role to `req`
9
9
  */
@@ -1,5 +1,5 @@
1
1
  import getDatabase from '../database/index.js';
2
- import { InvalidIPException } from '../exceptions/index.js';
2
+ import { InvalidIpError } from '../errors/index.js';
3
3
  import asyncHandler from '../utils/async-handler.js';
4
4
  export const checkIP = asyncHandler(async (req, _res, next) => {
5
5
  const database = getDatabase();
@@ -13,6 +13,6 @@ export const checkIP = asyncHandler(async (req, _res, next) => {
13
13
  const role = await query.first();
14
14
  const ipAllowlist = (role?.ip_access || '').split(',').filter((ip) => ip);
15
15
  if (ipAllowlist.length > 0 && ipAllowlist.includes(req.accountability.ip) === false)
16
- throw new InvalidIPException();
16
+ throw new InvalidIpError();
17
17
  return next();
18
18
  });
@@ -2,13 +2,13 @@
2
2
  * Check if requested collection exists, and save it to req.collection
3
3
  */
4
4
  import { systemCollectionRows } from '../database/system-data/collections/index.js';
5
- import { ForbiddenException } from '../exceptions/index.js';
5
+ import { ForbiddenError } from '../errors/index.js';
6
6
  import asyncHandler from '../utils/async-handler.js';
7
7
  const collectionExists = asyncHandler(async (req, _res, next) => {
8
8
  if (!req.params['collection'])
9
9
  return next();
10
10
  if (req.params['collection'] in req.schema.collections === false) {
11
- throw new ForbiddenException();
11
+ throw new ForbiddenError();
12
12
  }
13
13
  req.collection = req.params['collection'];
14
14
  if (req.collection.startsWith('directus_')) {
@@ -1,9 +1,9 @@
1
- import { BaseException } from '@directus/exceptions';
1
+ import { isDirectusError } from '@directus/errors';
2
2
  import { toArray } from '@directus/utils';
3
3
  import getDatabase from '../database/index.js';
4
4
  import emitter from '../emitter.js';
5
5
  import env from '../env.js';
6
- import { MethodNotAllowedException } from '../exceptions/index.js';
6
+ import { ErrorCode, MethodNotAllowedError } from '../errors/index.js';
7
7
  import logger from '../logger.js';
8
8
  // Note: keep all 4 parameters here. That's how Express recognizes it's the error handler, even if
9
9
  // we don't use next
@@ -12,7 +12,7 @@ const errorHandler = (err, req, res, _next) => {
12
12
  errors: [],
13
13
  };
14
14
  const errors = toArray(err);
15
- if (errors.some((err) => err instanceof BaseException === false)) {
15
+ if (errors.some((err) => isDirectusError(err) === false)) {
16
16
  res.status(500);
17
17
  }
18
18
  else {
@@ -33,18 +33,18 @@ const errorHandler = (err, req, res, _next) => {
33
33
  stack: err.stack,
34
34
  };
35
35
  }
36
- if (err instanceof BaseException) {
36
+ if (isDirectusError(err)) {
37
37
  logger.debug(err);
38
38
  res.status(err.status);
39
39
  payload.errors.push({
40
40
  message: err.message,
41
41
  extensions: {
42
42
  code: err.code,
43
- ...err.extensions,
43
+ ...(err.extensions ?? {}),
44
44
  },
45
45
  });
46
- if (err instanceof MethodNotAllowedException) {
47
- res.header('Allow', err.extensions['allow'].join(', '));
46
+ if (isDirectusError(err, ErrorCode.MethodNotAllowed)) {
47
+ res.header('Allow', err.extensions.allowed.join(', '));
48
48
  }
49
49
  }
50
50
  else {
@@ -1,10 +1,11 @@
1
1
  import { parseJSON } from '@directus/utils';
2
2
  import { getOperationAST, parse, Source } from 'graphql';
3
- import { InvalidPayloadException, InvalidQueryException, MethodNotAllowedException } from '../exceptions/index.js';
3
+ import { InvalidPayloadError, InvalidQueryError, MethodNotAllowedError } from '../errors/index.js';
4
+ import { GraphQLValidationError } from '../services/graphql/errors/validation.js';
4
5
  import asyncHandler from '../utils/async-handler.js';
5
6
  export const parseGraphQL = asyncHandler(async (req, res, next) => {
6
7
  if (req.method !== 'GET' && req.method !== 'POST') {
7
- throw new MethodNotAllowedException('GraphQL only supports GET and POST requests.', { allow: ['GET', 'POST'] });
8
+ throw new MethodNotAllowedError({ allowed: ['GET', 'POST'], current: req.method });
8
9
  }
9
10
  let query = null;
10
11
  let variables = null;
@@ -17,7 +18,7 @@ export const parseGraphQL = asyncHandler(async (req, res, next) => {
17
18
  variables = parseJSON(req.query['variables']);
18
19
  }
19
20
  catch {
20
- throw new InvalidQueryException(`Variables are invalid JSON.`);
21
+ throw new InvalidQueryError({ reason: `Variables are invalid JSON` });
21
22
  }
22
23
  }
23
24
  else {
@@ -31,21 +32,22 @@ export const parseGraphQL = asyncHandler(async (req, res, next) => {
31
32
  operationName = req.body.operationName || null;
32
33
  }
33
34
  if (query === null) {
34
- throw new InvalidPayloadException('Must provide query string.');
35
+ throw new InvalidPayloadError({ reason: 'Must provide query string' });
35
36
  }
36
37
  try {
37
38
  document = parse(new Source(query));
38
39
  }
39
40
  catch (err) {
40
- throw new InvalidPayloadException(`GraphQL schema validation error.`, {
41
- graphqlErrors: [err],
41
+ throw new GraphQLValidationError({
42
+ errors: [err],
42
43
  });
43
44
  }
44
45
  const operationAST = getOperationAST(document, operationName);
45
- // You can only do `query` through GET
46
+ // Mutations can't happen through GET requests
46
47
  if (req.method === 'GET' && operationAST?.operation !== 'query') {
47
- throw new MethodNotAllowedException(`Can only perform a ${operationAST?.operation} from a POST request.`, {
48
- allow: ['POST'],
48
+ throw new MethodNotAllowedError({
49
+ allowed: ['POST'],
50
+ current: 'GET',
49
51
  });
50
52
  }
51
53
  // Prevent caching responses when mutations are made
@@ -1,5 +1,5 @@
1
1
  import type { RequestHandler } from 'express';
2
- import type { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
2
+ import type { RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
3
3
  declare let checkRateLimit: RequestHandler;
4
- export declare let rateLimiterGlobal: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
4
+ export declare let rateLimiterGlobal: RateLimiterRedis | RateLimiterMemory;
5
5
  export default checkRateLimit;