@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.
- package/dist/app.js +3 -4
- package/dist/auth/auth.d.ts +4 -4
- package/dist/auth/auth.js +2 -2
- package/dist/auth/drivers/ldap.js +20 -17
- package/dist/auth/drivers/local.js +5 -5
- package/dist/auth/drivers/oauth2.js +16 -16
- package/dist/auth/drivers/openid.js +18 -17
- package/dist/auth/drivers/saml.js +6 -7
- package/dist/auth.js +3 -2
- package/dist/cache.js +3 -13
- package/dist/cli/utils/create-env/env-stub.liquid +5 -7
- package/dist/controllers/activity.js +7 -6
- package/dist/controllers/assets.js +25 -12
- package/dist/controllers/auth.js +8 -7
- package/dist/controllers/collections.js +4 -3
- package/dist/controllers/dashboards.js +5 -4
- package/dist/controllers/extensions.js +3 -3
- package/dist/controllers/fields.js +9 -8
- package/dist/controllers/files.js +11 -11
- package/dist/controllers/flows.js +5 -4
- package/dist/controllers/folders.js +5 -4
- package/dist/controllers/items.js +14 -13
- package/dist/controllers/not-found.js +2 -2
- package/dist/controllers/notifications.js +5 -4
- package/dist/controllers/operations.js +5 -4
- package/dist/controllers/panels.js +5 -4
- package/dist/controllers/permissions.js +5 -4
- package/dist/controllers/presets.js +5 -4
- package/dist/controllers/relations.js +6 -5
- package/dist/controllers/roles.js +5 -4
- package/dist/controllers/schema.js +8 -8
- package/dist/controllers/server.js +2 -2
- package/dist/controllers/settings.js +3 -2
- package/dist/controllers/shares.js +7 -6
- package/dist/controllers/translations.js +6 -5
- package/dist/controllers/users.js +22 -21
- package/dist/controllers/utils.js +10 -10
- package/dist/controllers/webhooks.js +5 -4
- package/dist/{exceptions/database → database/errors}/dialects/mssql.js +8 -18
- package/dist/{exceptions/database → database/errors}/dialects/mysql.js +9 -19
- package/dist/{exceptions/database → database/errors}/dialects/oracle.js +2 -2
- package/dist/{exceptions/database → database/errors}/dialects/postgres.js +7 -18
- package/dist/{exceptions/database → database/errors}/dialects/sqlite.js +7 -10
- package/dist/{exceptions/database → database/errors}/translate.js +1 -1
- package/dist/database/migrations/run.js +10 -1
- package/dist/emitter.d.ts +3 -2
- package/dist/emitter.js +12 -4
- package/dist/env.js +21 -17
- package/dist/errors/codes.d.ts +29 -0
- package/dist/errors/codes.js +30 -0
- package/dist/errors/contains-null-values.d.ts +7 -0
- package/dist/errors/contains-null-values.js +4 -0
- package/dist/errors/content-too-large.d.ts +1 -0
- package/dist/errors/content-too-large.js +3 -0
- package/dist/errors/forbidden.d.ts +1 -0
- package/dist/errors/forbidden.js +3 -0
- package/dist/errors/hit-rate-limit.d.ts +6 -0
- package/dist/errors/hit-rate-limit.js +8 -0
- package/dist/errors/illegal-asset-transformation.d.ts +4 -0
- package/dist/errors/illegal-asset-transformation.js +3 -0
- package/dist/errors/index.d.ts +28 -0
- package/dist/errors/index.js +28 -0
- package/dist/errors/invalid-credentials.d.ts +1 -0
- package/dist/errors/invalid-credentials.js +3 -0
- package/dist/errors/invalid-foreign-key.d.ts +6 -0
- package/dist/errors/invalid-foreign-key.js +14 -0
- package/dist/errors/invalid-ip.d.ts +1 -0
- package/dist/errors/invalid-ip.js +3 -0
- package/dist/errors/invalid-otp.d.ts +1 -0
- package/dist/errors/invalid-otp.js +3 -0
- package/dist/errors/invalid-payload.d.ts +5 -0
- package/dist/errors/invalid-payload.js +4 -0
- package/dist/errors/invalid-provider-config.d.ts +5 -0
- package/dist/errors/invalid-provider-config.js +3 -0
- package/dist/errors/invalid-provider.d.ts +1 -0
- package/dist/errors/invalid-provider.js +3 -0
- package/dist/errors/invalid-query.d.ts +5 -0
- package/dist/errors/invalid-query.js +4 -0
- package/dist/errors/invalid-token.d.ts +1 -0
- package/dist/errors/invalid-token.js +3 -0
- package/dist/errors/method-not-allowed.d.ts +6 -0
- package/dist/errors/method-not-allowed.js +6 -0
- package/dist/errors/not-null-violation.d.ts +6 -0
- package/dist/errors/not-null-violation.js +14 -0
- package/dist/errors/range-not-satisfiable.d.ts +7 -0
- package/dist/errors/range-not-satisfiable.js +7 -0
- package/dist/errors/record-not-unique.d.ts +6 -0
- package/dist/errors/record-not-unique.js +14 -0
- package/dist/errors/route-not-found.d.ts +5 -0
- package/dist/errors/route-not-found.js +4 -0
- package/dist/errors/service-unavailable.d.ts +7 -0
- package/dist/errors/service-unavailable.js +4 -0
- package/dist/errors/token-expired.d.ts +1 -0
- package/dist/errors/token-expired.js +3 -0
- package/dist/errors/unexpected-response.d.ts +1 -0
- package/dist/errors/unexpected-response.js +3 -0
- package/dist/errors/unprocessable-content.d.ts +5 -0
- package/dist/errors/unprocessable-content.js +4 -0
- package/dist/errors/unsupported-media-type.d.ts +6 -0
- package/dist/errors/unsupported-media-type.js +4 -0
- package/dist/errors/user-suspended.d.ts +1 -0
- package/dist/errors/user-suspended.js +3 -0
- package/dist/errors/value-out-of-range.d.ts +6 -0
- package/dist/errors/value-out-of-range.js +14 -0
- package/dist/errors/value-too-long.d.ts +6 -0
- package/dist/errors/value-too-long.js +14 -0
- package/dist/extensions.js +0 -4
- package/dist/flows.js +6 -8
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/messenger.d.ts +3 -3
- package/dist/messenger.js +18 -9
- package/dist/middleware/authenticate.js +2 -38
- package/dist/middleware/check-ip.js +2 -2
- package/dist/middleware/collection-exists.js +2 -2
- package/dist/middleware/error-handler.js +7 -7
- package/dist/middleware/graphql.js +11 -9
- package/dist/middleware/rate-limiter-global.d.ts +2 -2
- package/dist/middleware/rate-limiter-global.js +2 -3
- package/dist/middleware/rate-limiter-ip.d.ts +2 -2
- package/dist/middleware/rate-limiter-ip.js +2 -3
- package/dist/middleware/validate-batch.js +3 -4
- package/dist/rate-limiter.js +2 -9
- package/dist/server.js +10 -0
- package/dist/services/activity.js +3 -2
- package/dist/services/assets.js +9 -10
- package/dist/services/authentication.js +12 -11
- package/dist/services/authorization.d.ts +1 -1
- package/dist/services/authorization.js +16 -16
- package/dist/services/collections.js +17 -16
- package/dist/services/fields.js +16 -14
- package/dist/services/files.js +7 -6
- package/dist/services/graphql/errors/execution.d.ts +6 -0
- package/dist/services/graphql/errors/execution.js +2 -0
- package/dist/services/graphql/errors/index.d.ts +2 -0
- package/dist/services/graphql/errors/index.js +2 -0
- package/dist/services/graphql/errors/validation.d.ts +6 -0
- package/dist/services/graphql/errors/validation.js +2 -0
- package/dist/services/graphql/index.d.ts +2 -8
- package/dist/services/graphql/index.js +125 -66
- package/dist/services/graphql/subscription.d.ts +16 -0
- package/dist/services/graphql/subscription.js +77 -0
- package/dist/services/graphql/utils/process-error.js +3 -3
- package/dist/services/import-export.js +7 -7
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/items.js +14 -13
- package/dist/services/mail/index.js +3 -3
- package/dist/services/meta.js +3 -3
- package/dist/services/payload.js +11 -7
- package/dist/services/relations.js +32 -22
- package/dist/services/revisions.js +3 -3
- package/dist/services/roles.js +10 -9
- package/dist/services/schema.js +5 -5
- package/dist/services/server.js +24 -0
- package/dist/services/shares.js +4 -4
- package/dist/services/tfa.js +6 -6
- package/dist/services/translations.d.ts +2 -2
- package/dist/services/translations.js +4 -4
- package/dist/services/users.js +26 -29
- package/dist/services/utils.js +4 -4
- package/dist/services/websocket.d.ts +14 -0
- package/dist/services/websocket.js +26 -0
- package/dist/synchronization.js +3 -3
- package/dist/types/items.d.ts +2 -2
- package/dist/utils/apply-diff.js +13 -4
- package/dist/utils/apply-query.js +22 -13
- package/dist/utils/get-accountability-for-role.js +1 -2
- package/dist/utils/get-accountability-for-token.d.ts +2 -0
- package/dist/utils/get-accountability-for-token.js +50 -0
- package/dist/utils/get-column-path.js +5 -3
- package/dist/utils/get-column.js +3 -3
- package/dist/utils/get-service.d.ts +7 -0
- package/dist/utils/get-service.js +49 -0
- package/dist/utils/jwt.js +5 -5
- package/dist/utils/redact.d.ts +4 -0
- package/dist/utils/redact.js +15 -1
- package/dist/utils/to-boolean.d.ts +4 -0
- package/dist/utils/to-boolean.js +6 -0
- package/dist/utils/validate-diff.js +23 -9
- package/dist/utils/validate-keys.js +3 -3
- package/dist/utils/validate-query.d.ts +2 -0
- package/dist/utils/validate-query.js +27 -21
- package/dist/utils/validate-snapshot.js +11 -5
- package/dist/websocket/authenticate.d.ts +6 -0
- package/dist/websocket/authenticate.js +59 -0
- package/dist/websocket/controllers/base.d.ts +42 -0
- package/dist/websocket/controllers/base.js +279 -0
- package/dist/websocket/controllers/graphql.d.ts +12 -0
- package/dist/websocket/controllers/graphql.js +102 -0
- package/dist/websocket/controllers/hooks.d.ts +1 -0
- package/dist/websocket/controllers/hooks.js +122 -0
- package/dist/websocket/controllers/index.d.ts +10 -0
- package/dist/websocket/controllers/index.js +31 -0
- package/dist/websocket/controllers/rest.d.ts +9 -0
- package/dist/websocket/controllers/rest.js +47 -0
- package/dist/websocket/errors.d.ts +16 -0
- package/dist/websocket/errors.js +55 -0
- package/dist/websocket/handlers/heartbeat.d.ts +11 -0
- package/dist/websocket/handlers/heartbeat.js +72 -0
- package/dist/websocket/handlers/index.d.ts +4 -0
- package/dist/websocket/handlers/index.js +11 -0
- package/dist/websocket/handlers/items.d.ts +6 -0
- package/dist/websocket/handlers/items.js +103 -0
- package/dist/websocket/handlers/subscribe.d.ts +43 -0
- package/dist/websocket/handlers/subscribe.js +278 -0
- package/dist/websocket/messages.d.ts +311 -0
- package/dist/websocket/messages.js +96 -0
- package/dist/websocket/types.d.ts +34 -0
- package/dist/websocket/types.js +1 -0
- package/dist/websocket/utils/get-expires-at-for-token.d.ts +1 -0
- package/dist/websocket/utils/get-expires-at-for-token.js +8 -0
- package/dist/websocket/utils/message.d.ts +4 -0
- package/dist/websocket/utils/message.js +27 -0
- package/dist/websocket/utils/wait-for-message.d.ts +4 -0
- package/dist/websocket/utils/wait-for-message.js +45 -0
- package/package.json +21 -16
- package/dist/exceptions/content-too-large.d.ts +0 -4
- package/dist/exceptions/content-too-large.js +0 -6
- package/dist/exceptions/database/contains-null-values.d.ts +0 -9
- package/dist/exceptions/database/contains-null-values.js +0 -6
- package/dist/exceptions/database/invalid-foreign-key.d.ts +0 -10
- package/dist/exceptions/database/invalid-foreign-key.js +0 -11
- package/dist/exceptions/database/not-null-violation.d.ts +0 -9
- package/dist/exceptions/database/not-null-violation.js +0 -6
- package/dist/exceptions/database/record-not-unique.d.ts +0 -10
- package/dist/exceptions/database/record-not-unique.js +0 -11
- package/dist/exceptions/database/value-out-of-range.d.ts +0 -10
- package/dist/exceptions/database/value-out-of-range.js +0 -11
- package/dist/exceptions/database/value-too-long.d.ts +0 -9
- package/dist/exceptions/database/value-too-long.js +0 -11
- package/dist/exceptions/forbidden.d.ts +0 -6
- package/dist/exceptions/forbidden.js +0 -13
- package/dist/exceptions/graphql-validation.d.ts +0 -4
- package/dist/exceptions/graphql-validation.js +0 -6
- package/dist/exceptions/hit-rate-limit.d.ts +0 -9
- package/dist/exceptions/hit-rate-limit.js +0 -6
- package/dist/exceptions/illegal-asset-transformation.d.ts +0 -4
- package/dist/exceptions/illegal-asset-transformation.js +0 -6
- package/dist/exceptions/index.d.ts +0 -21
- package/dist/exceptions/index.js +0 -21
- package/dist/exceptions/invalid-config.d.ts +0 -4
- package/dist/exceptions/invalid-config.js +0 -6
- package/dist/exceptions/invalid-credentials.d.ts +0 -4
- package/dist/exceptions/invalid-credentials.js +0 -6
- package/dist/exceptions/invalid-ip.d.ts +0 -4
- package/dist/exceptions/invalid-ip.js +0 -6
- package/dist/exceptions/invalid-otp.d.ts +0 -4
- package/dist/exceptions/invalid-otp.js +0 -6
- package/dist/exceptions/invalid-payload.d.ts +0 -4
- package/dist/exceptions/invalid-payload.js +0 -6
- package/dist/exceptions/invalid-provider.d.ts +0 -4
- package/dist/exceptions/invalid-provider.js +0 -6
- package/dist/exceptions/invalid-query.d.ts +0 -4
- package/dist/exceptions/invalid-query.js +0 -6
- package/dist/exceptions/invalid-token.d.ts +0 -4
- package/dist/exceptions/invalid-token.js +0 -6
- package/dist/exceptions/method-not-allowed.d.ts +0 -8
- package/dist/exceptions/method-not-allowed.js +0 -6
- package/dist/exceptions/range-not-satisfiable.d.ts +0 -5
- package/dist/exceptions/range-not-satisfiable.js +0 -9
- package/dist/exceptions/route-not-found.d.ts +0 -4
- package/dist/exceptions/route-not-found.js +0 -6
- package/dist/exceptions/service-unavailable.d.ts +0 -9
- package/dist/exceptions/service-unavailable.js +0 -6
- package/dist/exceptions/token-expired.d.ts +0 -4
- package/dist/exceptions/token-expired.js +0 -6
- package/dist/exceptions/unexpected-response.d.ts +0 -4
- package/dist/exceptions/unexpected-response.js +0 -6
- package/dist/exceptions/unprocessable-entity.d.ts +0 -4
- package/dist/exceptions/unprocessable-entity.js +0 -6
- package/dist/exceptions/unsupported-media-type.d.ts +0 -4
- package/dist/exceptions/unsupported-media-type.js +0 -6
- package/dist/exceptions/user-suspended.d.ts +0 -4
- package/dist/exceptions/user-suspended.js +0 -6
- /package/dist/{exceptions/database → database/errors}/dialects/mssql.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/mysql.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/oracle.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/postgres.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/sqlite.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/types.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/types.js +0 -0
- /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 {
|
|
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
|
|
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
|
|
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
|
|
33
|
+
throw new InvalidPayloadError({ reason: `"string" is required` });
|
|
34
34
|
}
|
|
35
35
|
if (!req.body?.hash) {
|
|
36
|
-
throw new
|
|
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
|
|
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
|
|
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
|
|
97
|
+
throw new InvalidPayloadError({ reason: `"query" is required` });
|
|
98
98
|
}
|
|
99
99
|
if (!req.body.format) {
|
|
100
|
-
throw new
|
|
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
|
|
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 {
|
|
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
|
|
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
|
|
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
|
|
106
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
106
107
|
return next();
|
|
107
108
|
}
|
|
108
109
|
throw error;
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
117
|
+
return new ContainsNullValuesError({ collection, field });
|
|
128
118
|
}
|
|
129
|
-
return new
|
|
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
|
|
138
|
+
return new InvalidForeignKeyError({
|
|
149
139
|
collection,
|
|
150
140
|
field,
|
|
151
141
|
});
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
133
|
+
return new ContainsNullValuesError({ collection, field });
|
|
144
134
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
|
22
|
+
return new ContainsNullValuesError({ collection, field });
|
|
23
23
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
72
|
+
return new ContainsNullValuesError({ collection: table, field: column });
|
|
82
73
|
}
|
|
83
|
-
return new
|
|
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
|
-
|
|
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 {
|
|
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
|
|
7
|
-
// - Sqlite doesn't have a max range for numbers, so no
|
|
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
|
|
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
|
|
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
|
|
40
|
+
return new ContainsNullValuesError({ collection: table, field: column });
|
|
44
41
|
}
|
|
45
|
-
return new
|
|
42
|
+
return new NotNullViolationError({
|
|
46
43
|
collection: table,
|
|
47
44
|
field: column,
|
|
48
45
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import getDatabase, { getDatabaseClient } from '
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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 {
|
|
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);
|