@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.
Files changed (51) hide show
  1. package/dist/database/get-ast-from-query/get-ast-from-query.js +2 -31
  2. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +2 -1
  3. package/dist/database/get-ast-from-query/lib/parse-fields.js +21 -3
  4. package/dist/database/get-ast-from-query/utils/get-allowed-sort.d.ts +9 -0
  5. package/dist/database/get-ast-from-query/utils/get-allowed-sort.js +35 -0
  6. package/dist/database/helpers/fn/types.d.ts +6 -3
  7. package/dist/database/helpers/fn/types.js +2 -2
  8. package/dist/database/index.d.ts +1 -1
  9. package/dist/database/index.js +2 -2
  10. package/dist/database/migrations/20240806A-permissions-policies.js +3 -2
  11. package/dist/database/run-ast/lib/get-db-query.d.ts +2 -2
  12. package/dist/database/run-ast/lib/get-db-query.js +9 -5
  13. package/dist/database/run-ast/run-ast.d.ts +2 -2
  14. package/dist/database/run-ast/run-ast.js +14 -7
  15. package/dist/database/run-ast/utils/apply-case-when.d.ts +3 -2
  16. package/dist/database/run-ast/utils/apply-case-when.js +2 -2
  17. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +2 -2
  18. package/dist/database/run-ast/utils/get-column-pre-processor.js +3 -1
  19. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +2 -2
  20. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +2 -1
  21. package/dist/permissions/lib/fetch-permissions.d.ts +2 -3
  22. package/dist/permissions/lib/fetch-permissions.js +5 -39
  23. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +1 -2
  24. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +1 -13
  25. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +1 -2
  26. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +1 -6
  27. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +1 -2
  28. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +1 -7
  29. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +1 -2
  30. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +2 -7
  31. package/dist/permissions/modules/process-ast/lib/get-cases.d.ts +6 -0
  32. package/dist/permissions/modules/process-ast/lib/get-cases.js +40 -0
  33. package/dist/permissions/modules/process-ast/lib/inject-cases.js +1 -40
  34. package/dist/permissions/modules/process-payload/process-payload.js +4 -5
  35. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +7 -6
  36. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +1 -2
  37. package/dist/permissions/utils/fetch-dynamic-variable-context.js +44 -24
  38. package/dist/permissions/utils/fetch-raw-permissions.d.ts +11 -0
  39. package/dist/permissions/utils/fetch-raw-permissions.js +39 -0
  40. package/dist/services/fields.d.ts +1 -1
  41. package/dist/services/fields.js +22 -19
  42. package/dist/services/import-export.js +2 -2
  43. package/dist/services/items.js +1 -1
  44. package/dist/services/meta.js +8 -7
  45. package/dist/services/permissions.js +19 -19
  46. package/dist/utils/apply-query.d.ts +3 -3
  47. package/dist/utils/apply-query.js +25 -20
  48. package/dist/utils/get-column.d.ts +8 -4
  49. package/dist/utils/get-column.js +10 -2
  50. package/dist/utils/sanitize-query.js +1 -1
  51. 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
- dbQuery[logical].whereNotIn(pkField, subQueryBuilder(Object.values(value)[0]));
365
- continue;
366
- }
367
- else if (childKey === '_some') {
368
- dbQuery[logical].whereIn(pkField, subQueryBuilder(Object.values(value)[0]));
369
- continue;
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 GetColumnOptions = {
4
- query?: Query | undefined;
5
- cases?: Filter[];
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
@@ -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
- query: options?.query,
33
- cases: options?.cases,
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 filter query parameter.');
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.0",
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.5",
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.2",
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.1",
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/extensions": "2.0.0",
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/extensions-sdk": "12.0.0",
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/storage-driver-s3": "11.0.0",
172
+ "@directus/utils": "12.0.0",
172
173
  "@directus/validation": "1.0.0",
173
- "directus": "11.0.1",
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": {