directus 9.12.1 → 9.14.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.
Files changed (136) hide show
  1. package/dist/app.js +20 -5
  2. package/dist/auth/drivers/index.js +5 -1
  3. package/dist/auth/drivers/ldap.js +5 -1
  4. package/dist/auth/drivers/oauth2.js +15 -23
  5. package/dist/auth/drivers/openid.js +20 -25
  6. package/dist/cli/commands/bootstrap/index.js +5 -1
  7. package/dist/cli/commands/schema/apply.js +7 -3
  8. package/dist/cli/commands/schema/snapshot.d.ts +1 -1
  9. package/dist/cli/commands/schema/snapshot.js +33 -25
  10. package/dist/cli/index.js +1 -1
  11. package/dist/cli/utils/create-env/env-stub.liquid +11 -11
  12. package/dist/constants.d.ts +1 -0
  13. package/dist/constants.js +5 -1
  14. package/dist/controllers/assets.js +5 -5
  15. package/dist/controllers/dashboards.js +4 -1
  16. package/dist/controllers/files.js +8 -5
  17. package/dist/controllers/flows.js +4 -1
  18. package/dist/controllers/folders.js +4 -1
  19. package/dist/controllers/items.js +4 -1
  20. package/dist/controllers/notifications.js +4 -1
  21. package/dist/controllers/operations.js +4 -1
  22. package/dist/controllers/panels.js +4 -1
  23. package/dist/controllers/permissions.js +4 -1
  24. package/dist/controllers/presets.js +4 -1
  25. package/dist/controllers/roles.js +4 -1
  26. package/dist/controllers/shares.js +4 -1
  27. package/dist/controllers/users.js +75 -3
  28. package/dist/controllers/utils.js +3 -3
  29. package/dist/database/helpers/date/dialects/sqlite.js +3 -0
  30. package/dist/database/helpers/fn/dialects/oracle.d.ts +9 -9
  31. package/dist/database/helpers/fn/dialects/oracle.js +22 -16
  32. package/dist/database/helpers/fn/dialects/sqlite.d.ts +9 -9
  33. package/dist/database/helpers/fn/dialects/sqlite.js +46 -16
  34. package/dist/database/helpers/fn/types.d.ts +12 -9
  35. package/dist/database/helpers/index.js +5 -1
  36. package/dist/database/index.js +2 -0
  37. package/dist/database/migrations/20210225A-add-relations-sort-field.js +2 -2
  38. package/dist/database/migrations/20210506A-rename-interfaces.js +2 -2
  39. package/dist/database/migrations/20210802A-replace-groups.js +2 -2
  40. package/dist/database/migrations/20210805A-update-groups.js +2 -2
  41. package/dist/database/migrations/20210805B-change-image-metadata-structure.js +3 -3
  42. package/dist/database/migrations/20211007A-update-presets.js +5 -5
  43. package/dist/database/migrations/20220429A-add-flows.js +1 -2
  44. package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +3 -0
  45. package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.js +11 -0
  46. package/dist/database/system-data/fields/dashboards.yaml +1 -0
  47. package/dist/database/system-data/fields/flows.yaml +1 -1
  48. package/dist/emitter.js +12 -7
  49. package/dist/env.d.ts +1 -1
  50. package/dist/env.js +8 -3
  51. package/dist/exceptions/database/translate.js +5 -1
  52. package/dist/exceptions/index.js +5 -1
  53. package/dist/extensions.d.ts +2 -1
  54. package/dist/extensions.js +28 -20
  55. package/dist/flows.d.ts +5 -0
  56. package/dist/flows.js +66 -40
  57. package/dist/index.js +5 -1
  58. package/dist/logger.js +5 -1
  59. package/dist/messenger.js +2 -2
  60. package/dist/middleware/graphql.js +2 -2
  61. package/dist/middleware/respond.js +10 -1
  62. package/dist/middleware/validate-batch.js +3 -1
  63. package/dist/operations/item-create/index.js +1 -2
  64. package/dist/operations/item-delete/index.d.ts +1 -0
  65. package/dist/operations/item-delete/index.js +8 -7
  66. package/dist/operations/item-read/index.d.ts +1 -0
  67. package/dist/operations/item-read/index.js +8 -7
  68. package/dist/operations/item-update/index.d.ts +1 -0
  69. package/dist/operations/item-update/index.js +9 -8
  70. package/dist/operations/log/index.js +1 -2
  71. package/dist/operations/notification/index.js +1 -2
  72. package/dist/operations/request/index.d.ts +4 -1
  73. package/dist/operations/request/index.js +5 -1
  74. package/dist/operations/transform/index.js +1 -2
  75. package/dist/operations/trigger/index.js +1 -2
  76. package/dist/server.js +5 -1
  77. package/dist/services/assets.js +5 -1
  78. package/dist/services/collections.js +5 -1
  79. package/dist/services/fields.d.ts +3 -3
  80. package/dist/services/fields.js +25 -17
  81. package/dist/services/files.js +5 -1
  82. package/dist/services/flows.d.ts +1 -2
  83. package/dist/services/flows.js +19 -8
  84. package/dist/services/{graphql.d.ts → graphql/index.d.ts} +3 -5
  85. package/dist/services/{graphql.js → graphql/index.js} +109 -101
  86. package/dist/services/graphql/types/date.d.ts +2 -0
  87. package/dist/services/graphql/types/date.js +9 -0
  88. package/dist/services/graphql/types/geojson.d.ts +2 -0
  89. package/dist/services/graphql/types/geojson.js +10 -0
  90. package/dist/services/graphql/types/string-or-float.d.ts +5 -0
  91. package/dist/services/graphql/types/string-or-float.js +34 -0
  92. package/dist/services/graphql/types/void.d.ts +2 -0
  93. package/dist/services/graphql/types/void.js +17 -0
  94. package/dist/services/graphql/utils/add-path-to-validation-error.d.ts +2 -0
  95. package/dist/services/graphql/utils/add-path-to-validation-error.js +20 -0
  96. package/dist/services/import-export.js +12 -8
  97. package/dist/services/index.js +5 -1
  98. package/dist/services/items.d.ts +6 -1
  99. package/dist/services/items.js +43 -19
  100. package/dist/services/mail/index.js +8 -6
  101. package/dist/services/notifications.js +22 -11
  102. package/dist/services/operations.d.ts +1 -2
  103. package/dist/services/operations.js +19 -8
  104. package/dist/services/payload.js +13 -11
  105. package/dist/services/permissions.d.ts +1 -0
  106. package/dist/services/permissions.js +5 -0
  107. package/dist/services/relations.js +5 -1
  108. package/dist/services/roles.d.ts +1 -0
  109. package/dist/services/roles.js +9 -0
  110. package/dist/services/server.js +5 -1
  111. package/dist/services/users.d.ts +1 -0
  112. package/dist/services/users.js +22 -0
  113. package/dist/types/index.js +5 -1
  114. package/dist/utils/apply-query.js +24 -15
  115. package/dist/utils/apply-snapshot.js +3 -0
  116. package/dist/utils/calculate-field-depth.d.ts +33 -0
  117. package/dist/utils/calculate-field-depth.js +75 -0
  118. package/dist/utils/get-column.js +1 -1
  119. package/dist/utils/get-default-value.js +3 -13
  120. package/dist/utils/get-graphql-type.js +4 -3
  121. package/dist/utils/get-local-type.d.ts +6 -3
  122. package/dist/utils/get-permissions.js +3 -4
  123. package/dist/utils/get-schema.js +1 -2
  124. package/dist/utils/get-string-byte-size.d.ts +4 -0
  125. package/dist/utils/get-string-byte-size.js +10 -0
  126. package/dist/utils/job-queue.d.ts +9 -0
  127. package/dist/utils/job-queue.js +24 -0
  128. package/dist/utils/jwt.js +5 -1
  129. package/dist/utils/sanitize-query.js +4 -5
  130. package/dist/utils/validate-query.js +50 -0
  131. package/dist/webhooks.js +5 -1
  132. package/package.json +74 -73
  133. package/dist/utils/operation-options.d.ts +0 -3
  134. package/dist/utils/operation-options.js +0 -45
  135. package/dist/utils/parse-json.d.ts +0 -5
  136. package/dist/utils/parse-json.js +0 -19
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateFieldDepth = void 0;
4
+ const lodash_1 = require("lodash");
5
+ /**
6
+ * Calculates the depth of a given JSON structure, not counting any _ prefixed properties
7
+ *
8
+ * Used to calculate the field depth in a filter or deep query structure
9
+ *
10
+ * @example
11
+ *
12
+ * ```js
13
+ * const deep = {
14
+ * translations: {
15
+ * _filter: {
16
+ * _and: [
17
+ * {
18
+ * language_id: {
19
+ * name: {
20
+ * _eq: 'English'
21
+ * }
22
+ * }
23
+ * },
24
+ * {
25
+ * status: {
26
+ * _eq: 'Published'
27
+ * }
28
+ * }
29
+ * ]
30
+ * }
31
+ * }
32
+ * };
33
+ *
34
+ * const result = calculateFieldDepth(deep); // => 3
35
+ * ```
36
+ */
37
+ function calculateFieldDepth(obj, dotNotationKeys = []) {
38
+ if (!obj) {
39
+ return 0;
40
+ }
41
+ let depth = 0;
42
+ const keys = Object.keys(obj);
43
+ for (const key of keys) {
44
+ const nestedValue = obj[key];
45
+ if (dotNotationKeys.includes(key) && nestedValue) {
46
+ let sortDepth = 0;
47
+ for (const sortKey of nestedValue) {
48
+ if (sortKey) {
49
+ sortDepth = Math.max(sortKey.split('.').length, sortDepth);
50
+ }
51
+ }
52
+ if (sortDepth > depth) {
53
+ depth = sortDepth;
54
+ }
55
+ }
56
+ else {
57
+ if (!(0, lodash_1.isPlainObject)(nestedValue) && !(0, lodash_1.isArray)(nestedValue))
58
+ continue;
59
+ let nestedDepth = 0;
60
+ if (Array.isArray(nestedValue)) {
61
+ nestedDepth = Math.max(...nestedValue.map((val) => calculateFieldDepth(val, dotNotationKeys)));
62
+ }
63
+ else {
64
+ nestedDepth = calculateFieldDepth(nestedValue, dotNotationKeys);
65
+ }
66
+ if (key.startsWith('_') === false)
67
+ nestedDepth += 1;
68
+ if (nestedDepth > depth) {
69
+ depth = nestedDepth;
70
+ }
71
+ }
72
+ }
73
+ return depth;
74
+ }
75
+ exports.calculateFieldDepth = calculateFieldDepth;
@@ -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);
31
+ const result = fn[functionName](table, columnName, { type });
32
32
  if (alias) {
33
33
  return knex.raw(result + ' AS ??', [alias]);
34
34
  }
@@ -3,26 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@directus/shared/utils");
6
7
  const env_1 = __importDefault(require("../env"));
7
8
  const logger_1 = __importDefault(require("../logger"));
8
9
  const get_local_type_1 = __importDefault(require("./get-local-type"));
9
- const parse_json_1 = require("./parse-json");
10
10
  function getDefaultValue(column) {
11
11
  var _a;
12
12
  const type = (0, get_local_type_1.default)(column);
13
- let defaultValue = (_a = column.default_value) !== null && _a !== void 0 ? _a : null;
13
+ const defaultValue = (_a = column.default_value) !== null && _a !== void 0 ? _a : null;
14
14
  if (defaultValue === null)
15
15
  return null;
16
- if (defaultValue === 'null')
17
- return null;
18
- if (defaultValue === 'NULL')
19
- return null;
20
- // Check if the default is wrapped in an extra pair of quotes, this happens in SQLite / MariaDB
21
- if (typeof defaultValue === 'string' &&
22
- ((defaultValue.startsWith(`'`) && defaultValue.endsWith(`'`)) ||
23
- (defaultValue.startsWith(`"`) && defaultValue.endsWith(`"`)))) {
24
- defaultValue = defaultValue.slice(1, -1);
25
- }
26
16
  if (defaultValue === '0000-00-00 00:00:00')
27
17
  return null;
28
18
  switch (type) {
@@ -60,7 +50,7 @@ function castToObject(value) {
60
50
  return value;
61
51
  if (typeof value === 'string') {
62
52
  try {
63
- return (0, parse_json_1.parseJSON)(value);
53
+ return (0, utils_1.parseJSON)(value);
64
54
  }
65
55
  catch (err) {
66
56
  if (env_1.default.NODE_ENV === 'development') {
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getGraphQLType = void 0;
4
4
  const graphql_1 = require("graphql");
5
5
  const graphql_compose_1 = require("graphql-compose");
6
- const graphql_2 = require("../services/graphql");
6
+ const date_1 = require("../services/graphql/types/date");
7
+ const geojson_1 = require("../services/graphql/types/geojson");
7
8
  function getGraphQLType(localType) {
8
9
  switch (localType) {
9
10
  case 'boolean':
@@ -20,11 +21,11 @@ function getGraphQLType(localType) {
20
21
  case 'json':
21
22
  return graphql_compose_1.GraphQLJSON;
22
23
  case 'geometry':
23
- return graphql_2.GraphQLGeoJSON;
24
+ return geojson_1.GraphQLGeoJSON;
24
25
  case 'timestamp':
25
26
  case 'dateTime':
26
27
  case 'date':
27
- return graphql_2.GraphQLDate;
28
+ return date_1.GraphQLDate;
28
29
  default:
29
30
  return graphql_1.GraphQLString;
30
31
  }
@@ -1,6 +1,9 @@
1
- import { SchemaOverview } from '@directus/schema/dist/types/overview';
2
- import { Column } from 'knex-schema-inspector/dist/types/column';
3
1
  import { FieldMeta, Type } from '@directus/shared/types';
4
- export default function getLocalType(column?: SchemaOverview[string]['columns'][string] | Column, field?: {
2
+ export default function getLocalType(column?: {
3
+ data_type: string;
4
+ numeric_precision?: null | number;
5
+ numeric_scale?: null | number;
6
+ max_length?: null | number;
7
+ }, field?: {
5
8
  special?: FieldMeta['special'];
6
9
  }): Type | 'unknown';
@@ -15,7 +15,6 @@ const roles_1 = require("../services/roles");
15
15
  const users_1 = require("../services/users");
16
16
  const merge_permissions_1 = require("../utils/merge-permissions");
17
17
  const merge_permissions_for_share_1 = require("./merge-permissions-for-share");
18
- const parse_json_1 = require("./parse-json");
19
18
  async function getPermissions(accountability, schema) {
20
19
  const database = (0, database_1.default)();
21
20
  const { systemCache, cache } = (0, cache_1.getCache)();
@@ -85,19 +84,19 @@ function parsePermissions(permissions) {
85
84
  permissions = permissions.map((permissionRaw) => {
86
85
  const permission = (0, lodash_1.cloneDeep)(permissionRaw);
87
86
  if (permission.permissions && typeof permission.permissions === 'string') {
88
- permission.permissions = (0, parse_json_1.parseJSON)(permission.permissions);
87
+ permission.permissions = (0, utils_1.parseJSON)(permission.permissions);
89
88
  }
90
89
  else if (permission.permissions === null) {
91
90
  permission.permissions = {};
92
91
  }
93
92
  if (permission.validation && typeof permission.validation === 'string') {
94
- permission.validation = (0, parse_json_1.parseJSON)(permission.validation);
93
+ permission.validation = (0, utils_1.parseJSON)(permission.validation);
95
94
  }
96
95
  else if (permission.validation === null) {
97
96
  permission.validation = {};
98
97
  }
99
98
  if (permission.presets && typeof permission.presets === 'string') {
100
- permission.presets = (0, parse_json_1.parseJSON)(permission.presets);
99
+ permission.presets = (0, utils_1.parseJSON)(permission.presets);
101
100
  }
102
101
  else if (permission.presets === null) {
103
102
  permission.presets = {};
@@ -17,7 +17,6 @@ const logger_1 = __importDefault(require("../logger"));
17
17
  const services_1 = require("../services");
18
18
  const get_default_value_1 = __importDefault(require("./get-default-value"));
19
19
  const get_local_type_1 = __importDefault(require("./get-local-type"));
20
- const parse_json_1 = require("./parse-json");
21
20
  async function getSchema(options) {
22
21
  const database = (options === null || options === void 0 ? void 0 : options.database) || (0, database_1.default)();
23
22
  const schemaInspector = (0, schema_1.default)(database);
@@ -120,7 +119,7 @@ async function getDatabaseSchema(database, schemaInspector) {
120
119
  const type = (existing && (0, get_local_type_1.default)(column, { special })) || 'alias';
121
120
  let validation = (_a = field.validation) !== null && _a !== void 0 ? _a : null;
122
121
  if (validation && typeof validation === 'string')
123
- validation = (0, parse_json_1.parseJSON)(validation);
122
+ validation = (0, utils_1.parseJSON)(validation);
124
123
  result.collections[field.collection].fields[field.field] = {
125
124
  field: field.field,
126
125
  defaultValue: (_b = existing === null || existing === void 0 ? void 0 : existing.defaultValue) !== null && _b !== void 0 ? _b : null,
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Returns the byte size for a given input string
3
+ */
4
+ export declare function stringByteSize(string: string): number;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stringByteSize = void 0;
4
+ /**
5
+ * Returns the byte size for a given input string
6
+ */
7
+ function stringByteSize(string) {
8
+ return Buffer.byteLength(string, 'utf-8');
9
+ }
10
+ exports.stringByteSize = stringByteSize;
@@ -0,0 +1,9 @@
1
+ declare type Job = () => Promise<void> | void;
2
+ export declare class JobQueue {
3
+ private running;
4
+ private jobs;
5
+ constructor();
6
+ enqueue(job: Job): void;
7
+ private run;
8
+ }
9
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobQueue = void 0;
4
+ class JobQueue {
5
+ constructor() {
6
+ this.running = false;
7
+ this.jobs = [];
8
+ }
9
+ enqueue(job) {
10
+ this.jobs.push(job);
11
+ if (!this.running) {
12
+ this.run();
13
+ }
14
+ }
15
+ async run() {
16
+ this.running = true;
17
+ while (this.jobs.length > 0) {
18
+ const job = this.jobs.shift();
19
+ await job();
20
+ }
21
+ this.running = false;
22
+ }
23
+ }
24
+ exports.JobQueue = JobQueue;
package/dist/utils/jwt.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -8,7 +8,6 @@ const utils_1 = require("@directus/shared/utils");
8
8
  const lodash_1 = require("lodash");
9
9
  const logger_1 = __importDefault(require("../logger"));
10
10
  const types_1 = require("../types");
11
- const parse_json_1 = require("./parse-json");
12
11
  function sanitizeQuery(rawQuery, accountability) {
13
12
  const query = {};
14
13
  if (rawQuery.limit !== undefined) {
@@ -83,7 +82,7 @@ function sanitizeAggregate(rawAggregate) {
83
82
  let aggregate = rawAggregate;
84
83
  if (typeof rawAggregate === 'string') {
85
84
  try {
86
- aggregate = (0, parse_json_1.parseJSON)(rawAggregate);
85
+ aggregate = (0, utils_1.parseJSON)(rawAggregate);
87
86
  }
88
87
  catch {
89
88
  logger_1.default.warn('Invalid value passed for filter query parameter.');
@@ -101,7 +100,7 @@ function sanitizeFilter(rawFilter, accountability) {
101
100
  let filters = rawFilter;
102
101
  if (typeof rawFilter === 'string') {
103
102
  try {
104
- filters = (0, parse_json_1.parseJSON)(rawFilter);
103
+ filters = (0, utils_1.parseJSON)(rawFilter);
105
104
  }
106
105
  catch {
107
106
  logger_1.default.warn('Invalid value passed for filter query parameter.');
@@ -136,7 +135,7 @@ function sanitizeDeep(deep, accountability) {
136
135
  const result = {};
137
136
  if (typeof deep === 'string') {
138
137
  try {
139
- deep = (0, parse_json_1.parseJSON)(deep);
138
+ deep = (0, utils_1.parseJSON)(deep);
140
139
  }
141
140
  catch {
142
141
  logger_1.default.warn('Invalid value passed for deep query parameter.');
@@ -170,7 +169,7 @@ function sanitizeAlias(rawAlias) {
170
169
  let alias = rawAlias;
171
170
  if (typeof rawAlias === 'string') {
172
171
  try {
173
- alias = (0, parse_json_1.parseJSON)(rawAlias);
172
+ alias = (0, utils_1.parseJSON)(rawAlias);
174
173
  }
175
174
  catch (err) {
176
175
  logger_1.default.warn('Invalid value passed for alias query parameter.');
@@ -8,6 +8,8 @@ const joi_1 = __importDefault(require("joi"));
8
8
  const lodash_1 = require("lodash");
9
9
  const exceptions_1 = require("../exceptions");
10
10
  const wellknown_1 = require("wellknown");
11
+ const calculate_field_depth_1 = require("./calculate-field-depth");
12
+ const env_1 = __importDefault(require("../env"));
11
13
  const querySchema = joi_1.default.object({
12
14
  fields: joi_1.default.array().items(joi_1.default.string()),
13
15
  group: joi_1.default.array().items(joi_1.default.string()),
@@ -31,6 +33,7 @@ function validateQuery(query) {
31
33
  if (query.alias) {
32
34
  validateAlias(query.alias);
33
35
  }
36
+ validateRelationalDepth(query);
34
37
  if (error) {
35
38
  throw new exceptions_1.InvalidQueryException(error.message);
36
39
  }
@@ -153,3 +156,50 @@ function validateAlias(alias) {
153
156
  }
154
157
  }
155
158
  }
159
+ function validateRelationalDepth(query) {
160
+ const maxRelationalDepth = Number(env_1.default.MAX_RELATIONAL_DEPTH) > 2 ? Number(env_1.default.MAX_RELATIONAL_DEPTH) : 2;
161
+ // Process the fields in the same way as api/src/utils/get-ast-from-query.ts
162
+ let fields = ['*'];
163
+ if (query.fields) {
164
+ fields = query.fields;
165
+ }
166
+ /**
167
+ * When using aggregate functions, you can't have any other regular fields
168
+ * selected. This makes sure you never end up in a non-aggregate fields selection error
169
+ */
170
+ if (Object.keys(query.aggregate || {}).length > 0) {
171
+ fields = [];
172
+ }
173
+ /**
174
+ * Similarly, when grouping on a specific field, you can't have other non-aggregated fields.
175
+ * The group query will override the fields query
176
+ */
177
+ if (query.group) {
178
+ fields = query.group;
179
+ }
180
+ fields = (0, lodash_1.uniq)(fields);
181
+ for (const field of fields) {
182
+ if (field.split('.').length > maxRelationalDepth) {
183
+ throw new exceptions_1.InvalidQueryException('Max relational depth exceeded.');
184
+ }
185
+ }
186
+ if (query.filter) {
187
+ const filterRelationalDepth = (0, calculate_field_depth_1.calculateFieldDepth)(query.filter);
188
+ if (filterRelationalDepth > maxRelationalDepth) {
189
+ throw new exceptions_1.InvalidQueryException('Max relational depth exceeded.');
190
+ }
191
+ }
192
+ if (query.sort) {
193
+ for (const sort of query.sort) {
194
+ if (sort.split('.').length > maxRelationalDepth) {
195
+ throw new exceptions_1.InvalidQueryException('Max relational depth exceeded.');
196
+ }
197
+ }
198
+ }
199
+ if (query.deep) {
200
+ const deepRelationalDepth = (0, calculate_field_depth_1.calculateFieldDepth)(query.deep, ['_sort']);
201
+ if (deepRelationalDepth > maxRelationalDepth) {
202
+ throw new exceptions_1.InvalidQueryException('Max relational depth exceeded.');
203
+ }
204
+ }
205
+ }
package/dist/webhooks.js CHANGED
@@ -11,13 +11,17 @@ const logger_1 = __importDefault(require("./logger"));
11
11
  const services_1 = require("./services");
12
12
  const get_schema_1 = require("./utils/get-schema");
13
13
  const messenger_1 = require("./messenger");
14
+ const job_queue_1 = require("./utils/job-queue");
14
15
  let registered = [];
16
+ const reloadQueue = new job_queue_1.JobQueue();
15
17
  async function init() {
16
18
  await register();
17
19
  const messenger = (0, messenger_1.getMessenger)();
18
20
  messenger.subscribe('webhooks', (event) => {
19
21
  if (event.type === 'reload') {
20
- reload();
22
+ reloadQueue.enqueue(async () => {
23
+ await reload();
24
+ });
21
25
  }
22
26
  });
23
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "directus",
3
- "version": "9.12.1",
3
+ "version": "9.14.0",
4
4
  "license": "GPL-3.0-only",
5
5
  "homepage": "https://github.com/directus/directus#readme",
6
6
  "description": "Directus is a real-time API and App dashboard for managing SQL database content.",
@@ -76,87 +76,88 @@
76
76
  "README.md"
77
77
  ],
78
78
  "dependencies": {
79
- "@aws-sdk/client-ses": "^3.40.0",
80
- "@directus/app": "9.12.1",
81
- "@directus/drive": "9.12.1",
82
- "@directus/drive-azure": "9.12.1",
83
- "@directus/drive-gcs": "9.12.1",
84
- "@directus/drive-s3": "9.12.1",
85
- "@directus/extensions-sdk": "9.12.1",
86
- "@directus/format-title": "9.12.1",
87
- "@directus/schema": "9.12.1",
88
- "@directus/shared": "9.12.1",
89
- "@directus/specs": "9.12.1",
90
- "@godaddy/terminus": "^4.9.0",
79
+ "@aws-sdk/client-ses": "^3.107.0",
80
+ "@directus/app": "9.14.0",
81
+ "@directus/drive": "9.14.0",
82
+ "@directus/drive-azure": "9.14.0",
83
+ "@directus/drive-gcs": "9.14.0",
84
+ "@directus/drive-s3": "9.14.0",
85
+ "@directus/extensions-sdk": "9.14.0",
86
+ "@directus/format-title": "9.14.0",
87
+ "@directus/schema": "9.14.0",
88
+ "@directus/shared": "9.14.0",
89
+ "@directus/specs": "9.14.0",
90
+ "@godaddy/terminus": "^4.10.2",
91
91
  "@rollup/plugin-alias": "^3.1.9",
92
- "@rollup/plugin-virtual": "^2.0.3",
93
- "argon2": "^0.28.2",
94
- "async": "^3.2.0",
95
- "async-mutex": "^0.3.1",
96
- "axios": "^0.24.0",
97
- "busboy": "^0.3.1",
92
+ "@rollup/plugin-virtual": "^2.1.0",
93
+ "argon2": "^0.28.5",
94
+ "async": "^3.2.4",
95
+ "async-mutex": "^0.3.2",
96
+ "axios": "^0.27.2",
97
+ "busboy": "^1.6.0",
98
+ "bytes": "^3.1.2",
98
99
  "camelcase": "^6.2.0",
99
100
  "chalk": "^4.1.1",
100
- "chokidar": "^3.5.2",
101
+ "chokidar": "^3.5.3",
101
102
  "commander": "^8.0.0",
102
- "cookie-parser": "^1.4.5",
103
+ "cookie-parser": "^1.4.6",
103
104
  "cors": "^2.8.5",
104
105
  "csv-parser": "^3.0.0",
105
- "date-fns": "^2.22.1",
106
+ "date-fns": "^2.28.0",
106
107
  "deep-diff": "^1.0.2",
107
108
  "deep-map": "^2.0.0",
108
- "destroy": "^1.0.4",
109
+ "destroy": "^1.2.0",
109
110
  "dotenv": "^10.0.0",
110
- "eventemitter2": "^6.4.3",
111
+ "eventemitter2": "^6.4.5",
111
112
  "execa": "^5.1.1",
112
- "exifr": "^7.1.2",
113
- "express": "^4.17.1",
113
+ "exifr": "^7.1.3",
114
+ "express": "^4.18.1",
114
115
  "fast-redact": "^3.1.1",
115
116
  "flat": "^5.0.2",
116
- "fs-extra": "^10.0.0",
117
+ "fs-extra": "^10.1.0",
117
118
  "globby": "^11.0.4",
118
119
  "graphql": "^15.5.0",
119
- "graphql-compose": "^9.0.1",
120
+ "graphql-compose": "^9.0.8",
120
121
  "helmet": "^4.6.0",
121
- "inquirer": "^8.1.1",
122
+ "inquirer": "^8.2.4",
122
123
  "ioredis": "^4.27.6",
123
- "joi": "^17.3.0",
124
+ "joi": "^17.6.0",
124
125
  "js-yaml": "^4.1.0",
125
- "js2xmlparser": "^4.0.1",
126
- "json2csv": "^5.0.3",
126
+ "js2xmlparser": "^4.0.2",
127
+ "json2csv": "^5.0.7",
127
128
  "jsonwebtoken": "^8.5.1",
128
- "keyv": "^4.0.3",
129
- "knex": "^2.0.0",
130
- "knex-schema-inspector": "1.7.3",
131
- "ldapjs": "^2.3.1",
132
- "liquidjs": "^9.25.0",
129
+ "keyv": "^4.3.0",
130
+ "knex": "^2.1.0",
131
+ "knex-schema-inspector": "^2.0.1",
132
+ "ldapjs": "^2.3.3",
133
+ "liquidjs": "^9.37.0",
133
134
  "lodash": "^4.17.21",
134
135
  "macos-release": "^2.4.1",
135
- "marked": "^4.0.3",
136
+ "marked": "^4.0.16",
136
137
  "micromustache": "^8.0.3",
137
- "mime-types": "^2.1.31",
138
+ "mime-types": "^2.1.35",
138
139
  "ms": "^2.1.3",
139
140
  "nanoid": "^3.1.23",
140
- "node-cron": "^3.0.0",
141
+ "node-cron": "^3.0.1",
141
142
  "node-machine-id": "^1.1.12",
142
- "nodemailer": "^6.6.1",
143
+ "nodemailer": "^6.7.5",
143
144
  "object-hash": "^2.2.0",
144
- "openapi3-ts": "^2.0.0",
145
- "openid-client": "^5.0.0",
145
+ "openapi3-ts": "^2.0.2",
146
+ "openid-client": "^5.1.6",
146
147
  "ora": "^5.4.0",
147
148
  "otplib": "^12.0.1",
148
149
  "pino": "6.13.3",
149
- "pino-colada": "^2.1.0",
150
+ "pino-colada": "^2.2.2",
150
151
  "pino-http": "5.8.0",
151
- "qs": "^6.9.4",
152
- "rate-limiter-flexible": "^2.2.2",
152
+ "qs": "^6.10.5",
153
+ "rate-limiter-flexible": "^2.3.7",
153
154
  "resolve-cwd": "^3.0.0",
154
- "rollup": "^2.67.3",
155
- "sanitize-html": "^2.6.0",
156
- "sharp": "^0.30.3",
157
- "stream-json": "^1.7.1",
155
+ "rollup": "^2.75.6",
156
+ "sanitize-html": "^2.7.0",
157
+ "sharp": "^0.30.6",
158
+ "stream-json": "^1.7.4",
158
159
  "strip-bom-stream": "^4.0.0",
159
- "supertest": "^6.1.6",
160
+ "supertest": "^6.2.3",
160
161
  "tmp-promise": "^3.0.3",
161
162
  "update-check": "^1.5.4",
162
163
  "uuid": "^8.3.2",
@@ -164,21 +165,21 @@
164
165
  "wellknown": "^0.5.0"
165
166
  },
166
167
  "optionalDependencies": {
167
- "@keyv/redis": "^2.1.2",
168
+ "@keyv/redis": "^2.3.6",
168
169
  "keyv-memcache": "^1.2.5",
169
170
  "memcached": "^2.2.2",
170
171
  "mysql": "^2.18.1",
171
- "nodemailer-mailgun-transport": "^2.1.3",
172
- "pg": "^8.6.0",
173
- "sqlite3": "^5.0.6",
172
+ "nodemailer-mailgun-transport": "^2.1.4",
173
+ "pg": "^8.7.3",
174
+ "sqlite3": "^5.0.8",
174
175
  "tedious": "^13.0.0"
175
176
  },
176
- "gitHead": "cd58611aa7114dd7ef13f0819f77f9858f34ad1e",
177
+ "gitHead": "d952222058dca96cf823b3e91dc146266ff89bd0",
177
178
  "devDependencies": {
178
- "@types/async": "3.2.10",
179
+ "@types/async": "3.2.13",
179
180
  "@types/body-parser": "1.19.2",
180
- "@types/busboy": "0.3.1",
181
- "@types/cookie-parser": "1.4.2",
181
+ "@types/busboy": "1.5.0",
182
+ "@types/cookie-parser": "1.4.3",
182
183
  "@types/cors": "2.8.12",
183
184
  "@types/deep-diff": "1.0.1",
184
185
  "@types/destroy": "1.0.0",
@@ -188,16 +189,16 @@
188
189
  "@types/fast-redact": "^3.0.1",
189
190
  "@types/flat": "5.0.2",
190
191
  "@types/fs-extra": "9.0.13",
191
- "@types/inquirer": "8.1.3",
192
+ "@types/inquirer": "8.2.1",
192
193
  "@types/ioredis": "^4.28.10",
193
194
  "@types/jest": "27.4.1",
194
195
  "@types/js-yaml": "4.0.5",
195
196
  "@types/json2csv": "5.0.3",
196
- "@types/jsonwebtoken": "8.5.6",
197
- "@types/keyv": "3.1.3",
197
+ "@types/jsonwebtoken": "8.5.8",
198
+ "@types/keyv": "3.1.4",
198
199
  "@types/ldapjs": "2.2.2",
199
- "@types/lodash": "4.14.177",
200
- "@types/marked": "4.0.1",
200
+ "@types/lodash": "4.14.182",
201
+ "@types/marked": "4.0.3",
201
202
  "@types/mime-types": "2.1.1",
202
203
  "@types/ms": "0.7.31",
203
204
  "@types/node": "16.11.9",
@@ -205,22 +206,22 @@
205
206
  "@types/nodemailer": "6.4.4",
206
207
  "@types/object-hash": "2.2.1",
207
208
  "@types/pino": "6.3.12",
208
- "@types/pino-http": "5.8.0",
209
+ "@types/pino-http": "5.8.1",
209
210
  "@types/qs": "6.9.7",
210
- "@types/sanitize-html": "2.5.0",
211
- "@types/sharp": "0.29.4",
212
- "@types/stream-json": "1.7.1",
213
- "@types/supertest": "2.0.11",
214
- "@types/uuid": "8.3.3",
211
+ "@types/sanitize-html": "2.6.2",
212
+ "@types/sharp": "0.30.4",
213
+ "@types/stream-json": "1.7.2",
214
+ "@types/supertest": "2.0.12",
215
+ "@types/uuid": "8.3.4",
215
216
  "@types/uuid-validate": "0.0.1",
216
- "@types/wellknown": "0.5.1",
217
+ "@types/wellknown": "0.5.3",
217
218
  "copyfiles": "2.4.1",
218
219
  "cross-env": "7.0.3",
219
220
  "form-data": "^4.0.0",
220
221
  "jest": "27.5.1",
221
- "knex-mock-client": "1.7.0",
222
+ "knex-mock-client": "1.8.4",
222
223
  "ts-jest": "27.1.3",
223
224
  "ts-node-dev": "1.1.8",
224
- "typescript": "4.5.2"
225
+ "typescript": "4.7.3"
225
226
  }
226
227
  }
@@ -1,3 +0,0 @@
1
- export declare function applyOperationOptions(options: Record<string, any>, data: Record<string, any>): Record<string, any>;
2
- export declare function optionToObject<T>(option: T): Exclude<T, string>;
3
- export declare function optionToString(option: unknown): string;