@directus/api 17.1.0 → 18.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 +8 -2
- package/dist/auth/drivers/ldap.js +14 -16
- package/dist/auth/drivers/local.js +16 -10
- package/dist/auth/drivers/oauth2.js +16 -11
- package/dist/auth/drivers/openid.js +16 -11
- package/dist/auth/drivers/saml.js +27 -12
- package/dist/cli/commands/init/index.js +3 -3
- package/dist/cli/commands/security/key.js +2 -2
- package/dist/cli/utils/create-env/env-stub.liquid +19 -4
- package/dist/cli/utils/create-env/index.js +2 -2
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +11 -4
- package/dist/controllers/auth.js +54 -19
- package/dist/controllers/extensions.js +102 -5
- package/dist/controllers/items.js +3 -2
- package/dist/controllers/permissions.js +1 -1
- package/dist/controllers/shares.js +19 -4
- package/dist/database/migrations/20220429A-add-flows.js +3 -3
- package/dist/database/migrations/20230526A-migrate-translation-strings.js +2 -2
- package/dist/database/migrations/20240204A-marketplace.d.ts +3 -0
- package/dist/database/migrations/20240204A-marketplace.js +68 -0
- package/dist/database/migrations/run.js +3 -2
- package/dist/extensions/lib/get-extensions-settings.d.ts +6 -2
- package/dist/extensions/lib/get-extensions-settings.js +70 -22
- package/dist/extensions/lib/get-extensions.d.ts +5 -1
- package/dist/extensions/lib/get-extensions.js +7 -31
- package/dist/extensions/lib/installation/index.d.ts +2 -0
- package/dist/extensions/lib/installation/index.js +9 -0
- package/dist/extensions/lib/installation/manager.d.ts +5 -0
- package/dist/extensions/lib/installation/manager.js +90 -0
- package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.d.ts +1 -1
- package/dist/extensions/lib/sync-extensions.js +11 -10
- package/dist/extensions/manager.d.ts +27 -25
- package/dist/extensions/manager.js +214 -183
- package/dist/middleware/authenticate.d.ts +1 -0
- package/dist/middleware/error-handler.js +22 -18
- package/dist/middleware/extract-token.d.ts +6 -5
- package/dist/middleware/extract-token.js +27 -11
- package/dist/middleware/merge-content-versions.d.ts +2 -0
- package/dist/middleware/merge-content-versions.js +26 -0
- package/dist/middleware/respond.js +0 -12
- package/dist/middleware/validate-batch.d.ts +1 -0
- package/dist/request/agent-with-ip-validation.d.ts +1 -1
- package/dist/request/agent-with-ip-validation.js +5 -1
- package/dist/services/activity.js +3 -3
- package/dist/services/assets.js +2 -3
- package/dist/services/authentication.d.ts +7 -2
- package/dist/services/authentication.js +21 -13
- package/dist/services/extensions.d.ts +4 -8
- package/dist/services/extensions.js +110 -93
- package/dist/services/fields.js +28 -22
- package/dist/services/graphql/index.js +98 -42
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/mail/index.d.ts +1 -1
- package/dist/services/mail/index.js +4 -2
- package/dist/services/payload.js +2 -2
- package/dist/services/{permissions.d.ts → permissions/index.d.ts} +3 -4
- package/dist/services/{permissions.js → permissions/index.js} +6 -23
- package/dist/services/permissions/lib/with-app-minimal-permissions.d.ts +2 -0
- package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
- package/dist/services/relations.d.ts +2 -3
- package/dist/services/relations.js +2 -2
- package/dist/services/roles.js +1 -1
- package/dist/services/server.js +3 -0
- package/dist/services/shares.d.ts +3 -1
- package/dist/services/shares.js +9 -5
- package/dist/storage/index.js +5 -4
- package/dist/types/auth.d.ts +6 -4
- package/dist/types/graphql.d.ts +1 -0
- package/dist/utils/apply-query.js +3 -3
- package/dist/utils/filter-items.d.ts +2 -2
- package/dist/utils/filter-items.js +1 -3
- package/dist/utils/get-cache-headers.d.ts +1 -0
- package/dist/utils/get-cache-key.d.ts +1 -0
- package/dist/utils/get-graphql-query-and-variables.d.ts +1 -0
- package/dist/utils/get-ip-from-req.d.ts +1 -0
- package/dist/utils/get-milliseconds.d.ts +1 -1
- package/dist/utils/get-milliseconds.js +4 -1
- package/dist/utils/is-login-redirect-allowed.d.ts +4 -0
- package/dist/utils/is-login-redirect-allowed.js +34 -0
- package/dist/utils/is-url-allowed.d.ts +1 -1
- package/dist/utils/is-url-allowed.js +5 -5
- package/dist/utils/is-valid-uuid.d.ts +3 -0
- package/dist/utils/is-valid-uuid.js +21 -0
- package/dist/utils/jwt.d.ts +1 -1
- package/dist/utils/jwt.js +3 -3
- package/dist/utils/merge-version-data.d.ts +3 -0
- package/dist/utils/merge-version-data.js +134 -0
- package/dist/utils/sanitize-query.js +2 -0
- package/dist/utils/should-skip-cache.d.ts +1 -0
- package/dist/utils/validate-keys.js +2 -2
- package/dist/utils/validate-query.js +1 -0
- package/dist/websocket/controllers/base.js +2 -2
- package/package.json +44 -45
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Query } from '@directus/types';
|
|
2
|
-
export declare function filterItems(items:
|
|
1
|
+
import type { Item, Query } from '@directus/types';
|
|
2
|
+
export declare function filterItems<T extends Item[]>(items: T, filter: Query['filter']): T;
|
|
@@ -6,9 +6,7 @@ import { generateJoi } from '@directus/utils';
|
|
|
6
6
|
export function filterItems(items, filter) {
|
|
7
7
|
if (!filter)
|
|
8
8
|
return items;
|
|
9
|
-
return items.filter((item) =>
|
|
10
|
-
return passesFilter(item, filter);
|
|
11
|
-
});
|
|
9
|
+
return items.filter((item) => passesFilter(item, filter));
|
|
12
10
|
function passesFilter(item, filter) {
|
|
13
11
|
if (!filter || Object.keys(filter).length === 0)
|
|
14
12
|
return true;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import ms from 'ms';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Safely parse human readable time format into milliseconds
|
|
4
|
+
*/
|
|
5
|
+
export function getMilliseconds(value, fallback) {
|
|
3
6
|
if ((typeof value !== 'string' && typeof value !== 'number') || value === '') {
|
|
4
7
|
return fallback;
|
|
5
8
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEnv } from '@directus/env';
|
|
2
|
+
import { toArray } from '@directus/utils';
|
|
3
|
+
import isUrlAllowed from './is-url-allowed.js';
|
|
4
|
+
/**
|
|
5
|
+
* Checks if the defined redirect after successful SSO login is in the allow list
|
|
6
|
+
*/
|
|
7
|
+
export function isLoginRedirectAllowed(redirect, provider) {
|
|
8
|
+
if (!redirect)
|
|
9
|
+
return true; // empty redirect
|
|
10
|
+
if (typeof redirect !== 'string')
|
|
11
|
+
return false; // invalid type
|
|
12
|
+
const env = useEnv();
|
|
13
|
+
const publicUrl = env['PUBLIC_URL'];
|
|
14
|
+
if (URL.canParse(redirect) === false) {
|
|
15
|
+
if (redirect.startsWith('//') === false) {
|
|
16
|
+
// should be a relative path like `/admin/test`
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
// domain without protocol `//example.com/test`
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const { protocol: redirectProtocol, hostname: redirectDomain } = new URL(redirect);
|
|
23
|
+
const envKey = `AUTH_${provider.toUpperCase()}_REDIRECT_ALLOW_LIST`;
|
|
24
|
+
if (envKey in env) {
|
|
25
|
+
if (isUrlAllowed(redirect, [...toArray(env[envKey]), publicUrl]))
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (URL.canParse(publicUrl) === false) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
// allow redirects to the defined PUBLIC_URL
|
|
32
|
+
const { protocol: publicProtocol, hostname: publicDomain } = new URL(publicUrl);
|
|
33
|
+
return `${redirectProtocol}//${redirectDomain}` === `${publicProtocol}//${publicDomain}`;
|
|
34
|
+
}
|
|
@@ -2,7 +2,7 @@ import { toArray } from '@directus/utils';
|
|
|
2
2
|
import { URL } from 'url';
|
|
3
3
|
import { useLogger } from '../logger.js';
|
|
4
4
|
/**
|
|
5
|
-
* Check if
|
|
5
|
+
* Check if URL matches allow list either exactly or by origin (protocol+domain+port) + pathname
|
|
6
6
|
*/
|
|
7
7
|
export default function isUrlAllowed(url, allowList) {
|
|
8
8
|
const logger = useLogger();
|
|
@@ -12,8 +12,8 @@ export default function isUrlAllowed(url, allowList) {
|
|
|
12
12
|
const parsedWhitelist = urlAllowList
|
|
13
13
|
.map((allowedURL) => {
|
|
14
14
|
try {
|
|
15
|
-
const {
|
|
16
|
-
return
|
|
15
|
+
const { origin, pathname } = new URL(allowedURL);
|
|
16
|
+
return origin + pathname;
|
|
17
17
|
}
|
|
18
18
|
catch {
|
|
19
19
|
logger.warn(`Invalid URL used "${url}"`);
|
|
@@ -22,8 +22,8 @@ export default function isUrlAllowed(url, allowList) {
|
|
|
22
22
|
})
|
|
23
23
|
.filter((f) => f);
|
|
24
24
|
try {
|
|
25
|
-
const {
|
|
26
|
-
return parsedWhitelist.includes(
|
|
25
|
+
const { origin, pathname } = new URL(url);
|
|
26
|
+
return parsedWhitelist.includes(origin + pathname);
|
|
27
27
|
}
|
|
28
28
|
catch {
|
|
29
29
|
return false;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Based on the patterns found in the 'uuid' and 'uuid-validate' npm packages, both of which are MIT licensed.
|
|
3
|
+
*
|
|
4
|
+
* The primary difference between this pattern and the patterns found in the referenced packages is that
|
|
5
|
+
* no validation over the version component (the 14th character) is performed, while the
|
|
6
|
+
* packages fail if the version is not a known one (only versions 1 through 5 are accepted).
|
|
7
|
+
*
|
|
8
|
+
* This specification complies with all major database vendors.
|
|
9
|
+
*
|
|
10
|
+
* e22f209d-9e85-4ef5-b1fe-7dc09d2b67cf
|
|
11
|
+
* ^ version
|
|
12
|
+
*
|
|
13
|
+
* @see https://datatracker.ietf.org/doc/html/rfc4122
|
|
14
|
+
* @see https://github.com/uuidjs/uuid/blob/bc46e198ab06311a9d82d3c9c6222062dd27f760/src/regex.js
|
|
15
|
+
* @see https://github.com/microsoft/uuid-validate/blob/06554db1b093aa6bb429156fa8964e1cde2b750c/index.js
|
|
16
|
+
* @see https://github.com/directus/directus/issues/21573
|
|
17
|
+
*/
|
|
18
|
+
const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19
|
+
export function isValidUuid(value) {
|
|
20
|
+
return regex.test(value);
|
|
21
|
+
}
|
package/dist/utils/jwt.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { DirectusTokenPayload } from '../types/index.js';
|
|
2
|
-
export declare function verifyJWT(token: string, secret: string): Record<string,
|
|
2
|
+
export declare function verifyJWT(token: string, secret: string): Record<string, unknown>;
|
|
3
3
|
export declare function verifyAccessJWT(token: string, secret: string): DirectusTokenPayload;
|
package/dist/utils/jwt.js
CHANGED
|
@@ -21,9 +21,9 @@ export function verifyJWT(token, secret) {
|
|
|
21
21
|
return payload;
|
|
22
22
|
}
|
|
23
23
|
export function verifyAccessJWT(token, secret) {
|
|
24
|
-
const
|
|
25
|
-
if (role === undefined || app_access === undefined || admin_access === undefined) {
|
|
24
|
+
const payload = verifyJWT(token, secret);
|
|
25
|
+
if (payload.role === undefined || payload.app_access === undefined || payload.admin_access === undefined) {
|
|
26
26
|
throw new InvalidTokenError();
|
|
27
27
|
}
|
|
28
|
-
return
|
|
28
|
+
return payload;
|
|
29
29
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Item, SchemaOverview } from '@directus/types';
|
|
2
|
+
export declare function mergeVersionsRaw(item: Item, versionData: Partial<Item>[]): Item;
|
|
3
|
+
export declare function mergeVersionsRecursive(item: Item, versionData: Item[], collection: string, schema: SchemaOverview): Item;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
import { isObject } from '@directus/utils';
|
|
3
|
+
import { cloneDeep } from 'lodash-es';
|
|
4
|
+
const alterationSchema = Joi.object({
|
|
5
|
+
create: Joi.array().items(Joi.object().unknown()),
|
|
6
|
+
update: Joi.array().items(Joi.object().unknown()),
|
|
7
|
+
delete: Joi.array().items(Joi.string(), Joi.number()),
|
|
8
|
+
});
|
|
9
|
+
export function mergeVersionsRaw(item, versionData) {
|
|
10
|
+
const result = cloneDeep(item);
|
|
11
|
+
for (const versionRecord of versionData) {
|
|
12
|
+
for (const key of Object.keys(versionRecord)) {
|
|
13
|
+
result[key] = versionRecord[key];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
export function mergeVersionsRecursive(item, versionData, collection, schema) {
|
|
19
|
+
if (versionData.length === 0)
|
|
20
|
+
return item;
|
|
21
|
+
return recursiveMerging(item, versionData, collection, schema);
|
|
22
|
+
}
|
|
23
|
+
function recursiveMerging(data, versionData, collection, schema) {
|
|
24
|
+
const result = cloneDeep(data);
|
|
25
|
+
const relations = getRelations(collection, schema);
|
|
26
|
+
for (const versionRecord of versionData) {
|
|
27
|
+
if (!isObject(versionRecord)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
for (const key of Object.keys(data)) {
|
|
31
|
+
if (key in versionRecord === false) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const currentValue = data[key];
|
|
35
|
+
const newValue = versionRecord[key];
|
|
36
|
+
if (typeof newValue !== 'object' || newValue === null) {
|
|
37
|
+
// primitive type substitution, json and non relational array values are handled in the next check
|
|
38
|
+
result[key] = newValue;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (key in relations === false) {
|
|
42
|
+
// check for m2a exception
|
|
43
|
+
if (isManyToAnyCollection(collection, schema) && key === 'item') {
|
|
44
|
+
const item = addMissingKeys(isObject(currentValue) ? currentValue : {}, newValue);
|
|
45
|
+
result[key] = recursiveMerging(item, [newValue], data['collection'], schema);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// item is not a relation
|
|
49
|
+
result[key] = newValue;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const { error } = alterationSchema.validate(newValue);
|
|
54
|
+
if (error) {
|
|
55
|
+
if (typeof newValue === 'object' && key in relations) {
|
|
56
|
+
const newItem = !currentValue || typeof currentValue !== 'object' ? newValue : currentValue;
|
|
57
|
+
result[key] = recursiveMerging(newItem, [newValue], relations[key], schema);
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const alterations = newValue;
|
|
62
|
+
const currentPrimaryKeyField = schema.collections[collection].primary;
|
|
63
|
+
const relatedPrimaryKeyField = schema.collections[relations[key]].primary;
|
|
64
|
+
const mergedRelation = [];
|
|
65
|
+
if (Array.isArray(currentValue)) {
|
|
66
|
+
if (alterations.delete.length > 0) {
|
|
67
|
+
for (const currentItem of currentValue) {
|
|
68
|
+
const currentId = typeof currentItem === 'object' ? currentItem[currentPrimaryKeyField] : currentItem;
|
|
69
|
+
if (alterations.delete.includes(currentId) === false) {
|
|
70
|
+
mergedRelation.push(currentItem);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
mergedRelation.push(...currentValue);
|
|
76
|
+
}
|
|
77
|
+
if (alterations.update.length > 0) {
|
|
78
|
+
for (const updatedItem of alterations.update) {
|
|
79
|
+
// find existing item to update
|
|
80
|
+
const itemIndex = mergedRelation.findIndex((currentItem) => currentItem[relatedPrimaryKeyField] === updatedItem[currentPrimaryKeyField]);
|
|
81
|
+
if (itemIndex === -1) {
|
|
82
|
+
// check for raw primary keys
|
|
83
|
+
const pkIndex = mergedRelation.findIndex((currentItem) => currentItem === updatedItem[currentPrimaryKeyField]);
|
|
84
|
+
if (pkIndex === -1) {
|
|
85
|
+
// nothing to update so add the item as is
|
|
86
|
+
mergedRelation.push(updatedItem);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
mergedRelation[pkIndex] = updatedItem;
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const item = addMissingKeys(mergedRelation[itemIndex], updatedItem);
|
|
94
|
+
mergedRelation[itemIndex] = recursiveMerging(item, [updatedItem], relations[key], schema);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (alterations.create.length > 0) {
|
|
99
|
+
for (const createdItem of alterations.create) {
|
|
100
|
+
const item = addMissingKeys({}, createdItem);
|
|
101
|
+
mergedRelation.push(recursiveMerging(item, [createdItem], relations[key], schema));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
result[key] = mergedRelation;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
function addMissingKeys(item, edits) {
|
|
110
|
+
const result = { ...item };
|
|
111
|
+
for (const key of Object.keys(edits)) {
|
|
112
|
+
if (key in item === false) {
|
|
113
|
+
result[key] = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function isManyToAnyCollection(collection, schema) {
|
|
119
|
+
const relation = schema.relations.find((relation) => relation.collection === collection && relation.meta?.many_collection === collection);
|
|
120
|
+
if (!relation || !relation.meta?.one_field || !relation.related_collection)
|
|
121
|
+
return false;
|
|
122
|
+
return Boolean(schema.collections[relation.related_collection]?.fields[relation.meta.one_field]?.special.includes('m2a'));
|
|
123
|
+
}
|
|
124
|
+
function getRelations(collection, schema) {
|
|
125
|
+
return schema.relations.reduce((result, relation) => {
|
|
126
|
+
if (relation.related_collection === collection && relation.meta?.one_field) {
|
|
127
|
+
result[relation.meta.one_field] = relation.collection;
|
|
128
|
+
}
|
|
129
|
+
if (relation.collection === collection && relation.related_collection) {
|
|
130
|
+
result[relation.field] = relation.related_collection;
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}, {});
|
|
134
|
+
}
|
|
@@ -48,6 +48,8 @@ export function sanitizeQuery(rawQuery, accountability) {
|
|
|
48
48
|
}
|
|
49
49
|
if (rawQuery['version']) {
|
|
50
50
|
query.version = rawQuery['version'];
|
|
51
|
+
// whether or not to merge the relational results
|
|
52
|
+
query.versionRaw = Boolean('versionRaw' in rawQuery && (rawQuery['versionRaw'] === '' || rawQuery['versionRaw'] === 'true'));
|
|
51
53
|
}
|
|
52
54
|
if (rawQuery['export']) {
|
|
53
55
|
query.export = rawQuery['export'];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ForbiddenError } from '@directus/errors';
|
|
2
|
-
import
|
|
2
|
+
import { isValidUuid } from './is-valid-uuid.js';
|
|
3
3
|
/**
|
|
4
4
|
* Validate keys based on its type
|
|
5
5
|
*/
|
|
@@ -11,7 +11,7 @@ export function validateKeys(schema, collection, keyField, keys) {
|
|
|
11
11
|
}
|
|
12
12
|
else {
|
|
13
13
|
const primaryKeyFieldType = schema.collections[collection]?.fields[keyField]?.type;
|
|
14
|
-
if (primaryKeyFieldType === 'uuid' && !
|
|
14
|
+
if (primaryKeyFieldType === 'uuid' && !isValidUuid(String(keys))) {
|
|
15
15
|
throw new ForbiddenError();
|
|
16
16
|
}
|
|
17
17
|
else if (primaryKeyFieldType === 'integer' && !Number.isInteger(Number(keys))) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEnv } from '@directus/env';
|
|
2
2
|
import { InvalidProviderConfigError, TokenExpiredError } from '@directus/errors';
|
|
3
3
|
import { parseJSON, toBoolean } from '@directus/utils';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
4
5
|
import { parse } from 'url';
|
|
5
|
-
import { v4 as uuid } from 'uuid';
|
|
6
6
|
import WebSocket, { WebSocketServer } from 'ws';
|
|
7
7
|
import { fromZodError } from 'zod-validation-error';
|
|
8
8
|
import emitter from '../../emitter.js';
|
|
@@ -157,7 +157,7 @@ export default class SocketController {
|
|
|
157
157
|
const client = ws;
|
|
158
158
|
client.accountability = accountability;
|
|
159
159
|
client.expires_at = expires_at;
|
|
160
|
-
client.uid =
|
|
160
|
+
client.uid = randomUUID();
|
|
161
161
|
client.auth_timer = null;
|
|
162
162
|
ws.on('message', async (data) => {
|
|
163
163
|
if (this.rateLimiter !== null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
],
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@authenio/samlify-node-xmllint": "2.0.0",
|
|
62
|
-
"@aws-sdk/client-ses": "3.
|
|
62
|
+
"@aws-sdk/client-ses": "3.525.0",
|
|
63
63
|
"@directus/format-title": "10.1.0",
|
|
64
64
|
"@godaddy/terminus": "4.12.1",
|
|
65
65
|
"@rollup/plugin-alias": "5.1.0",
|
|
66
66
|
"@rollup/plugin-node-resolve": "15.2.3",
|
|
67
67
|
"@rollup/plugin-virtual": "3.0.2",
|
|
68
|
-
"argon2": "0.
|
|
68
|
+
"argon2": "0.40.1",
|
|
69
69
|
"async": "3.2.5",
|
|
70
70
|
"axios": "1.6.7",
|
|
71
71
|
"busboy": "1.6.0",
|
|
@@ -81,12 +81,12 @@
|
|
|
81
81
|
"date-fns": "3.3.1",
|
|
82
82
|
"deep-diff": "1.0.2",
|
|
83
83
|
"destroy": "1.2.0",
|
|
84
|
-
"dotenv": "16.4.
|
|
84
|
+
"dotenv": "16.4.5",
|
|
85
85
|
"encodeurl": "1.0.2",
|
|
86
86
|
"eventemitter2": "6.4.9",
|
|
87
87
|
"execa": "8.0.1",
|
|
88
88
|
"exif-reader": "2.0.1",
|
|
89
|
-
"express": "4.18.
|
|
89
|
+
"express": "4.18.3",
|
|
90
90
|
"flat": "6.0.1",
|
|
91
91
|
"fs-extra": "11.2.0",
|
|
92
92
|
"glob-to-regexp": "0.4.1",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"ioredis": "5.3.2",
|
|
100
100
|
"ip-matching": "2.1.2",
|
|
101
101
|
"isolated-vm": "4.7.2",
|
|
102
|
-
"joi": "17.12.
|
|
102
|
+
"joi": "17.12.2",
|
|
103
103
|
"js-yaml": "4.1.0",
|
|
104
104
|
"js2xmlparser": "5.0.0",
|
|
105
105
|
"json2csv": "5.0.7",
|
|
@@ -117,9 +117,9 @@
|
|
|
117
117
|
"nanoid": "5.0.6",
|
|
118
118
|
"node-machine-id": "1.1.12",
|
|
119
119
|
"node-schedule": "2.1.1",
|
|
120
|
-
"nodemailer": "6.9.
|
|
120
|
+
"nodemailer": "6.9.11",
|
|
121
121
|
"object-hash": "3.0.0",
|
|
122
|
-
"openapi3-ts": "4.2.
|
|
122
|
+
"openapi3-ts": "4.2.2",
|
|
123
123
|
"openid-client": "5.6.4",
|
|
124
124
|
"ora": "8.0.1",
|
|
125
125
|
"otplib": "12.0.1",
|
|
@@ -131,41 +131,41 @@
|
|
|
131
131
|
"pino-http-print": "3.1.0",
|
|
132
132
|
"pino-pretty": "10.3.1",
|
|
133
133
|
"qs": "6.11.2",
|
|
134
|
-
"rate-limiter-flexible": "
|
|
135
|
-
"rollup": "4.
|
|
136
|
-
"samlify": "2.8.
|
|
137
|
-
"sanitize-html": "2.12.
|
|
134
|
+
"rate-limiter-flexible": "5.0.0",
|
|
135
|
+
"rollup": "4.12.0",
|
|
136
|
+
"samlify": "2.8.11",
|
|
137
|
+
"sanitize-html": "2.12.1",
|
|
138
138
|
"sharp": "0.33.2",
|
|
139
139
|
"snappy": "7.2.2",
|
|
140
140
|
"stream-json": "1.8.0",
|
|
141
|
+
"tar": "6.2.0",
|
|
141
142
|
"tsx": "4.7.1",
|
|
142
|
-
"uuid": "9.0.1",
|
|
143
|
-
"uuid-validate": "0.0.3",
|
|
144
143
|
"wellknown": "0.5.0",
|
|
145
144
|
"ws": "8.16.0",
|
|
146
145
|
"zod": "3.22.4",
|
|
147
|
-
"zod-validation-error": "3.0.
|
|
148
|
-
"@directus/app": "
|
|
146
|
+
"zod-validation-error": "3.0.3",
|
|
147
|
+
"@directus/app": "11.0.0",
|
|
149
148
|
"@directus/constants": "11.0.3",
|
|
150
|
-
"@directus/
|
|
151
|
-
"@directus/
|
|
152
|
-
"@directus/extensions": "0.
|
|
153
|
-
"@directus/extensions
|
|
154
|
-
"@directus/
|
|
149
|
+
"@directus/env": "1.0.3",
|
|
150
|
+
"@directus/errors": "0.2.4",
|
|
151
|
+
"@directus/extensions-registry": "1.0.0",
|
|
152
|
+
"@directus/extensions": "1.0.0",
|
|
153
|
+
"@directus/extensions-sdk": "11.0.0",
|
|
154
|
+
"@directus/memory": "1.0.4",
|
|
155
|
+
"@directus/pressure": "1.0.17",
|
|
155
156
|
"@directus/schema": "11.0.1",
|
|
156
|
-
"@directus/specs": "10.2.
|
|
157
|
-
"@directus/
|
|
158
|
-
"@directus/storage-driver-azure": "10.0.
|
|
159
|
-
"@directus/storage": "10.0.
|
|
160
|
-
"@directus/storage-driver-
|
|
161
|
-
"@directus/storage-driver-
|
|
162
|
-
"@directus/storage-driver-
|
|
163
|
-
"@directus/storage-driver-
|
|
164
|
-
"@directus/
|
|
165
|
-
"@directus/
|
|
166
|
-
"
|
|
167
|
-
"directus": "
|
|
168
|
-
"@directus/validation": "0.0.12"
|
|
157
|
+
"@directus/specs": "10.2.7",
|
|
158
|
+
"@directus/storage": "10.0.11",
|
|
159
|
+
"@directus/storage-driver-azure": "10.0.18",
|
|
160
|
+
"@directus/storage-driver-cloudinary": "10.0.18",
|
|
161
|
+
"@directus/storage-driver-gcs": "10.0.18",
|
|
162
|
+
"@directus/storage-driver-s3": "10.0.19",
|
|
163
|
+
"@directus/storage-driver-local": "10.0.18",
|
|
164
|
+
"@directus/storage-driver-supabase": "1.0.10",
|
|
165
|
+
"@directus/system-data": "1.0.1",
|
|
166
|
+
"@directus/utils": "11.0.6",
|
|
167
|
+
"directus": "10.10.0",
|
|
168
|
+
"@directus/validation": "0.0.13"
|
|
169
169
|
},
|
|
170
170
|
"devDependencies": {
|
|
171
171
|
"@ngneat/falso": "7.2.0",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"@types/busboy": "1.5.3",
|
|
174
174
|
"@types/bytes": "3.1.4",
|
|
175
175
|
"@types/content-disposition": "0.5.8",
|
|
176
|
-
"@types/cookie-parser": "1.4.
|
|
176
|
+
"@types/cookie-parser": "1.4.7",
|
|
177
177
|
"@types/cors": "2.8.17",
|
|
178
178
|
"@types/deep-diff": "1.0.5",
|
|
179
179
|
"@types/destroy": "1.0.3",
|
|
@@ -185,21 +185,20 @@
|
|
|
185
185
|
"@types/inquirer": "9.0.7",
|
|
186
186
|
"@types/js-yaml": "4.0.9",
|
|
187
187
|
"@types/json2csv": "5.0.7",
|
|
188
|
-
"@types/jsonwebtoken": "9.0.
|
|
188
|
+
"@types/jsonwebtoken": "9.0.6",
|
|
189
189
|
"@types/ldapjs": "2.2.5",
|
|
190
190
|
"@types/lodash-es": "4.17.12",
|
|
191
191
|
"@types/mime-types": "2.1.4",
|
|
192
192
|
"@types/ms": "0.7.34",
|
|
193
|
-
"@types/node": "18.19.
|
|
193
|
+
"@types/node": "18.19.21",
|
|
194
194
|
"@types/node-schedule": "2.1.6",
|
|
195
195
|
"@types/nodemailer": "6.4.14",
|
|
196
196
|
"@types/object-hash": "3.0.6",
|
|
197
197
|
"@types/papaparse": "5.3.14",
|
|
198
|
-
"@types/qs": "6.9.
|
|
198
|
+
"@types/qs": "6.9.12",
|
|
199
199
|
"@types/sanitize-html": "2.11.0",
|
|
200
200
|
"@types/stream-json": "1.7.7",
|
|
201
|
-
"@types/
|
|
202
|
-
"@types/uuid-validate": "0.0.3",
|
|
201
|
+
"@types/tar": "6.1.11",
|
|
203
202
|
"@types/wellknown": "0.5.8",
|
|
204
203
|
"@types/ws": "8.5.10",
|
|
205
204
|
"@vitest/coverage-v8": "1.3.1",
|
|
@@ -207,10 +206,10 @@
|
|
|
207
206
|
"form-data": "4.0.0",
|
|
208
207
|
"knex-mock-client": "2.0.1",
|
|
209
208
|
"typescript": "5.3.3",
|
|
210
|
-
"vitest": "1.3.
|
|
209
|
+
"vitest": "1.3.1",
|
|
210
|
+
"@directus/random": "0.2.7",
|
|
211
211
|
"@directus/tsconfig": "1.0.1",
|
|
212
|
-
"@directus/
|
|
213
|
-
"@directus/types": "11.0.6"
|
|
212
|
+
"@directus/types": "11.0.7"
|
|
214
213
|
},
|
|
215
214
|
"optionalDependencies": {
|
|
216
215
|
"@keyv/redis": "2.8.4",
|
|
@@ -220,7 +219,7 @@
|
|
|
220
219
|
"oracledb": "6.3.0",
|
|
221
220
|
"pg": "8.11.3",
|
|
222
221
|
"sqlite3": "5.1.7",
|
|
223
|
-
"tedious": "
|
|
222
|
+
"tedious": "17.0.0"
|
|
224
223
|
},
|
|
225
224
|
"engines": {
|
|
226
225
|
"node": ">=18.17.0"
|
|
@@ -228,7 +227,7 @@
|
|
|
228
227
|
"scripts": {
|
|
229
228
|
"build": "tsc --project tsconfig.prod.json && copyfiles \"src/**/*.{yaml,liquid}\" -u 1 dist",
|
|
230
229
|
"cli": "NODE_ENV=development SERVE_APP=false tsx src/cli/run.ts",
|
|
231
|
-
"dev": "NODE_ENV=development SERVE_APP=
|
|
230
|
+
"dev": "NODE_ENV=development SERVE_APP=true tsx watch --clear-screen=false src/start.ts",
|
|
232
231
|
"test": "vitest --watch=false"
|
|
233
232
|
}
|
|
234
233
|
}
|