directus 9.21.0 → 9.22.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 +9 -5
- package/dist/app.test.d.ts +1 -0
- package/dist/auth/drivers/openid.js +3 -1
- package/dist/cli/commands/bootstrap/index.js +2 -2
- package/dist/cli/commands/schema/apply.js +0 -2
- package/dist/cli/commands/schema/snapshot.js +0 -2
- package/dist/cli/commands/security/secret.js +2 -2
- package/dist/cli/utils/create-env/env-stub.liquid +3 -3
- package/dist/cli/utils/create-env/index.js +5 -8
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -1
- package/dist/controllers/assets.js +9 -7
- package/dist/controllers/files.js +2 -1
- package/dist/controllers/utils.js +2 -2
- package/dist/database/helpers/fn/dialects/mssql.js +2 -1
- package/dist/database/helpers/fn/dialects/mysql.js +3 -2
- package/dist/database/helpers/fn/dialects/oracle.js +2 -1
- package/dist/database/helpers/fn/dialects/postgres.js +2 -1
- package/dist/database/helpers/fn/dialects/sqlite.js +2 -1
- package/dist/database/helpers/fn/types.d.ts +1 -0
- package/dist/database/helpers/fn/types.js +5 -4
- package/dist/database/helpers/index.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mssql.d.ts +6 -0
- package/dist/database/helpers/schema/dialects/mssql.js +14 -0
- package/dist/database/helpers/schema/dialects/mysql.d.ts +5 -0
- package/dist/database/helpers/schema/dialects/mysql.js +19 -0
- package/dist/database/helpers/schema/dialects/oracle.d.ts +1 -0
- package/dist/database/helpers/schema/dialects/oracle.js +3 -0
- package/dist/database/helpers/schema/index.d.ts +2 -2
- package/dist/database/helpers/schema/index.js +4 -4
- package/dist/database/helpers/schema/types.d.ts +5 -0
- package/dist/database/helpers/schema/types.js +13 -0
- package/dist/database/index.d.ts +6 -0
- package/dist/database/index.js +20 -1
- package/dist/database/migrations/20211007A-update-presets.js +2 -2
- package/dist/database/migrations/run.js +7 -31
- package/dist/database/run-ast.js +132 -6
- package/dist/database/system-data/fields/index.js +2 -1
- package/dist/env.js +3 -2
- package/dist/exceptions/range-not-satisfiable.d.ts +1 -1
- package/dist/extensions.d.ts +7 -1
- package/dist/extensions.js +41 -15
- package/dist/logger.js +27 -1
- package/dist/middleware/schema.js +1 -1
- package/dist/operations/request/index.d.ts +1 -2
- package/dist/operations/request/index.js +2 -2
- package/dist/services/assets.d.ts +4 -3
- package/dist/services/assets.js +13 -11
- package/dist/services/authentication.js +4 -3
- package/dist/services/authorization.js +1 -1
- package/dist/services/collections.js +7 -7
- package/dist/services/fields.d.ts +3 -2
- package/dist/services/fields.js +40 -20
- package/dist/services/files.d.ts +4 -3
- package/dist/services/files.js +92 -68
- package/dist/services/flows.d.ts +0 -2
- package/dist/services/flows.js +0 -14
- package/dist/services/flows.test.d.ts +1 -0
- package/dist/services/graphql/index.d.ts +5 -1
- package/dist/services/graphql/index.js +29 -31
- package/dist/services/import-export.d.ts +4 -3
- package/dist/services/items.js +7 -1
- package/dist/services/meta.js +2 -2
- package/dist/services/operations.d.ts +0 -2
- package/dist/services/operations.js +0 -12
- package/dist/services/operations.test.d.ts +1 -0
- package/dist/services/permissions.d.ts +0 -5
- package/dist/services/permissions.js +0 -25
- package/dist/services/permissions.test.d.ts +1 -0
- package/dist/services/relations.d.ts +2 -2
- package/dist/services/relations.js +24 -16
- package/dist/services/roles.js +0 -3
- package/dist/services/roles.test.d.ts +1 -0
- package/dist/services/server.js +8 -6
- package/dist/services/shares.js +2 -2
- package/dist/services/specifications.js +12 -1
- package/dist/services/users.js +10 -4
- package/dist/services/webhooks.d.ts +0 -2
- package/dist/services/webhooks.js +0 -10
- package/dist/services/webhooks.test.d.ts +1 -0
- package/dist/storage/get-storage-driver.d.ts +3 -0
- package/dist/storage/get-storage-driver.js +20 -0
- package/dist/storage/get-storage-driver.test.d.ts +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +20 -0
- package/dist/storage/index.test.d.ts +1 -0
- package/dist/storage/register-drivers.d.ts +2 -0
- package/dist/storage/register-drivers.js +22 -0
- package/dist/storage/register-drivers.test.d.ts +1 -0
- package/dist/storage/register-locations.d.ts +2 -0
- package/dist/storage/register-locations.js +17 -0
- package/dist/storage/register-locations.test.d.ts +1 -0
- package/dist/utils/apply-query.d.ts +27 -3
- package/dist/utils/apply-query.js +180 -127
- package/dist/utils/apply-snapshot.js +32 -13
- package/dist/utils/dynamic-import.d.ts +1 -0
- package/dist/utils/dynamic-import.js +7 -0
- package/dist/utils/get-collection-from-alias.d.ts +6 -0
- package/dist/utils/get-collection-from-alias.js +15 -0
- package/dist/utils/get-collection-from-alias.test.d.ts +1 -0
- package/dist/utils/get-column-path.d.ts +14 -8
- package/dist/utils/get-column-path.js +24 -7
- package/dist/utils/get-column.d.ts +8 -1
- package/dist/utils/get-column.js +10 -3
- package/dist/utils/get-config-from-env.js +3 -2
- package/dist/utils/get-default-value.d.ts +1 -1
- package/dist/utils/get-schema.d.ts +6 -2
- package/dist/utils/get-schema.js +1 -1
- package/dist/utils/get-snapshot.js +1 -1
- package/dist/utils/parse-image-metadata.d.ts +3 -0
- package/dist/utils/parse-image-metadata.js +73 -0
- package/dist/utils/track.js +2 -2
- package/dist/utils/validate-env.js +3 -2
- package/dist/webhooks.js +2 -2
- package/package.json +18 -22
- package/dist/storage.d.ts +0 -3
- package/dist/storage.js +0 -61
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.GraphQLService = void 0;
|
|
7
7
|
const types_1 = require("@directus/shared/types");
|
|
8
|
+
const utils_1 = require("@directus/shared/utils");
|
|
8
9
|
const argon2_1 = __importDefault(require("argon2"));
|
|
9
10
|
const graphql_1 = require("graphql");
|
|
10
11
|
const graphql_compose_1 = require("graphql-compose");
|
|
@@ -13,7 +14,6 @@ const lodash_1 = require("lodash");
|
|
|
13
14
|
const ms_1 = __importDefault(require("ms"));
|
|
14
15
|
const cache_1 = require("../../cache");
|
|
15
16
|
const constants_1 = require("../../constants");
|
|
16
|
-
const constants_2 = require("@directus/shared/constants");
|
|
17
17
|
const database_1 = __importDefault(require("../../database"));
|
|
18
18
|
const env_1 = __importDefault(require("../../env"));
|
|
19
19
|
const exceptions_1 = require("../../exceptions");
|
|
@@ -44,7 +44,7 @@ const shares_1 = require("../shares");
|
|
|
44
44
|
const specifications_1 = require("../specifications");
|
|
45
45
|
const tfa_1 = require("../tfa");
|
|
46
46
|
const users_1 = require("../users");
|
|
47
|
-
const
|
|
47
|
+
const utils_2 = require("../utils");
|
|
48
48
|
const webhooks_1 = require("../webhooks");
|
|
49
49
|
const date_1 = require("./types/date");
|
|
50
50
|
const geojson_1 = require("./types/geojson");
|
|
@@ -53,6 +53,7 @@ const void_1 = require("./types/void");
|
|
|
53
53
|
const add_path_to_validation_error_1 = require("./utils/add-path-to-validation-error");
|
|
54
54
|
const hash_1 = require("./types/hash");
|
|
55
55
|
const bigint_1 = require("./types/bigint");
|
|
56
|
+
const constants_2 = require("@directus/shared/constants");
|
|
56
57
|
const validationRules = Array.from(graphql_1.specifiedRules);
|
|
57
58
|
if (env_1.default.GRAPHQL_INTROSPECTION === false) {
|
|
58
59
|
validationRules.push(graphql_1.NoSchemaIntrospectionCustomRule);
|
|
@@ -1111,14 +1112,7 @@ class GraphQLService {
|
|
|
1111
1112
|
// Transform count(a.b.c) into a.b.count(c)
|
|
1112
1113
|
if ((_c = query.fields) === null || _c === void 0 ? void 0 : _c.length) {
|
|
1113
1114
|
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
|
|
1114
|
-
|
|
1115
|
-
const functionName = query.fields[fieldIndex].split('(')[0];
|
|
1116
|
-
const columnNames = query.fields[fieldIndex].match(constants_2.REGEX_BETWEEN_PARENS)[1].split('.');
|
|
1117
|
-
if (columnNames.length > 1) {
|
|
1118
|
-
const column = columnNames.pop();
|
|
1119
|
-
query.fields[fieldIndex] = columnNames.join('.') + '.' + functionName + '(' + column + ')';
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1115
|
+
query.fields[fieldIndex] = (0, utils_1.parseFilterFunctionPath)(query.fields[fieldIndex]);
|
|
1122
1116
|
}
|
|
1123
1117
|
}
|
|
1124
1118
|
const result = await this.read(collection, query);
|
|
@@ -1347,28 +1341,10 @@ class GraphQLService {
|
|
|
1347
1341
|
}
|
|
1348
1342
|
return (0, lodash_1.uniq)(fields);
|
|
1349
1343
|
};
|
|
1350
|
-
const replaceFuncs = (filter) => {
|
|
1351
|
-
if (!filter)
|
|
1352
|
-
return filter;
|
|
1353
|
-
return replaceFuncDeep(filter);
|
|
1354
|
-
function replaceFuncDeep(filter) {
|
|
1355
|
-
return (0, lodash_1.transform)(filter, (result, value, key) => {
|
|
1356
|
-
let currentKey = key;
|
|
1357
|
-
if (typeof key === 'string' && key.endsWith('_func')) {
|
|
1358
|
-
const functionName = Object.keys(value)[0];
|
|
1359
|
-
currentKey = `${functionName}(${currentKey.slice(0, -5)})`;
|
|
1360
|
-
result[currentKey] = Object.values(value)[0];
|
|
1361
|
-
}
|
|
1362
|
-
else {
|
|
1363
|
-
result[currentKey] =
|
|
1364
|
-
(value === null || value === void 0 ? void 0 : value.constructor) === Object || (value === null || value === void 0 ? void 0 : value.constructor) === Array ? replaceFuncDeep(value) : value;
|
|
1365
|
-
}
|
|
1366
|
-
});
|
|
1367
|
-
}
|
|
1368
|
-
};
|
|
1369
1344
|
query.alias = parseAliases(selections);
|
|
1370
1345
|
query.fields = parseFields(selections);
|
|
1371
|
-
query.filter = replaceFuncs(query.filter);
|
|
1346
|
+
query.filter = this.replaceFuncs(query.filter);
|
|
1347
|
+
query.deep = this.replaceFuncs(query.deep);
|
|
1372
1348
|
(0, validate_query_1.validateQuery)(query);
|
|
1373
1349
|
return query;
|
|
1374
1350
|
}
|
|
@@ -1393,9 +1369,31 @@ class GraphQLService {
|
|
|
1393
1369
|
return selectionNode.name.value;
|
|
1394
1370
|
})) !== null && _b !== void 0 ? _b : [];
|
|
1395
1371
|
}
|
|
1372
|
+
query.filter = this.replaceFuncs(query.filter);
|
|
1396
1373
|
(0, validate_query_1.validateQuery)(query);
|
|
1397
1374
|
return query;
|
|
1398
1375
|
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Replace functions from GraphQL format to Directus-Filter format
|
|
1378
|
+
*/
|
|
1379
|
+
replaceFuncs(filter) {
|
|
1380
|
+
if (!filter)
|
|
1381
|
+
return filter;
|
|
1382
|
+
return replaceFuncDeep(filter);
|
|
1383
|
+
function replaceFuncDeep(filter) {
|
|
1384
|
+
return (0, lodash_1.transform)(filter, (result, value, key) => {
|
|
1385
|
+
const isFunctionKey = typeof key === 'string' && key.endsWith('_func') && constants_2.FUNCTIONS.includes(Object.keys(value)[0]);
|
|
1386
|
+
if (isFunctionKey) {
|
|
1387
|
+
const functionName = Object.keys(value)[0];
|
|
1388
|
+
const fieldName = key.slice(0, -5);
|
|
1389
|
+
result[`${functionName}(${fieldName})`] = Object.values(value)[0];
|
|
1390
|
+
}
|
|
1391
|
+
else {
|
|
1392
|
+
result[key] = (value === null || value === void 0 ? void 0 : value.constructor) === Object || (value === null || value === void 0 ? void 0 : value.constructor) === Array ? replaceFuncDeep(value) : value;
|
|
1393
|
+
}
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1399
1397
|
/**
|
|
1400
1398
|
* Convert Directus-Exception into a GraphQL format, so it can be returned by GraphQL properly.
|
|
1401
1399
|
*/
|
|
@@ -1870,7 +1868,7 @@ class GraphQLService {
|
|
|
1870
1868
|
to: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID),
|
|
1871
1869
|
},
|
|
1872
1870
|
resolve: async (_, args) => {
|
|
1873
|
-
const service = new
|
|
1871
|
+
const service = new utils_2.UtilsService({
|
|
1874
1872
|
accountability: this.accountability,
|
|
1875
1873
|
schema: this.schema,
|
|
1876
1874
|
});
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
3
3
|
import { Knex } from 'knex';
|
|
4
4
|
import { AbstractServiceOptions, File } from '../types';
|
|
5
|
+
import type { Readable } from 'node:stream';
|
|
5
6
|
export declare class ImportService {
|
|
6
7
|
knex: Knex;
|
|
7
8
|
accountability: Accountability | null;
|
|
8
9
|
schema: SchemaOverview;
|
|
9
10
|
constructor(options: AbstractServiceOptions);
|
|
10
|
-
import(collection: string, mimetype: string, stream:
|
|
11
|
-
importJSON(collection: string, stream:
|
|
12
|
-
importCSV(collection: string, stream:
|
|
11
|
+
import(collection: string, mimetype: string, stream: Readable): Promise<void>;
|
|
12
|
+
importJSON(collection: string, stream: Readable): Promise<void>;
|
|
13
|
+
importCSV(collection: string, stream: Readable): Promise<void>;
|
|
13
14
|
}
|
|
14
15
|
export declare class ExportService {
|
|
15
16
|
knex: Knex;
|
package/dist/services/items.js
CHANGED
|
@@ -8,6 +8,7 @@ const types_1 = require("@directus/shared/types");
|
|
|
8
8
|
const lodash_1 = require("lodash");
|
|
9
9
|
const cache_1 = require("../cache");
|
|
10
10
|
const database_1 = __importDefault(require("../database"));
|
|
11
|
+
const helpers_1 = require("../database/helpers");
|
|
11
12
|
const run_ast_1 = __importDefault(require("../database/run-ast"));
|
|
12
13
|
const emitter_1 = __importDefault(require("../emitter"));
|
|
13
14
|
const env_1 = __importDefault(require("../env"));
|
|
@@ -98,7 +99,12 @@ class ItemsService {
|
|
|
98
99
|
.returning(primaryKeyField)
|
|
99
100
|
.then((result) => result[0]);
|
|
100
101
|
const returnedKey = typeof result === 'object' ? result[primaryKeyField] : result;
|
|
101
|
-
|
|
102
|
+
if (this.schema.collections[this.collection].fields[primaryKeyField].type === 'uuid') {
|
|
103
|
+
primaryKey = (0, helpers_1.getHelpers)(trx).schema.formatUUID(primaryKey !== null && primaryKey !== void 0 ? primaryKey : returnedKey);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
primaryKey = primaryKey !== null && primaryKey !== void 0 ? primaryKey : returnedKey;
|
|
107
|
+
}
|
|
102
108
|
}
|
|
103
109
|
catch (err) {
|
|
104
110
|
throw await (0, translate_1.translateDatabaseError)(err);
|
package/dist/services/meta.js
CHANGED
|
@@ -40,7 +40,7 @@ class MetaService {
|
|
|
40
40
|
if (!permissionsRecord)
|
|
41
41
|
throw new exceptions_1.ForbiddenException();
|
|
42
42
|
const permissions = (_d = permissionsRecord.permissions) !== null && _d !== void 0 ? _d : {};
|
|
43
|
-
(0, apply_query_1.applyFilter)(this.knex, this.schema, dbQuery, permissions, collection);
|
|
43
|
+
(0, apply_query_1.applyFilter)(this.knex, this.schema, dbQuery, permissions, collection, {});
|
|
44
44
|
}
|
|
45
45
|
const result = await dbQuery;
|
|
46
46
|
return Number((_e = result === null || result === void 0 ? void 0 : result.count) !== null && _e !== void 0 ? _e : 0);
|
|
@@ -64,7 +64,7 @@ class MetaService {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
if (Object.keys(filter).length > 0) {
|
|
67
|
-
(0, apply_query_1.applyFilter)(this.knex, this.schema, dbQuery, filter, collection);
|
|
67
|
+
(0, apply_query_1.applyFilter)(this.knex, this.schema, dbQuery, filter, collection, {});
|
|
68
68
|
}
|
|
69
69
|
if (query.search) {
|
|
70
70
|
(0, apply_query_1.applySearch)(this.schema, dbQuery, query.search, collection);
|
|
@@ -5,9 +5,7 @@ export declare class OperationsService extends ItemsService<OperationRaw> {
|
|
|
5
5
|
constructor(options: AbstractServiceOptions);
|
|
6
6
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
7
7
|
createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
8
|
-
updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
9
8
|
updateBatch(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
10
9
|
updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
11
|
-
deleteOne(key: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
12
10
|
deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
13
11
|
}
|
|
@@ -19,12 +19,6 @@ class OperationsService extends items_1.ItemsService {
|
|
|
19
19
|
await flowManager.reload();
|
|
20
20
|
return result;
|
|
21
21
|
}
|
|
22
|
-
async updateOne(key, data, opts) {
|
|
23
|
-
const flowManager = (0, flows_1.getFlowManager)();
|
|
24
|
-
const result = await super.updateOne(key, data, opts);
|
|
25
|
-
await flowManager.reload();
|
|
26
|
-
return result;
|
|
27
|
-
}
|
|
28
22
|
async updateBatch(data, opts) {
|
|
29
23
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
30
24
|
const result = await super.updateBatch(data, opts);
|
|
@@ -37,12 +31,6 @@ class OperationsService extends items_1.ItemsService {
|
|
|
37
31
|
await flowManager.reload();
|
|
38
32
|
return result;
|
|
39
33
|
}
|
|
40
|
-
async deleteOne(key, opts) {
|
|
41
|
-
const flowManager = (0, flows_1.getFlowManager)();
|
|
42
|
-
const result = await super.deleteOne(key, opts);
|
|
43
|
-
await flowManager.reload();
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
34
|
async deleteMany(keys, opts) {
|
|
47
35
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
48
36
|
const result = await super.deleteMany(keys, opts);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -10,13 +10,8 @@ export declare class PermissionsService extends ItemsService {
|
|
|
10
10
|
readMany(keys: PrimaryKey[], query?: Query, opts?: QueryOptions): Promise<Partial<Item>[]>;
|
|
11
11
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
12
12
|
createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
13
|
-
updateByQuery(query: Query, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
14
|
-
updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
15
13
|
updateBatch(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
16
14
|
updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
17
|
-
upsertOne(payload: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
18
15
|
upsertMany(payloads: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
19
|
-
deleteByQuery(query: Query, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
20
|
-
deleteOne(key: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
21
16
|
deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
22
17
|
}
|
|
@@ -60,16 +60,6 @@ class PermissionsService extends items_1.ItemsService {
|
|
|
60
60
|
await (0, cache_1.clearSystemCache)();
|
|
61
61
|
return res;
|
|
62
62
|
}
|
|
63
|
-
async updateByQuery(query, data, opts) {
|
|
64
|
-
const res = await super.updateByQuery(query, data, opts);
|
|
65
|
-
await (0, cache_1.clearSystemCache)();
|
|
66
|
-
return res;
|
|
67
|
-
}
|
|
68
|
-
async updateOne(key, data, opts) {
|
|
69
|
-
const res = await super.updateOne(key, data, opts);
|
|
70
|
-
await (0, cache_1.clearSystemCache)();
|
|
71
|
-
return res;
|
|
72
|
-
}
|
|
73
63
|
async updateBatch(data, opts) {
|
|
74
64
|
const res = await super.updateBatch(data, opts);
|
|
75
65
|
await (0, cache_1.clearSystemCache)();
|
|
@@ -80,26 +70,11 @@ class PermissionsService extends items_1.ItemsService {
|
|
|
80
70
|
await (0, cache_1.clearSystemCache)();
|
|
81
71
|
return res;
|
|
82
72
|
}
|
|
83
|
-
async upsertOne(payload, opts) {
|
|
84
|
-
const res = await super.upsertOne(payload, opts);
|
|
85
|
-
await (0, cache_1.clearSystemCache)();
|
|
86
|
-
return res;
|
|
87
|
-
}
|
|
88
73
|
async upsertMany(payloads, opts) {
|
|
89
74
|
const res = await super.upsertMany(payloads, opts);
|
|
90
75
|
await (0, cache_1.clearSystemCache)();
|
|
91
76
|
return res;
|
|
92
77
|
}
|
|
93
|
-
async deleteByQuery(query, opts) {
|
|
94
|
-
const res = await super.deleteByQuery(query, opts);
|
|
95
|
-
await (0, cache_1.clearSystemCache)();
|
|
96
|
-
return res;
|
|
97
|
-
}
|
|
98
|
-
async deleteOne(key, opts) {
|
|
99
|
-
const res = await super.deleteOne(key, opts);
|
|
100
|
-
await (0, cache_1.clearSystemCache)();
|
|
101
|
-
return res;
|
|
102
|
-
}
|
|
103
78
|
async deleteMany(keys, opts) {
|
|
104
79
|
const res = await super.deleteMany(keys, opts);
|
|
105
80
|
await (0, cache_1.clearSystemCache)();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -21,13 +21,13 @@ export declare class RelationsService {
|
|
|
21
21
|
/**
|
|
22
22
|
* Create a new relationship / foreign key constraint
|
|
23
23
|
*/
|
|
24
|
-
createOne(relation: Partial<Relation
|
|
24
|
+
createOne(relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Update an existing foreign key constraint
|
|
27
27
|
*
|
|
28
28
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
29
29
|
*/
|
|
30
|
-
updateOne(collection: string, field: string, relation: Partial<Relation
|
|
30
|
+
updateOne(collection: string, field: string, relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Delete an existing relationship
|
|
33
33
|
*/
|
|
@@ -127,7 +127,7 @@ class RelationsService {
|
|
|
127
127
|
/**
|
|
128
128
|
* Create a new relationship / foreign key constraint
|
|
129
129
|
*/
|
|
130
|
-
async createOne(relation) {
|
|
130
|
+
async createOne(relation, opts) {
|
|
131
131
|
if (this.accountability && this.accountability.admin !== true) {
|
|
132
132
|
throw new exceptions_1.ForbiddenException();
|
|
133
133
|
}
|
|
@@ -185,7 +185,7 @@ class RelationsService {
|
|
|
185
185
|
// happens in `filterForbidden` down below
|
|
186
186
|
});
|
|
187
187
|
await relationsItemService.createOne(metaRow, {
|
|
188
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
188
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
189
189
|
});
|
|
190
190
|
});
|
|
191
191
|
}
|
|
@@ -193,11 +193,15 @@ class RelationsService {
|
|
|
193
193
|
if (runPostColumnChange) {
|
|
194
194
|
await this.helpers.schema.postColumnChange();
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
197
|
+
await (0, cache_1.clearSystemCache)();
|
|
198
|
+
}
|
|
199
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
200
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
201
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
202
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
203
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
204
|
+
}
|
|
201
205
|
}
|
|
202
206
|
}
|
|
203
207
|
}
|
|
@@ -206,7 +210,7 @@ class RelationsService {
|
|
|
206
210
|
*
|
|
207
211
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
208
212
|
*/
|
|
209
|
-
async updateOne(collection, field, relation) {
|
|
213
|
+
async updateOne(collection, field, relation, opts) {
|
|
210
214
|
if (this.accountability && this.accountability.admin !== true) {
|
|
211
215
|
throw new exceptions_1.ForbiddenException();
|
|
212
216
|
}
|
|
@@ -254,7 +258,7 @@ class RelationsService {
|
|
|
254
258
|
if (relation.meta) {
|
|
255
259
|
if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.meta) {
|
|
256
260
|
await relationsItemService.updateOne(existingRelation.meta.id, relation.meta, {
|
|
257
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
261
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
258
262
|
});
|
|
259
263
|
}
|
|
260
264
|
else {
|
|
@@ -264,7 +268,7 @@ class RelationsService {
|
|
|
264
268
|
many_field: relation.field,
|
|
265
269
|
one_collection: existingRelation.related_collection || null,
|
|
266
270
|
}, {
|
|
267
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
271
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
268
272
|
});
|
|
269
273
|
}
|
|
270
274
|
}
|
|
@@ -274,11 +278,15 @@ class RelationsService {
|
|
|
274
278
|
if (runPostColumnChange) {
|
|
275
279
|
await this.helpers.schema.postColumnChange();
|
|
276
280
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
281
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
282
|
+
await (0, cache_1.clearSystemCache)();
|
|
283
|
+
}
|
|
284
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
285
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
286
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
287
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
288
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
289
|
+
}
|
|
282
290
|
}
|
|
283
291
|
}
|
|
284
292
|
}
|
|
@@ -343,7 +351,7 @@ class RelationsService {
|
|
|
343
351
|
await (0, cache_1.clearSystemCache)();
|
|
344
352
|
}
|
|
345
353
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
346
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
354
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
347
355
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
348
356
|
nestedActionEvent.context.schema = updatedSchema;
|
|
349
357
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
package/dist/services/roles.js
CHANGED
|
@@ -56,9 +56,6 @@ class RolesService extends items_1.ItemsService {
|
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
async updateOne(key, data, opts) {
|
|
59
|
-
if ('admin_access' in data && data.admin_access === false) {
|
|
60
|
-
await this.checkForOtherAdminRoles([key]);
|
|
61
|
-
}
|
|
62
59
|
if ('users' in data) {
|
|
63
60
|
await this.checkForOtherAdminUsers(key, data.users);
|
|
64
61
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/services/server.js
CHANGED
|
@@ -28,7 +28,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.ServerService = void 0;
|
|
30
30
|
const lodash_1 = require("lodash");
|
|
31
|
-
const nanoid_1 = require("nanoid");
|
|
32
31
|
const os_1 = __importDefault(require("os"));
|
|
33
32
|
const perf_hooks_1 = require("perf_hooks");
|
|
34
33
|
// @ts-ignore
|
|
@@ -38,11 +37,12 @@ const database_1 = __importStar(require("../database"));
|
|
|
38
37
|
const env_1 = __importDefault(require("../env"));
|
|
39
38
|
const logger_1 = __importDefault(require("../logger"));
|
|
40
39
|
const rate_limiter_1 = require("../middleware/rate-limiter");
|
|
41
|
-
const storage_1 =
|
|
40
|
+
const storage_1 = require("../storage");
|
|
42
41
|
const utils_1 = require("@directus/shared/utils");
|
|
43
42
|
const mailer_1 = __importDefault(require("../mailer"));
|
|
44
43
|
const settings_1 = require("./settings");
|
|
45
44
|
const get_os_info_1 = require("../utils/get-os-info");
|
|
45
|
+
const node_stream_1 = require("node:stream");
|
|
46
46
|
class ServerService {
|
|
47
47
|
constructor(options) {
|
|
48
48
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -101,7 +101,8 @@ class ServerService {
|
|
|
101
101
|
}
|
|
102
102
|
async health() {
|
|
103
103
|
var _a;
|
|
104
|
-
const
|
|
104
|
+
const { nanoid } = await import('nanoid');
|
|
105
|
+
const checkID = nanoid(5);
|
|
105
106
|
const data = {
|
|
106
107
|
status: 'ok',
|
|
107
108
|
releaseId: package_json_1.version,
|
|
@@ -246,9 +247,10 @@ class ServerService {
|
|
|
246
247
|
return checks;
|
|
247
248
|
}
|
|
248
249
|
async function testStorage() {
|
|
250
|
+
const storage = await (0, storage_1.getStorage)();
|
|
249
251
|
const checks = {};
|
|
250
252
|
for (const location of (0, utils_1.toArray)(env_1.default.STORAGE_LOCATIONS)) {
|
|
251
|
-
const disk =
|
|
253
|
+
const disk = storage.location(location);
|
|
252
254
|
const envThresholdKey = `STORAGE_${location}_HEALTHCHECK_THRESHOLD`.toUpperCase();
|
|
253
255
|
checks[`storage:${location}:responseTime`] = [
|
|
254
256
|
{
|
|
@@ -261,8 +263,8 @@ class ServerService {
|
|
|
261
263
|
];
|
|
262
264
|
const startTime = perf_hooks_1.performance.now();
|
|
263
265
|
try {
|
|
264
|
-
await disk.
|
|
265
|
-
await disk.
|
|
266
|
+
await disk.write(`health-${checkID}`, node_stream_1.Readable.from(['check']));
|
|
267
|
+
await disk.read(`health-${checkID}`);
|
|
266
268
|
await disk.delete(`health-${checkID}`);
|
|
267
269
|
}
|
|
268
270
|
catch (err) {
|
package/dist/services/shares.js
CHANGED
|
@@ -10,7 +10,6 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
|
10
10
|
const ms_1 = __importDefault(require("ms"));
|
|
11
11
|
const exceptions_1 = require("../exceptions");
|
|
12
12
|
const env_1 = __importDefault(require("../env"));
|
|
13
|
-
const nanoid_1 = require("nanoid");
|
|
14
13
|
const authorization_1 = require("./authorization");
|
|
15
14
|
const users_1 = require("./users");
|
|
16
15
|
const mail_1 = require("./mail");
|
|
@@ -32,6 +31,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
32
31
|
}
|
|
33
32
|
async login(payload) {
|
|
34
33
|
var _a, _b, _c;
|
|
34
|
+
const { nanoid } = await import('nanoid');
|
|
35
35
|
const record = await this.knex
|
|
36
36
|
.select({
|
|
37
37
|
share_id: 'id',
|
|
@@ -79,7 +79,7 @@ class SharesService extends items_1.ItemsService {
|
|
|
79
79
|
expiresIn: env_1.default.ACCESS_TOKEN_TTL,
|
|
80
80
|
issuer: 'directus',
|
|
81
81
|
});
|
|
82
|
-
const refreshToken =
|
|
82
|
+
const refreshToken = nanoid(64);
|
|
83
83
|
const refreshTokenExpiration = new Date(Date.now() + (0, ms_1.default)(env_1.default.REFRESH_TOKEN_TTL));
|
|
84
84
|
await this.knex('directus_sessions').insert({
|
|
85
85
|
token: refreshToken,
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SpecificationService = void 0;
|
|
7
|
-
const format_title_1 = __importDefault(require("@directus/format-title"));
|
|
8
7
|
const specs_1 = __importDefault(require("@directus/specs"));
|
|
9
8
|
const lodash_1 = require("lodash");
|
|
10
9
|
// @ts-ignore
|
|
@@ -16,6 +15,9 @@ const collections_1 = require("./collections");
|
|
|
16
15
|
const fields_1 = require("./fields");
|
|
17
16
|
const graphql_1 = require("./graphql");
|
|
18
17
|
const relations_1 = require("./relations");
|
|
18
|
+
const constants_1 = require("../constants");
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
const format_title_1 = __importDefault(require("@directus/format-title"));
|
|
19
21
|
class SpecificationService {
|
|
20
22
|
constructor(options) {
|
|
21
23
|
this.accountability = options.accountability || null;
|
|
@@ -330,10 +332,19 @@ class OASSpecsService {
|
|
|
330
332
|
return paths;
|
|
331
333
|
}
|
|
332
334
|
async generateComponents(collections, fields, relations, tags) {
|
|
335
|
+
var _a;
|
|
333
336
|
let components = (0, lodash_1.cloneDeep)(specs_1.default.components);
|
|
334
337
|
if (!components)
|
|
335
338
|
components = {};
|
|
336
339
|
components.schemas = {};
|
|
340
|
+
// Always includes the schemas with these names
|
|
341
|
+
if (((_a = specs_1.default.components) === null || _a === void 0 ? void 0 : _a.schemas) !== null) {
|
|
342
|
+
for (const schemaName of constants_1.OAS_REQUIRED_SCHEMAS) {
|
|
343
|
+
if (specs_1.default.components.schemas[schemaName] !== null) {
|
|
344
|
+
components.schemas[schemaName] = (0, lodash_1.cloneDeep)(specs_1.default.components.schemas[schemaName]);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
337
348
|
if (!tags)
|
|
338
349
|
return;
|
|
339
350
|
for (const collection of collections) {
|
package/dist/services/users.js
CHANGED
|
@@ -202,11 +202,17 @@ class UsersService extends items_1.ItemsService {
|
|
|
202
202
|
if (data.tfa_secret !== undefined) {
|
|
203
203
|
throw new exceptions_2.InvalidPayloadException(`You can't change the "tfa_secret" value manually.`);
|
|
204
204
|
}
|
|
205
|
-
if (data.provider !== undefined
|
|
206
|
-
|
|
205
|
+
if (data.provider !== undefined) {
|
|
206
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
207
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "provider" value manually.`);
|
|
208
|
+
}
|
|
209
|
+
data.auth_data = null;
|
|
207
210
|
}
|
|
208
|
-
if (data.external_identifier !== undefined
|
|
209
|
-
|
|
211
|
+
if (data.external_identifier !== undefined) {
|
|
212
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
213
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "external_identifier" value manually.`);
|
|
214
|
+
}
|
|
215
|
+
data.auth_data = null;
|
|
210
216
|
}
|
|
211
217
|
return await super.updateMany(keys, data, opts);
|
|
212
218
|
}
|
|
@@ -6,8 +6,6 @@ export declare class WebhooksService extends ItemsService<Webhook> {
|
|
|
6
6
|
constructor(options: AbstractServiceOptions);
|
|
7
7
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
8
8
|
createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
9
|
-
updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
10
9
|
updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
11
|
-
deleteOne(key: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
12
10
|
deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
13
11
|
}
|
|
@@ -18,21 +18,11 @@ class WebhooksService extends items_1.ItemsService {
|
|
|
18
18
|
this.messenger.publish('webhooks', { type: 'reload' });
|
|
19
19
|
return result;
|
|
20
20
|
}
|
|
21
|
-
async updateOne(key, data, opts) {
|
|
22
|
-
const result = await super.updateOne(key, data, opts);
|
|
23
|
-
this.messenger.publish('webhooks', { type: 'reload' });
|
|
24
|
-
return result;
|
|
25
|
-
}
|
|
26
21
|
async updateMany(keys, data, opts) {
|
|
27
22
|
const result = await super.updateMany(keys, data, opts);
|
|
28
23
|
this.messenger.publish('webhooks', { type: 'reload' });
|
|
29
24
|
return result;
|
|
30
25
|
}
|
|
31
|
-
async deleteOne(key, opts) {
|
|
32
|
-
const result = await super.deleteOne(key, opts);
|
|
33
|
-
this.messenger.publish('webhooks', { type: 'reload' });
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
26
|
async deleteMany(keys, opts) {
|
|
37
27
|
const result = await super.deleteMany(keys, opts);
|
|
38
28
|
this.messenger.publish('webhooks', { type: 'reload' });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStorageDriver = exports._aliasMap = void 0;
|
|
4
|
+
exports._aliasMap = {
|
|
5
|
+
local: '@directus/storage-driver-local',
|
|
6
|
+
s3: '@directus/storage-driver-s3',
|
|
7
|
+
gcs: '@directus/storage-driver-gcs',
|
|
8
|
+
azure: '@directus/storage-driver-azure',
|
|
9
|
+
cloudinary: '@directus/storage-driver-cloudinary',
|
|
10
|
+
};
|
|
11
|
+
const getStorageDriver = async (driverName) => {
|
|
12
|
+
if (driverName in exports._aliasMap) {
|
|
13
|
+
driverName = exports._aliasMap[driverName];
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
throw new Error(`Driver "${driverName}" doesn't exist.`);
|
|
17
|
+
}
|
|
18
|
+
return (await import(driverName)).default;
|
|
19
|
+
};
|
|
20
|
+
exports.getStorageDriver = getStorageDriver;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStorage = exports._cache = void 0;
|
|
4
|
+
const validate_env_1 = require("../utils/validate-env");
|
|
5
|
+
const register_drivers_1 = require("./register-drivers");
|
|
6
|
+
const register_locations_1 = require("./register-locations");
|
|
7
|
+
exports._cache = {
|
|
8
|
+
storage: null,
|
|
9
|
+
};
|
|
10
|
+
const getStorage = async () => {
|
|
11
|
+
if (exports._cache.storage)
|
|
12
|
+
return exports._cache.storage;
|
|
13
|
+
const { StorageManager } = await import('@directus/storage');
|
|
14
|
+
(0, validate_env_1.validateEnv)(['STORAGE_LOCATIONS']);
|
|
15
|
+
exports._cache.storage = new StorageManager();
|
|
16
|
+
await (0, register_drivers_1.registerDrivers)(exports._cache.storage);
|
|
17
|
+
await (0, register_locations_1.registerLocations)(exports._cache.storage);
|
|
18
|
+
return exports._cache.storage;
|
|
19
|
+
};
|
|
20
|
+
exports.getStorage = getStorage;
|