@directus/api 22.1.0 → 22.1.1
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/database/get-ast-from-query/get-ast-from-query.js +2 -31
- package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +2 -1
- package/dist/database/get-ast-from-query/lib/parse-fields.js +21 -3
- package/dist/database/get-ast-from-query/utils/get-allowed-sort.d.ts +9 -0
- package/dist/database/get-ast-from-query/utils/get-allowed-sort.js +35 -0
- package/dist/database/helpers/fn/types.d.ts +6 -3
- package/dist/database/helpers/fn/types.js +2 -2
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/migrations/20240806A-permissions-policies.js +3 -2
- package/dist/database/run-ast/lib/get-db-query.d.ts +2 -2
- package/dist/database/run-ast/lib/get-db-query.js +9 -5
- package/dist/database/run-ast/run-ast.d.ts +2 -2
- package/dist/database/run-ast/run-ast.js +14 -7
- package/dist/database/run-ast/utils/apply-case-when.d.ts +3 -2
- package/dist/database/run-ast/utils/apply-case-when.js +2 -2
- package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +2 -2
- package/dist/database/run-ast/utils/get-column-pre-processor.js +3 -1
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +2 -2
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +2 -1
- package/dist/permissions/lib/fetch-permissions.d.ts +2 -3
- package/dist/permissions/lib/fetch-permissions.js +5 -39
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +1 -2
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +1 -13
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +1 -2
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +1 -6
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +1 -2
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +1 -7
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +1 -2
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +2 -7
- package/dist/permissions/modules/process-ast/lib/get-cases.d.ts +6 -0
- package/dist/permissions/modules/process-ast/lib/get-cases.js +40 -0
- package/dist/permissions/modules/process-ast/lib/inject-cases.js +1 -40
- package/dist/permissions/modules/process-payload/process-payload.js +4 -5
- package/dist/permissions/modules/validate-access/lib/validate-item-access.js +7 -6
- package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +1 -2
- package/dist/permissions/utils/fetch-dynamic-variable-context.js +44 -24
- package/dist/permissions/utils/fetch-raw-permissions.d.ts +11 -0
- package/dist/permissions/utils/fetch-raw-permissions.js +39 -0
- package/dist/services/fields.d.ts +1 -1
- package/dist/services/fields.js +22 -19
- package/dist/services/import-export.js +2 -2
- package/dist/services/items.js +1 -1
- package/dist/services/meta.js +8 -7
- package/dist/services/permissions.js +19 -19
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +25 -20
- package/dist/utils/get-column.d.ts +8 -4
- package/dist/utils/get-column.js +10 -2
- package/dist/utils/sanitize-query.js +1 -1
- package/package.json +15 -14
|
@@ -5,6 +5,7 @@ import { clone, isPlainObject } from 'lodash-es';
|
|
|
5
5
|
import { customAlphabet } from 'nanoid/non-secure';
|
|
6
6
|
import { getHelpers } from '../database/helpers/index.js';
|
|
7
7
|
import { applyCaseWhen } from '../database/run-ast/utils/apply-case-when.js';
|
|
8
|
+
import { getCases } from '../permissions/modules/process-ast/lib/get-cases.js';
|
|
8
9
|
import { getColumnPath } from './get-column-path.js';
|
|
9
10
|
import { getColumn } from './get-column.js';
|
|
10
11
|
import { getRelationInfo } from './get-relation-info.js';
|
|
@@ -15,7 +16,7 @@ export const generateAlias = customAlphabet('abcdefghijklmnopqrstuvwxyz', 5);
|
|
|
15
16
|
/**
|
|
16
17
|
* Apply the Query to a given Knex query builder instance
|
|
17
18
|
*/
|
|
18
|
-
export default function applyQuery(knex, collection, dbQuery, query, schema, cases, options) {
|
|
19
|
+
export default function applyQuery(knex, collection, dbQuery, query, schema, cases, permissions, options) {
|
|
19
20
|
const aliasMap = options?.aliasMap ?? Object.create(null);
|
|
20
21
|
let hasJoins = false;
|
|
21
22
|
let hasMultiRelationalFilter = false;
|
|
@@ -42,7 +43,7 @@ export default function applyQuery(knex, collection, dbQuery, query, schema, cas
|
|
|
42
43
|
// you're actually allowed to read
|
|
43
44
|
const filter = joinFilterWithCases(query.filter, cases);
|
|
44
45
|
if (filter) {
|
|
45
|
-
const filterResult = applyFilter(knex, schema, dbQuery, filter, collection, aliasMap, cases);
|
|
46
|
+
const filterResult = applyFilter(knex, schema, dbQuery, filter, collection, aliasMap, cases, permissions);
|
|
46
47
|
if (!hasJoins) {
|
|
47
48
|
hasJoins = filterResult.hasJoins;
|
|
48
49
|
}
|
|
@@ -58,6 +59,7 @@ export default function applyQuery(knex, collection, dbQuery, query, schema, cas
|
|
|
58
59
|
aliasMap,
|
|
59
60
|
cases,
|
|
60
61
|
table: collection,
|
|
62
|
+
permissions,
|
|
61
63
|
}, {
|
|
62
64
|
knex,
|
|
63
65
|
schema,
|
|
@@ -261,7 +263,7 @@ export function applyOffset(knex, rootQuery, offset) {
|
|
|
261
263
|
getHelpers(knex).schema.applyOffset(rootQuery, offset);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
|
-
export function applyFilter(knex, schema, rootQuery, rootFilter, collection, aliasMap, cases) {
|
|
266
|
+
export function applyFilter(knex, schema, rootQuery, rootFilter, collection, aliasMap, cases, permissions) {
|
|
265
267
|
const helpers = getHelpers(knex);
|
|
266
268
|
const relations = schema.relations;
|
|
267
269
|
let hasJoins = false;
|
|
@@ -349,24 +351,27 @@ export function applyFilter(knex, schema, rootQuery, rootFilter, collection, ali
|
|
|
349
351
|
if (relationType === 'o2a') {
|
|
350
352
|
pkField = knex.raw(getHelpers(knex).schema.castA2oPrimaryKey(), [pkField]);
|
|
351
353
|
}
|
|
352
|
-
const subQueryBuilder = (filter) => (subQueryKnex) => {
|
|
353
|
-
const field = relation.field;
|
|
354
|
-
const collection = relation.collection;
|
|
355
|
-
const column = `${collection}.${field}`;
|
|
356
|
-
subQueryKnex
|
|
357
|
-
.select({ [field]: column })
|
|
358
|
-
.from(collection)
|
|
359
|
-
.whereNotNull(column);
|
|
360
|
-
applyQuery(knex, relation.collection, subQueryKnex, { filter }, schema, cases);
|
|
361
|
-
};
|
|
362
354
|
const childKey = Object.keys(value)?.[0];
|
|
363
|
-
if (childKey === '_none') {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
355
|
+
if (childKey === '_none' || childKey === '_some') {
|
|
356
|
+
const subQueryBuilder = (filter, cases) => (subQueryKnex) => {
|
|
357
|
+
const field = relation.field;
|
|
358
|
+
const collection = relation.collection;
|
|
359
|
+
const column = `${collection}.${field}`;
|
|
360
|
+
subQueryKnex
|
|
361
|
+
.select({ [field]: column })
|
|
362
|
+
.from(collection)
|
|
363
|
+
.whereNotNull(column);
|
|
364
|
+
applyQuery(knex, relation.collection, subQueryKnex, { filter }, schema, cases, permissions);
|
|
365
|
+
};
|
|
366
|
+
const { cases: subCases } = getCases(relation.collection, permissions, []);
|
|
367
|
+
if (childKey === '_none') {
|
|
368
|
+
dbQuery[logical].whereNotIn(pkField, subQueryBuilder(Object.values(value)[0], subCases));
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
else if (childKey === '_some') {
|
|
372
|
+
dbQuery[logical].whereIn(pkField, subQueryBuilder(Object.values(value)[0], subCases));
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
370
375
|
}
|
|
371
376
|
}
|
|
372
377
|
if (filterPath.includes('_none') || filterPath.includes('_some')) {
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import type { Filter, Query, SchemaOverview } from '@directus/types';
|
|
1
|
+
import type { Filter, Permission, Query, SchemaOverview } from '@directus/types';
|
|
2
2
|
import type { Knex } from 'knex';
|
|
3
|
-
type
|
|
4
|
-
query
|
|
5
|
-
cases
|
|
3
|
+
type FunctionColumnOptions = {
|
|
4
|
+
query: Query;
|
|
5
|
+
cases: Filter[];
|
|
6
|
+
permissions: Permission[];
|
|
7
|
+
};
|
|
8
|
+
type OriginalCollectionName = {
|
|
6
9
|
originalCollectionName?: string | undefined;
|
|
7
10
|
};
|
|
11
|
+
type GetColumnOptions = OriginalCollectionName | (FunctionColumnOptions & OriginalCollectionName);
|
|
8
12
|
/**
|
|
9
13
|
* Return column prefixed by table. If column includes functions (like `year(date_created)`), the
|
|
10
14
|
* column is replaced with the appropriate SQL
|
package/dist/utils/get-column.js
CHANGED
|
@@ -29,8 +29,13 @@ export function getColumn(knex, table, column, alias = applyFunctionToColumnName
|
|
|
29
29
|
}
|
|
30
30
|
const result = fn[functionName](table, columnName, {
|
|
31
31
|
type,
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
relationalCountOptions: isFunctionColumnOptions(options)
|
|
33
|
+
? {
|
|
34
|
+
query: options.query,
|
|
35
|
+
cases: options.cases,
|
|
36
|
+
permissions: options.permissions,
|
|
37
|
+
}
|
|
38
|
+
: undefined,
|
|
34
39
|
originalCollectionName: options?.originalCollectionName,
|
|
35
40
|
});
|
|
36
41
|
if (alias) {
|
|
@@ -47,3 +52,6 @@ export function getColumn(knex, table, column, alias = applyFunctionToColumnName
|
|
|
47
52
|
}
|
|
48
53
|
return knex.ref(`${table}.${column}`);
|
|
49
54
|
}
|
|
55
|
+
function isFunctionColumnOptions(options) {
|
|
56
|
+
return !!options && 'query' in options;
|
|
57
|
+
}
|
|
@@ -95,7 +95,7 @@ function sanitizeAggregate(rawAggregate) {
|
|
|
95
95
|
aggregate = parseJSON(rawAggregate);
|
|
96
96
|
}
|
|
97
97
|
catch {
|
|
98
|
-
logger.warn('Invalid value passed for
|
|
98
|
+
logger.warn('Invalid value passed for aggregate query parameter.');
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
for (const [operation, fields] of Object.entries(aggregate)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/api",
|
|
3
|
-
"version": "22.1.
|
|
3
|
+
"version": "22.1.1",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"graphql-ws": "5.16.0",
|
|
100
100
|
"helmet": "7.1.0",
|
|
101
101
|
"icc": "3.0.0",
|
|
102
|
-
"inquirer": "9.3.
|
|
102
|
+
"inquirer": "9.3.6",
|
|
103
103
|
"ioredis": "5.4.1",
|
|
104
104
|
"ip-matching": "2.1.2",
|
|
105
105
|
"isolated-vm": "4.7.2",
|
|
@@ -143,35 +143,35 @@
|
|
|
143
143
|
"sharp": "0.33.4",
|
|
144
144
|
"snappy": "7.2.2",
|
|
145
145
|
"stream-json": "1.8.0",
|
|
146
|
-
"tar": "7.4.
|
|
146
|
+
"tar": "7.4.3",
|
|
147
147
|
"tsx": "4.16.5",
|
|
148
148
|
"wellknown": "0.5.0",
|
|
149
149
|
"ws": "8.18.0",
|
|
150
150
|
"zod": "3.23.8",
|
|
151
151
|
"zod-validation-error": "3.3.1",
|
|
152
|
-
"@directus/app": "13.0
|
|
153
|
-
"@directus/constants": "12.0.0",
|
|
154
|
-
"@directus/env": "3.0.0",
|
|
152
|
+
"@directus/app": "13.1.0",
|
|
155
153
|
"@directus/errors": "1.0.0",
|
|
156
|
-
"@directus/
|
|
154
|
+
"@directus/env": "3.0.0",
|
|
155
|
+
"@directus/constants": "12.0.0",
|
|
157
156
|
"@directus/extensions-registry": "2.0.0",
|
|
157
|
+
"@directus/extensions": "2.0.0",
|
|
158
|
+
"@directus/extensions-sdk": "12.0.1",
|
|
158
159
|
"@directus/format-title": "11.0.0",
|
|
159
160
|
"@directus/memory": "2.0.0",
|
|
160
|
-
"@directus/pressure": "2.0.0",
|
|
161
161
|
"@directus/schema": "12.0.0",
|
|
162
|
-
"@directus/
|
|
162
|
+
"@directus/pressure": "2.0.0",
|
|
163
163
|
"@directus/specs": "11.0.0",
|
|
164
|
-
"@directus/storage-driver-azure": "11.0.0",
|
|
165
164
|
"@directus/storage": "11.0.0",
|
|
165
|
+
"@directus/storage-driver-azure": "11.0.0",
|
|
166
166
|
"@directus/storage-driver-cloudinary": "11.0.0",
|
|
167
167
|
"@directus/storage-driver-gcs": "11.0.0",
|
|
168
|
+
"@directus/storage-driver-s3": "11.0.0",
|
|
168
169
|
"@directus/storage-driver-local": "11.0.0",
|
|
169
170
|
"@directus/storage-driver-supabase": "2.0.0",
|
|
170
171
|
"@directus/system-data": "2.0.0",
|
|
171
|
-
"@directus/
|
|
172
|
+
"@directus/utils": "12.0.0",
|
|
172
173
|
"@directus/validation": "1.0.0",
|
|
173
|
-
"directus": "11.0.
|
|
174
|
-
"@directus/utils": "12.0.0"
|
|
174
|
+
"directus": "11.0.2"
|
|
175
175
|
},
|
|
176
176
|
"devDependencies": {
|
|
177
177
|
"@ngneat/falso": "7.2.0",
|
|
@@ -209,11 +209,12 @@
|
|
|
209
209
|
"@vitest/coverage-v8": "1.5.3",
|
|
210
210
|
"copyfiles": "2.4.1",
|
|
211
211
|
"form-data": "4.0.0",
|
|
212
|
+
"get-port": "7.1.0",
|
|
212
213
|
"knex-mock-client": "2.0.1",
|
|
213
214
|
"typescript": "5.4.5",
|
|
214
215
|
"vitest": "1.5.3",
|
|
215
|
-
"@directus/random": "1.0.0",
|
|
216
216
|
"@directus/tsconfig": "2.0.0",
|
|
217
|
+
"@directus/random": "1.0.0",
|
|
217
218
|
"@directus/types": "12.0.0"
|
|
218
219
|
},
|
|
219
220
|
"optionalDependencies": {
|