directus 9.14.0 → 9.14.3
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/cli/commands/security/key.d.ts +1 -0
- package/dist/cli/commands/security/key.js +8 -0
- package/dist/cli/commands/security/secret.d.ts +1 -0
- package/dist/cli/commands/security/secret.js +8 -0
- package/dist/cli/index.js +6 -0
- package/dist/controllers/extensions.js +9 -1
- package/dist/database/helpers/fn/dialects/mssql.d.ts +2 -2
- package/dist/database/helpers/fn/dialects/mssql.js +2 -2
- package/dist/database/helpers/fn/dialects/mysql.d.ts +2 -2
- package/dist/database/helpers/fn/dialects/mysql.js +2 -2
- package/dist/database/helpers/fn/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/oracle.js +2 -2
- package/dist/database/helpers/fn/dialects/postgres.d.ts +2 -2
- package/dist/database/helpers/fn/dialects/postgres.js +2 -2
- package/dist/database/helpers/fn/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/sqlite.js +2 -2
- package/dist/database/helpers/fn/types.d.ts +3 -2
- package/dist/database/helpers/fn/types.js +11 -8
- package/dist/database/helpers/index.d.ts +3 -3
- package/dist/database/helpers/schema/dialects/sqlite.d.ts +5 -0
- package/dist/database/helpers/schema/dialects/sqlite.js +17 -0
- package/dist/database/helpers/schema/index.d.ts +1 -1
- package/dist/database/helpers/schema/index.js +4 -4
- package/dist/database/helpers/schema/types.d.ts +2 -0
- package/dist/database/helpers/schema/types.js +6 -0
- package/dist/database/run-ast.js +8 -5
- package/dist/logger.d.ts +0 -1
- package/dist/middleware/authenticate.d.ts +0 -1
- package/dist/middleware/cache.js +3 -3
- package/dist/middleware/graphql.js +9 -7
- package/dist/middleware/respond.js +5 -5
- package/dist/operations/request/index.js +1 -1
- package/dist/services/authorization.js +15 -5
- package/dist/services/fields.js +4 -0
- package/dist/services/graphql/index.js +40 -15
- package/dist/services/server.js +13 -2
- package/dist/types/ast.d.ts +11 -4
- package/dist/utils/apply-query.js +5 -13
- package/dist/utils/apply-snapshot.js +41 -17
- package/dist/utils/filter-items.js +3 -6
- package/dist/utils/get-ast-from-query.js +18 -0
- package/dist/utils/get-column-path.d.ts +5 -1
- package/dist/utils/get-column-path.js +3 -1
- package/dist/utils/get-column.d.ts +2 -2
- package/dist/utils/get-column.js +2 -2
- package/dist/utils/get-config-from-env.js +1 -1
- package/dist/utils/merge-permissions.d.ts +0 -1
- package/package.json +231 -226
- package/dist/utils/generate-joi.d.ts +0 -3
- package/dist/utils/generate-joi.js +0 -145
|
@@ -12,6 +12,7 @@ const lodash_1 = require("lodash");
|
|
|
12
12
|
const ms_1 = __importDefault(require("ms"));
|
|
13
13
|
const cache_1 = require("../../cache");
|
|
14
14
|
const constants_1 = require("../../constants");
|
|
15
|
+
const constants_2 = require("@directus/shared/constants");
|
|
15
16
|
const database_1 = __importDefault(require("../../database"));
|
|
16
17
|
const env_1 = __importDefault(require("../../env"));
|
|
17
18
|
const exceptions_1 = require("../../exceptions");
|
|
@@ -488,6 +489,12 @@ class GraphQLService {
|
|
|
488
489
|
_nnull: {
|
|
489
490
|
type: graphql_1.GraphQLBoolean,
|
|
490
491
|
},
|
|
492
|
+
_between: {
|
|
493
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
494
|
+
},
|
|
495
|
+
_nbetween: {
|
|
496
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
497
|
+
},
|
|
491
498
|
},
|
|
492
499
|
});
|
|
493
500
|
// Uses StringOrFloat rather than Float to support api dynamic variables (like `$NOW`)
|
|
@@ -524,6 +531,12 @@ class GraphQLService {
|
|
|
524
531
|
_nnull: {
|
|
525
532
|
type: graphql_1.GraphQLBoolean,
|
|
526
533
|
},
|
|
534
|
+
_between: {
|
|
535
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
536
|
+
},
|
|
537
|
+
_nbetween: {
|
|
538
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
539
|
+
},
|
|
527
540
|
},
|
|
528
541
|
});
|
|
529
542
|
const GeometryFilterOperators = schemaComposer.createInputTC({
|
|
@@ -671,6 +684,16 @@ class GraphQLService {
|
|
|
671
684
|
return acc;
|
|
672
685
|
}, {}),
|
|
673
686
|
});
|
|
687
|
+
const countType = schemaComposer.createObjectTC({
|
|
688
|
+
name: `${collection.collection}_aggregated_count`,
|
|
689
|
+
fields: Object.values(collection.fields).reduce((acc, field) => {
|
|
690
|
+
acc[field.field] = {
|
|
691
|
+
type: graphql_1.GraphQLInt,
|
|
692
|
+
description: field.note,
|
|
693
|
+
};
|
|
694
|
+
return acc;
|
|
695
|
+
}, {}),
|
|
696
|
+
});
|
|
674
697
|
AggregateMethods[collection.collection] = {
|
|
675
698
|
group: {
|
|
676
699
|
name: 'group',
|
|
@@ -682,16 +705,11 @@ class GraphQLService {
|
|
|
682
705
|
},
|
|
683
706
|
count: {
|
|
684
707
|
name: 'count',
|
|
685
|
-
type:
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
description: field.note,
|
|
691
|
-
};
|
|
692
|
-
return acc;
|
|
693
|
-
}, {}),
|
|
694
|
-
}),
|
|
708
|
+
type: countType,
|
|
709
|
+
},
|
|
710
|
+
countDistinct: {
|
|
711
|
+
name: 'countDistinct',
|
|
712
|
+
type: countType,
|
|
695
713
|
},
|
|
696
714
|
};
|
|
697
715
|
const hasNumericAggregates = Object.values(collection.fields).some((field) => {
|
|
@@ -711,10 +729,6 @@ class GraphQLService {
|
|
|
711
729
|
name: 'sum',
|
|
712
730
|
type: AggregatedFields[collection.collection],
|
|
713
731
|
},
|
|
714
|
-
countDistinct: {
|
|
715
|
-
name: 'countDistinct',
|
|
716
|
-
type: AggregatedFields[collection.collection],
|
|
717
|
-
},
|
|
718
732
|
avgDistinct: {
|
|
719
733
|
name: 'avgDistinct',
|
|
720
734
|
type: AggregatedFields[collection.collection],
|
|
@@ -1042,6 +1056,17 @@ class GraphQLService {
|
|
|
1042
1056
|
};
|
|
1043
1057
|
query.limit = 1;
|
|
1044
1058
|
}
|
|
1059
|
+
// Transform count(a.b.c) into a.b.count(c)
|
|
1060
|
+
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
|
|
1061
|
+
if (query.fields[fieldIndex].includes('(') && query.fields[fieldIndex].includes(')')) {
|
|
1062
|
+
const functionName = query.fields[fieldIndex].split('(')[0];
|
|
1063
|
+
const columnNames = query.fields[fieldIndex].match(constants_2.REGEX_BETWEEN_PARENS)[1].split('.');
|
|
1064
|
+
if (columnNames.length > 1) {
|
|
1065
|
+
const column = columnNames.pop();
|
|
1066
|
+
query.fields[fieldIndex] = columnNames.join('.') + '.' + functionName + '(' + column + ')';
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1045
1070
|
const result = await this.read(collection, query);
|
|
1046
1071
|
if (args.id) {
|
|
1047
1072
|
return (result === null || result === void 0 ? void 0 : result[0]) || null;
|
|
@@ -1288,7 +1313,7 @@ class GraphQLService {
|
|
|
1288
1313
|
result[currentKey] = Object.values(value)[0];
|
|
1289
1314
|
}
|
|
1290
1315
|
else {
|
|
1291
|
-
result[currentKey] = (0
|
|
1316
|
+
result[currentKey] = (value === null || value === void 0 ? void 0 : value.constructor) === Object ? replaceFuncDeep(value) : value;
|
|
1292
1317
|
}
|
|
1293
1318
|
});
|
|
1294
1319
|
}
|
package/dist/services/server.js
CHANGED
|
@@ -51,7 +51,7 @@ class ServerService {
|
|
|
51
51
|
this.settingsService = new settings_1.SettingsService({ knex: this.knex, schema: this.schema });
|
|
52
52
|
}
|
|
53
53
|
async serverInfo() {
|
|
54
|
-
var _a;
|
|
54
|
+
var _a, _b;
|
|
55
55
|
const info = {};
|
|
56
56
|
const projectInfo = await this.settingsService.readSingleton({
|
|
57
57
|
fields: [
|
|
@@ -67,7 +67,18 @@ class ServerService {
|
|
|
67
67
|
],
|
|
68
68
|
});
|
|
69
69
|
info.project = projectInfo;
|
|
70
|
-
if ((
|
|
70
|
+
if ((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.user) {
|
|
71
|
+
if (env_1.default.RATE_LIMITER_ENABLED) {
|
|
72
|
+
info.rateLimit = {
|
|
73
|
+
points: env_1.default.RATE_LIMITER_POINTS,
|
|
74
|
+
duration: env_1.default.RATE_LIMITER_DURATION,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
info.rateLimit = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (((_b = this.accountability) === null || _b === void 0 ? void 0 : _b.admin) === true) {
|
|
71
82
|
const osType = os_1.default.type() === 'Darwin' ? 'macOS' : os_1.default.type();
|
|
72
83
|
const osVersion = osType === 'macOS' ? `${(0, macos_release_1.default)().name} (${(0, macos_release_1.default)().version})` : os_1.default.release();
|
|
73
84
|
info.directus = {
|
package/dist/types/ast.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Query, Relation } from '@directus/shared/types';
|
|
|
2
2
|
export declare type M2ONode = {
|
|
3
3
|
type: 'm2o';
|
|
4
4
|
name: string;
|
|
5
|
-
children: (NestedCollectionNode | FieldNode)[];
|
|
5
|
+
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
6
6
|
query: Query;
|
|
7
7
|
fieldKey: string;
|
|
8
8
|
relation: Relation;
|
|
@@ -13,7 +13,7 @@ export declare type A2MNode = {
|
|
|
13
13
|
type: 'a2o';
|
|
14
14
|
names: string[];
|
|
15
15
|
children: {
|
|
16
|
-
[collection: string]: (NestedCollectionNode | FieldNode)[];
|
|
16
|
+
[collection: string]: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
17
17
|
};
|
|
18
18
|
query: {
|
|
19
19
|
[collection: string]: Query;
|
|
@@ -28,7 +28,7 @@ export declare type A2MNode = {
|
|
|
28
28
|
export declare type O2MNode = {
|
|
29
29
|
type: 'o2m';
|
|
30
30
|
name: string;
|
|
31
|
-
children: (NestedCollectionNode | FieldNode)[];
|
|
31
|
+
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
32
32
|
query: Query;
|
|
33
33
|
fieldKey: string;
|
|
34
34
|
relation: Relation;
|
|
@@ -41,9 +41,16 @@ export declare type FieldNode = {
|
|
|
41
41
|
name: string;
|
|
42
42
|
fieldKey: string;
|
|
43
43
|
};
|
|
44
|
+
export declare type FunctionFieldNode = {
|
|
45
|
+
type: 'functionField';
|
|
46
|
+
name: string;
|
|
47
|
+
fieldKey: string;
|
|
48
|
+
query: Query;
|
|
49
|
+
relatedCollection: string;
|
|
50
|
+
};
|
|
44
51
|
export declare type AST = {
|
|
45
52
|
type: 'root';
|
|
46
53
|
name: string;
|
|
47
|
-
children: (NestedCollectionNode | FieldNode)[];
|
|
54
|
+
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
48
55
|
query: Query;
|
|
49
56
|
};
|
|
@@ -129,8 +129,8 @@ function applySort(knex, schema, rootQuery, rootSort, collection, subQuery = fal
|
|
|
129
129
|
relations,
|
|
130
130
|
knex,
|
|
131
131
|
});
|
|
132
|
-
const
|
|
133
|
-
const [alias, field] =
|
|
132
|
+
const { columnPath } = (0, get_column_path_1.getColumnPath)({ path: column, collection, aliasMap, relations });
|
|
133
|
+
const [alias, field] = columnPath.split('.');
|
|
134
134
|
return {
|
|
135
135
|
order,
|
|
136
136
|
column: (0, get_column_1.getColumn)(knex, alias, field, false, schema),
|
|
@@ -208,18 +208,10 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
208
208
|
const { operator: filterOperator, value: filterValue } = getOperation(key, value);
|
|
209
209
|
if (relationType === 'm2o' || relationType === 'a2o' || relationType === null) {
|
|
210
210
|
if (filterPath.length > 1) {
|
|
211
|
-
const
|
|
212
|
-
if (!
|
|
211
|
+
const { columnPath, targetCollection } = (0, get_column_path_1.getColumnPath)({ path: filterPath, collection, relations, aliasMap });
|
|
212
|
+
if (!columnPath)
|
|
213
213
|
continue;
|
|
214
|
-
|
|
215
|
-
applyFilterToQuery(columnName, filterOperator, filterValue, logical, relation.related_collection); // m2o
|
|
216
|
-
}
|
|
217
|
-
else if (filterPath[0].includes(':')) {
|
|
218
|
-
applyFilterToQuery(columnName, filterOperator, filterValue, logical, filterPath[0].split(':')[1]); // a2o
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
applyFilterToQuery(columnName, filterOperator, filterValue, logical);
|
|
222
|
-
}
|
|
214
|
+
applyFilterToQuery(columnPath, filterOperator, filterValue, logical, targetCollection);
|
|
223
215
|
}
|
|
224
216
|
else {
|
|
225
217
|
applyFilterToQuery(`${collection}.${filterPath[0]}`, filterOperator, filterValue, logical);
|
|
@@ -32,23 +32,18 @@ async function applySnapshot(snapshot, options) {
|
|
|
32
32
|
.filter((fieldDiff) => fieldDiff.collection === collection)
|
|
33
33
|
.map((fieldDiff) => fieldDiff.diff[0].rhs)
|
|
34
34
|
.map((fieldDiff) => {
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
if (
|
|
39
|
-
fieldDiff.schema.
|
|
40
|
-
fieldDiff.schema
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return fieldDiff;
|
|
35
|
+
var _a, _b, _c, _d, _e;
|
|
36
|
+
// Casts field type to UUID when applying non-PostgreSQL schema onto PostgreSQL database.
|
|
37
|
+
// This is needed because they snapshots UUID fields as char with length 36.
|
|
38
|
+
if (((_a = fieldDiff.schema) === null || _a === void 0 ? void 0 : _a.data_type) === 'char' &&
|
|
39
|
+
((_b = fieldDiff.schema) === null || _b === void 0 ? void 0 : _b.max_length) === 36 &&
|
|
40
|
+
(((_c = fieldDiff.schema) === null || _c === void 0 ? void 0 : _c.is_primary_key) ||
|
|
41
|
+
(((_d = fieldDiff.schema) === null || _d === void 0 ? void 0 : _d.foreign_key_table) && ((_e = fieldDiff.schema) === null || _e === void 0 ? void 0 : _e.foreign_key_column)))) {
|
|
42
|
+
return (0, lodash_1.merge)(fieldDiff, { type: 'uuid', schema: { data_type: 'uuid', max_length: null } });
|
|
44
43
|
}
|
|
45
|
-
|
|
46
|
-
if (!matchingForeignKeyTable)
|
|
47
|
-
return fieldDiff;
|
|
48
|
-
const matchingForeignKeyField = matchingForeignKeyTable.fields[fieldDiff.schema.foreign_key_column];
|
|
49
|
-
if (!matchingForeignKeyField || matchingForeignKeyField.type !== 'uuid')
|
|
44
|
+
else {
|
|
50
45
|
return fieldDiff;
|
|
51
|
-
|
|
46
|
+
}
|
|
52
47
|
});
|
|
53
48
|
try {
|
|
54
49
|
await collectionsService.createOne({
|
|
@@ -80,8 +75,37 @@ async function applySnapshot(snapshot, options) {
|
|
|
80
75
|
}
|
|
81
76
|
}
|
|
82
77
|
};
|
|
83
|
-
//
|
|
84
|
-
|
|
78
|
+
// Finds all collections that need to be created
|
|
79
|
+
const filterCollectionsForCreation = ({ diff }) => {
|
|
80
|
+
var _a;
|
|
81
|
+
// Check new collections only
|
|
82
|
+
const isNewCollection = diff[0].kind === 'N';
|
|
83
|
+
if (!isNewCollection)
|
|
84
|
+
return false;
|
|
85
|
+
// Create now if no group
|
|
86
|
+
const groupName = (_a = diff[0].rhs.meta) === null || _a === void 0 ? void 0 : _a.group;
|
|
87
|
+
if (!groupName)
|
|
88
|
+
return true;
|
|
89
|
+
// Check if parent collection already exists in schema
|
|
90
|
+
const parentExists = current.collections.find((c) => c.collection === groupName) !== undefined;
|
|
91
|
+
// If this is a new collection and the parent collection doesn't exist in current schema ->
|
|
92
|
+
// Check if the parent collection will be created as part of applying this snapshot ->
|
|
93
|
+
// If yes -> this collection will be created recursively
|
|
94
|
+
// If not -> create now
|
|
95
|
+
// (ex.)
|
|
96
|
+
// TopLevelCollection - I exist in current schema
|
|
97
|
+
// NestedCollection - I exist in snapshotDiff as a new collection
|
|
98
|
+
// TheCurrentCollectionInIteration - I exist in snapshotDiff as a new collection but will be created as part of NestedCollection
|
|
99
|
+
const parentWillBeCreatedInThisApply = snapshotDiff.collections.filter(({ collection, diff }) => diff[0].kind === 'N' && collection === groupName)
|
|
100
|
+
.length > 0;
|
|
101
|
+
// Has group, but parent is not new, parent is also not being created in this snapshot apply
|
|
102
|
+
if (parentExists && !parentWillBeCreatedInThisApply)
|
|
103
|
+
return true;
|
|
104
|
+
return false;
|
|
105
|
+
};
|
|
106
|
+
// Create top level collections (no group, or highest level in existing group) first,
|
|
107
|
+
// then continue with nested collections recursively
|
|
108
|
+
await createCollections(snapshotDiff.collections.filter(filterCollectionsForCreation));
|
|
85
109
|
// delete top level collections (no group) first, then continue with nested collections recursively
|
|
86
110
|
await deleteCollections(snapshotDiff.collections.filter(({ diff }) => { var _a; return diff[0].kind === 'D' && ((_a = diff[0].lhs.meta) === null || _a === void 0 ? void 0 : _a.group) === null; }));
|
|
87
111
|
for (const { collection, diff } of snapshotDiff.collections) {
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.filterItems = void 0;
|
|
7
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
8
5
|
/*
|
|
9
6
|
Note: Filtering is normally done through SQL in run-ast. This function can be used in case an already
|
|
10
7
|
existing array of items has to be filtered using the same filter syntax as used in the ast-to-sql flow
|
|
@@ -16,7 +13,7 @@ function filterItems(items, filter) {
|
|
|
16
13
|
return passesFilter(item, filter);
|
|
17
14
|
});
|
|
18
15
|
function passesFilter(item, filter) {
|
|
19
|
-
if (!filter)
|
|
16
|
+
if (!filter || Object.keys(filter).length === 0)
|
|
20
17
|
return true;
|
|
21
18
|
if (Object.keys(filter)[0] === '_and') {
|
|
22
19
|
const subfilter = Object.values(filter)[0];
|
|
@@ -31,7 +28,7 @@ function filterItems(items, filter) {
|
|
|
31
28
|
});
|
|
32
29
|
}
|
|
33
30
|
else {
|
|
34
|
-
const schema = (0,
|
|
31
|
+
const schema = (0, utils_1.generateJoi)(filter);
|
|
35
32
|
const { error } = schema.validate(item);
|
|
36
33
|
return error === undefined;
|
|
37
34
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const lodash_1 = require("lodash");
|
|
7
7
|
const get_relation_type_1 = require("../utils/get-relation-type");
|
|
8
|
+
const constants_1 = require("@directus/shared/constants");
|
|
8
9
|
async function getASTFromQuery(collection, query, schema, options) {
|
|
9
10
|
var _a, _b, _c, _d, _e;
|
|
10
11
|
query = (0, lodash_1.cloneDeep)(query);
|
|
@@ -118,6 +119,23 @@ async function getASTFromQuery(collection, query, schema, options) {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
else {
|
|
122
|
+
if (fieldKey.includes('(') && fieldKey.includes(')')) {
|
|
123
|
+
const columnName = fieldKey.match(constants_1.REGEX_BETWEEN_PARENS)[1];
|
|
124
|
+
const foundField = schema.collections[parentCollection].fields[columnName];
|
|
125
|
+
if (foundField && foundField.type === 'alias') {
|
|
126
|
+
const foundRelation = schema.relations.find((relation) => { var _a; return relation.related_collection === parentCollection && ((_a = relation.meta) === null || _a === void 0 ? void 0 : _a.one_field) === columnName; });
|
|
127
|
+
if (foundRelation) {
|
|
128
|
+
children.push({
|
|
129
|
+
type: 'functionField',
|
|
130
|
+
name,
|
|
131
|
+
fieldKey,
|
|
132
|
+
query: {},
|
|
133
|
+
relatedCollection: foundRelation.collection,
|
|
134
|
+
});
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
121
139
|
children.push({ type: 'field', name, fieldKey });
|
|
122
140
|
}
|
|
123
141
|
}
|
|
@@ -11,6 +11,10 @@ export declare type ColPathProps = {
|
|
|
11
11
|
/**
|
|
12
12
|
* Converts a Directus field list path to the correct SQL names based on the constructed alias map.
|
|
13
13
|
* For example: ['author', 'role', 'name'] -> 'ljnsv.name'
|
|
14
|
+
* Also returns the target collection of the column: 'directus_roles'
|
|
14
15
|
*/
|
|
15
|
-
export declare function getColumnPath({ path, collection, aliasMap, relations }: ColPathProps):
|
|
16
|
+
export declare function getColumnPath({ path, collection, aliasMap, relations }: ColPathProps): {
|
|
17
|
+
columnPath: string;
|
|
18
|
+
targetCollection: string;
|
|
19
|
+
};
|
|
16
20
|
export {};
|
|
@@ -7,6 +7,7 @@ const lodash_1 = require("lodash");
|
|
|
7
7
|
/**
|
|
8
8
|
* Converts a Directus field list path to the correct SQL names based on the constructed alias map.
|
|
9
9
|
* For example: ['author', 'role', 'name'] -> 'ljnsv.name'
|
|
10
|
+
* Also returns the target collection of the column: 'directus_roles'
|
|
10
11
|
*/
|
|
11
12
|
function getColumnPath({ path, collection, aliasMap, relations }) {
|
|
12
13
|
return followRelation(path);
|
|
@@ -36,11 +37,12 @@ function getColumnPath({ path, collection, aliasMap, relations }) {
|
|
|
36
37
|
parent = relation.collection;
|
|
37
38
|
}
|
|
38
39
|
if (remainingParts.length === 1) {
|
|
39
|
-
return `${alias || parent}.${remainingParts[0]}
|
|
40
|
+
return { columnPath: `${alias || parent}.${remainingParts[0]}`, targetCollection: parent };
|
|
40
41
|
}
|
|
41
42
|
if (remainingParts.length) {
|
|
42
43
|
return followRelation(remainingParts, parent, alias);
|
|
43
44
|
}
|
|
45
|
+
return { columnPath: '', targetCollection: '' };
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
exports.getColumnPath = getColumnPath;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SchemaOverview } from '@directus/shared/types';
|
|
1
|
+
import { Query, SchemaOverview } from '@directus/shared/types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
3
|
/**
|
|
4
4
|
* Return column prefixed by table. If column includes functions (like `year(date_created)`), the
|
|
@@ -10,4 +10,4 @@ import { Knex } from 'knex';
|
|
|
10
10
|
* @param alias Whether or not to add a SQL AS statement
|
|
11
11
|
* @returns Knex raw instance
|
|
12
12
|
*/
|
|
13
|
-
export declare function getColumn(knex: Knex, table: string, column: string, alias: string | false | undefined, schema: SchemaOverview): Knex.Raw;
|
|
13
|
+
export declare function getColumn(knex: Knex, table: string, column: string, alias: string | false | undefined, schema: SchemaOverview, query?: Query): Knex.Raw;
|
package/dist/utils/get-column.js
CHANGED
|
@@ -16,7 +16,7 @@ const apply_function_to_column_name_1 = require("./apply-function-to-column-name
|
|
|
16
16
|
* @param alias Whether or not to add a SQL AS statement
|
|
17
17
|
* @returns Knex raw instance
|
|
18
18
|
*/
|
|
19
|
-
function getColumn(knex, table, column, alias = (0, apply_function_to_column_name_1.applyFunctionToColumnName)(column), schema) {
|
|
19
|
+
function getColumn(knex, table, column, alias = (0, apply_function_to_column_name_1.applyFunctionToColumnName)(column), schema, query) {
|
|
20
20
|
var _a, _b, _c, _d;
|
|
21
21
|
const fn = (0, helpers_1.getFunctions)(knex, schema);
|
|
22
22
|
if (column.includes('(') && column.includes(')')) {
|
|
@@ -28,7 +28,7 @@ function getColumn(knex, table, column, alias = (0, apply_function_to_column_nam
|
|
|
28
28
|
if (allowedFunctions.includes(functionName) === false) {
|
|
29
29
|
throw new exceptions_1.InvalidQueryException(`Invalid function specified "${functionName}"`);
|
|
30
30
|
}
|
|
31
|
-
const result = fn[functionName](table, columnName, { type });
|
|
31
|
+
const result = fn[functionName](table, columnName, { type, query });
|
|
32
32
|
if (alias) {
|
|
33
33
|
return knex.raw(result + ' AS ??', [alias]);
|
|
34
34
|
}
|
|
@@ -36,7 +36,7 @@ function getConfigFromEnv(prefix, omitPrefix, type = 'camelcase') {
|
|
|
36
36
|
return config;
|
|
37
37
|
function transform(key) {
|
|
38
38
|
if (type === 'camelcase') {
|
|
39
|
-
return (0, camelcase_1.default)(key);
|
|
39
|
+
return (0, camelcase_1.default)(key, { locale: false });
|
|
40
40
|
}
|
|
41
41
|
else if (type === 'underscore') {
|
|
42
42
|
return key.toLowerCase();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="lodash" />
|
|
2
1
|
import { Permission } from '@directus/shared/types';
|
|
3
2
|
export declare function mergePermissions(strategy: 'and' | 'or', ...permissions: Permission[][]): Permission[];
|
|
4
3
|
export declare function mergePermission(strategy: 'and' | 'or', currentPerm: Permission, newPerm: Permission): import("lodash").Omit<{
|