directus 9.12.2 → 9.14.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 (120) hide show
  1. package/dist/app.js +14 -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/controllers/assets.js +5 -5
  13. package/dist/controllers/dashboards.js +4 -1
  14. package/dist/controllers/files.js +8 -5
  15. package/dist/controllers/flows.js +4 -1
  16. package/dist/controllers/folders.js +4 -1
  17. package/dist/controllers/items.js +4 -1
  18. package/dist/controllers/notifications.js +4 -1
  19. package/dist/controllers/operations.js +4 -1
  20. package/dist/controllers/panels.js +4 -1
  21. package/dist/controllers/permissions.js +4 -1
  22. package/dist/controllers/presets.js +4 -1
  23. package/dist/controllers/roles.js +4 -1
  24. package/dist/controllers/shares.js +4 -1
  25. package/dist/controllers/users.js +75 -3
  26. package/dist/controllers/utils.js +3 -3
  27. package/dist/database/helpers/date/dialects/sqlite.js +3 -0
  28. package/dist/database/helpers/index.js +5 -1
  29. package/dist/database/index.js +2 -0
  30. package/dist/database/migrations/20210225A-add-relations-sort-field.js +2 -2
  31. package/dist/database/migrations/20210506A-rename-interfaces.js +2 -2
  32. package/dist/database/migrations/20210802A-replace-groups.js +2 -2
  33. package/dist/database/migrations/20210805A-update-groups.js +2 -2
  34. package/dist/database/migrations/20210805B-change-image-metadata-structure.js +3 -3
  35. package/dist/database/migrations/20211007A-update-presets.js +5 -5
  36. package/dist/database/migrations/20220429A-add-flows.js +1 -2
  37. package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +3 -0
  38. package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.js +11 -0
  39. package/dist/database/system-data/fields/dashboards.yaml +1 -0
  40. package/dist/emitter.js +12 -7
  41. package/dist/env.d.ts +1 -1
  42. package/dist/env.js +8 -3
  43. package/dist/exceptions/database/translate.js +5 -1
  44. package/dist/exceptions/index.js +5 -1
  45. package/dist/extensions.js +5 -1
  46. package/dist/flows.js +15 -11
  47. package/dist/index.js +5 -1
  48. package/dist/logger.js +5 -1
  49. package/dist/messenger.js +2 -2
  50. package/dist/middleware/graphql.js +2 -2
  51. package/dist/middleware/respond.js +10 -1
  52. package/dist/middleware/validate-batch.js +3 -1
  53. package/dist/operations/item-create/index.js +1 -2
  54. package/dist/operations/item-delete/index.d.ts +1 -0
  55. package/dist/operations/item-delete/index.js +8 -7
  56. package/dist/operations/item-read/index.d.ts +1 -0
  57. package/dist/operations/item-read/index.js +8 -7
  58. package/dist/operations/item-update/index.d.ts +1 -0
  59. package/dist/operations/item-update/index.js +9 -8
  60. package/dist/operations/log/index.js +1 -2
  61. package/dist/operations/notification/index.js +1 -2
  62. package/dist/operations/transform/index.js +1 -2
  63. package/dist/operations/trigger/index.js +1 -2
  64. package/dist/server.js +5 -1
  65. package/dist/services/assets.js +5 -1
  66. package/dist/services/collections.js +5 -1
  67. package/dist/services/fields.d.ts +3 -3
  68. package/dist/services/fields.js +25 -17
  69. package/dist/services/files.js +5 -1
  70. package/dist/services/flows.d.ts +1 -0
  71. package/dist/services/flows.js +6 -0
  72. package/dist/services/{graphql.d.ts → graphql/index.d.ts} +3 -5
  73. package/dist/services/{graphql.js → graphql/index.js} +109 -101
  74. package/dist/services/graphql/types/date.d.ts +2 -0
  75. package/dist/services/graphql/types/date.js +9 -0
  76. package/dist/services/graphql/types/geojson.d.ts +2 -0
  77. package/dist/services/graphql/types/geojson.js +10 -0
  78. package/dist/services/graphql/types/string-or-float.d.ts +5 -0
  79. package/dist/services/graphql/types/string-or-float.js +34 -0
  80. package/dist/services/graphql/types/void.d.ts +2 -0
  81. package/dist/services/graphql/types/void.js +17 -0
  82. package/dist/services/graphql/utils/add-path-to-validation-error.d.ts +2 -0
  83. package/dist/services/graphql/utils/add-path-to-validation-error.js +20 -0
  84. package/dist/services/import-export.js +12 -8
  85. package/dist/services/index.js +5 -1
  86. package/dist/services/items.d.ts +6 -1
  87. package/dist/services/items.js +43 -19
  88. package/dist/services/mail/index.js +8 -6
  89. package/dist/services/notifications.js +22 -11
  90. package/dist/services/operations.d.ts +1 -0
  91. package/dist/services/operations.js +6 -0
  92. package/dist/services/payload.js +13 -11
  93. package/dist/services/permissions.d.ts +1 -0
  94. package/dist/services/permissions.js +5 -0
  95. package/dist/services/relations.js +5 -1
  96. package/dist/services/roles.d.ts +1 -0
  97. package/dist/services/roles.js +9 -0
  98. package/dist/services/server.js +5 -1
  99. package/dist/services/users.d.ts +1 -0
  100. package/dist/services/users.js +17 -0
  101. package/dist/types/index.js +5 -1
  102. package/dist/utils/apply-query.js +24 -15
  103. package/dist/utils/calculate-field-depth.d.ts +33 -0
  104. package/dist/utils/calculate-field-depth.js +75 -0
  105. package/dist/utils/get-default-value.js +3 -13
  106. package/dist/utils/get-graphql-type.js +4 -3
  107. package/dist/utils/get-local-type.d.ts +6 -3
  108. package/dist/utils/get-permissions.js +3 -4
  109. package/dist/utils/get-schema.js +1 -2
  110. package/dist/utils/get-string-byte-size.d.ts +4 -0
  111. package/dist/utils/get-string-byte-size.js +10 -0
  112. package/dist/utils/jwt.js +5 -1
  113. package/dist/utils/sanitize-query.js +4 -5
  114. package/dist/utils/validate-query.js +50 -0
  115. package/dist/webhooks.js +5 -1
  116. package/package.json +74 -73
  117. package/dist/utils/operation-options.d.ts +0 -3
  118. package/dist/utils/operation-options.js +0 -45
  119. package/dist/utils/parse-json.d.ts +0 -5
  120. package/dist/utils/parse-json.js +0 -19
@@ -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];
@@ -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];
@@ -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];
package/dist/flows.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];
@@ -25,6 +29,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
29
  exports.getFlowManager = void 0;
26
30
  const sharedExceptions = __importStar(require("@directus/shared/exceptions"));
27
31
  const types_1 = require("@directus/shared/types");
32
+ const utils_1 = require("@directus/shared/utils");
33
+ const fast_redact_1 = __importDefault(require("fast-redact"));
34
+ const lodash_1 = require("lodash");
28
35
  const micromustache_1 = require("micromustache");
29
36
  const node_cron_1 = require("node-cron");
30
37
  const database_1 = __importDefault(require("./database"));
@@ -32,16 +39,13 @@ const emitter_1 = __importDefault(require("./emitter"));
32
39
  const env_1 = __importDefault(require("./env"));
33
40
  const exceptions = __importStar(require("./exceptions"));
34
41
  const logger_1 = __importDefault(require("./logger"));
42
+ const messenger_1 = require("./messenger");
35
43
  const services = __importStar(require("./services"));
36
44
  const services_1 = require("./services");
37
- const construct_flow_tree_1 = require("./utils/construct-flow-tree");
38
- const get_schema_1 = require("./utils/get-schema");
39
45
  const activity_1 = require("./services/activity");
40
46
  const revisions_1 = require("./services/revisions");
41
- const lodash_1 = require("lodash");
42
- const messenger_1 = require("./messenger");
43
- const fast_redact_1 = __importDefault(require("fast-redact"));
44
- const operation_options_1 = require("./utils/operation-options");
47
+ const construct_flow_tree_1 = require("./utils/construct-flow-tree");
48
+ const get_schema_1 = require("./utils/get-schema");
45
49
  const job_queue_1 = require("./utils/job-queue");
46
50
  let flowManager;
47
51
  const redactLogs = (0, fast_redact_1.default)({
@@ -152,7 +156,7 @@ class FlowManager {
152
156
  else if (flow.options.type === 'action') {
153
157
  const handler = (meta, context) => this.executeFlow(flow, meta, {
154
158
  accountability: context.accountability,
155
- database: context.database,
159
+ database: (0, database_1.default)(),
156
160
  getSchema: context.schema ? () => context.schema : get_schema_1.getSchema,
157
161
  });
158
162
  events.forEach((event) => emitter_1.default.onAction(event, handler));
@@ -198,9 +202,9 @@ class FlowManager {
198
202
  }
199
203
  else if (flow.trigger === 'manual') {
200
204
  const handler = (data, context) => {
201
- var _a, _b, _c;
205
+ var _a, _b;
202
206
  const enabledCollections = (_b = (_a = flow.options) === null || _a === void 0 ? void 0 : _a.collections) !== null && _b !== void 0 ? _b : [];
203
- const targetCollection = (_c = data) === null || _c === void 0 ? void 0 : _c.body.collection;
207
+ const targetCollection = data === null || data === void 0 ? void 0 : data.body.collection;
204
208
  if (!targetCollection) {
205
209
  logger_1.default.warn(`Manual trigger requires "collection" to be specified in the payload`);
206
210
  throw new exceptions.ForbiddenException();
@@ -310,7 +314,7 @@ class FlowManager {
310
314
  return { successor: null, status: 'unknown', data: null, options: null };
311
315
  }
312
316
  const handler = this.operations[operation.type];
313
- const options = (0, operation_options_1.applyOperationOptions)(operation.options, keyedData);
317
+ const options = (0, utils_1.applyOptionsData)(operation.options, keyedData);
314
318
  try {
315
319
  const result = await handler(options, {
316
320
  services,
package/dist/index.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];
package/dist/logger.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];
package/dist/messenger.js CHANGED
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getMessenger = exports.MessengerRedis = exports.MessengerMemory = void 0;
7
+ const utils_1 = require("@directus/shared/utils");
7
8
  const ioredis_1 = __importDefault(require("ioredis"));
8
9
  const env_1 = __importDefault(require("./env"));
9
10
  const get_config_from_env_1 = require("./utils/get-config-from-env");
10
- const parse_json_1 = require("./utils/parse-json");
11
11
  class MessengerMemory {
12
12
  constructor() {
13
13
  this.handlers = {};
@@ -38,7 +38,7 @@ class MessengerRedis {
38
38
  subscribe(channel, callback) {
39
39
  this.sub.subscribe(`${this.namespace}:${channel}`);
40
40
  this.sub.on('message', (messageChannel, payloadString) => {
41
- const payload = (0, parse_json_1.parseJSON)(payloadString);
41
+ const payload = (0, utils_1.parseJSON)(payloadString);
42
42
  if (messageChannel === `${this.namespace}:${channel}`) {
43
43
  callback(payload);
44
44
  }
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.parseGraphQL = void 0;
7
+ const utils_1 = require("@directus/shared/utils");
7
8
  const graphql_1 = require("graphql");
8
9
  const exceptions_1 = require("../exceptions");
9
10
  const async_handler_1 = __importDefault(require("../utils/async-handler"));
10
- const parse_json_1 = require("../utils/parse-json");
11
11
  exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
12
12
  if (req.method !== 'GET' && req.method !== 'POST') {
13
13
  throw new exceptions_1.MethodNotAllowedException('GraphQL only supports GET and POST requests.', { allow: ['GET', 'POST'] });
@@ -20,7 +20,7 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
20
20
  query = req.query.query || null;
21
21
  if (req.query.variables) {
22
22
  try {
23
- variables = (0, parse_json_1.parseJSON)(req.query.variables);
23
+ variables = (0, utils_1.parseJSON)(req.query.variables);
24
24
  }
25
25
  catch {
26
26
  throw new exceptions_1.InvalidQueryException(`Variables are invalid JSON.`);
@@ -13,14 +13,23 @@ const get_cache_headers_1 = require("../utils/get-cache-headers");
13
13
  const logger_1 = __importDefault(require("../logger"));
14
14
  const services_1 = require("../services");
15
15
  const get_date_formatted_1 = require("../utils/get-date-formatted");
16
+ const get_string_byte_size_1 = require("../utils/get-string-byte-size");
17
+ const bytes_1 = require("bytes");
16
18
  exports.respond = (0, async_handler_1.default)(async (req, res) => {
17
19
  var _a, _b, _c;
18
20
  const { cache } = (0, cache_1.getCache)();
21
+ let exceedsMaxSize = false;
22
+ if (env_1.default.CACHE_VALUE_MAX_SIZE !== false) {
23
+ const valueSize = res.locals.payload ? (0, get_string_byte_size_1.stringByteSize)(JSON.stringify(res.locals.payload)) : 0;
24
+ const maxSize = (0, bytes_1.parse)(env_1.default.CACHE_VALUE_MAX_SIZE);
25
+ exceedsMaxSize = valueSize > maxSize;
26
+ }
19
27
  if (req.method.toLowerCase() === 'get' &&
20
28
  env_1.default.CACHE_ENABLED === true &&
21
29
  cache &&
22
30
  !req.sanitizedQuery.export &&
23
- res.locals.cache !== false) {
31
+ res.locals.cache !== false &&
32
+ exceedsMaxSize === false) {
24
33
  const key = (0, get_cache_key_1.getCacheKey)(req);
25
34
  try {
26
35
  await cache.set(key, res.locals.payload, (0, ms_1.default)(env_1.default.CACHE_TTL));
@@ -27,8 +27,10 @@ const validateBatch = (scope) => (0, async_handler_1.default)(async (req, res, n
27
27
  if (scope !== 'read') {
28
28
  batchSchema = batchSchema.xor('query', 'keys');
29
29
  }
30
- // In updates, we add a required `data` that holds the update payload
30
+ // In updates, we add a required `data` that holds the update payload if an array isn't used
31
31
  if (scope === 'update') {
32
+ if (Array.isArray(req.body))
33
+ return next();
32
34
  batchSchema = batchSchema.keys({
33
35
  data: joi_1.default.object().unknown().required(),
34
36
  });
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const services_1 = require("../../services");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  const get_accountability_for_role_1 = require("../../utils/get-accountability-for-role");
7
6
  exports.default = (0, utils_1.defineOperationApi)({
8
7
  id: 'item-create',
@@ -27,7 +26,7 @@ exports.default = (0, utils_1.defineOperationApi)({
27
26
  accountability: customAccountability,
28
27
  knex: database,
29
28
  });
30
- const payloadObject = (_a = (0, operation_options_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
29
+ const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
31
30
  let result;
32
31
  if (!payloadObject) {
33
32
  result = null;
@@ -3,6 +3,7 @@ declare type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  query?: Record<string, any> | string | null;
6
+ emitEvents: boolean;
6
7
  permissions: string;
7
8
  };
8
9
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const services_1 = require("../../services");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  const get_accountability_for_role_1 = require("../../utils/get-accountability-for-role");
6
+ const sanitize_query_1 = require("../../utils/sanitize-query");
7
7
  exports.default = (0, utils_1.defineOperationApi)({
8
8
  id: 'item-delete',
9
- handler: async ({ collection, key, query, permissions }, { accountability, database, getSchema }) => {
9
+ handler: async ({ collection, key, query, emitEvents, permissions }, { accountability, database, getSchema }) => {
10
10
  const schema = await getSchema({ database });
11
11
  let customAccountability;
12
12
  if (!permissions || permissions === '$trigger') {
@@ -26,18 +26,19 @@ exports.default = (0, utils_1.defineOperationApi)({
26
26
  accountability: customAccountability,
27
27
  knex: database,
28
28
  });
29
- const queryObject = query ? (0, operation_options_1.optionToObject)(query) : {};
29
+ const queryObject = query ? (0, utils_1.optionToObject)(query) : {};
30
+ const sanitizedQueryObject = (0, sanitize_query_1.sanitizeQuery)(queryObject, customAccountability);
30
31
  let result;
31
- if (!key) {
32
- result = await itemsService.deleteByQuery(queryObject);
32
+ if (!key || (Array.isArray(key) && key.length === 0)) {
33
+ result = await itemsService.deleteByQuery(sanitizedQueryObject);
33
34
  }
34
35
  else {
35
36
  const keys = (0, utils_1.toArray)(key);
36
37
  if (keys.length === 1) {
37
- result = await itemsService.deleteOne(keys[0]);
38
+ result = await itemsService.deleteOne(keys[0], { emitEvents });
38
39
  }
39
40
  else {
40
- result = await itemsService.deleteMany(keys);
41
+ result = await itemsService.deleteMany(keys, { emitEvents });
41
42
  }
42
43
  }
43
44
  return result;
@@ -3,6 +3,7 @@ declare type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  query?: Record<string, any> | string | null;
6
+ emitEvents: boolean;
6
7
  permissions: string;
7
8
  };
8
9
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const services_1 = require("../../services");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  const get_accountability_for_role_1 = require("../../utils/get-accountability-for-role");
6
+ const sanitize_query_1 = require("../../utils/sanitize-query");
7
7
  exports.default = (0, utils_1.defineOperationApi)({
8
8
  id: 'item-read',
9
- handler: async ({ collection, key, query, permissions }, { accountability, database, getSchema }) => {
9
+ handler: async ({ collection, key, query, emitEvents, permissions }, { accountability, database, getSchema }) => {
10
10
  const schema = await getSchema({ database });
11
11
  let customAccountability;
12
12
  if (!permissions || permissions === '$trigger') {
@@ -26,18 +26,19 @@ exports.default = (0, utils_1.defineOperationApi)({
26
26
  accountability: customAccountability,
27
27
  knex: database,
28
28
  });
29
- const queryObject = query ? (0, operation_options_1.optionToObject)(query) : {};
29
+ const queryObject = query ? (0, utils_1.optionToObject)(query) : {};
30
+ const sanitizedQueryObject = (0, sanitize_query_1.sanitizeQuery)(queryObject, customAccountability);
30
31
  let result;
31
- if (!key) {
32
- result = await itemsService.readByQuery(queryObject);
32
+ if (!key || (Array.isArray(key) && key.length === 0)) {
33
+ result = await itemsService.readByQuery(sanitizedQueryObject);
33
34
  }
34
35
  else {
35
36
  const keys = (0, utils_1.toArray)(key);
36
37
  if (keys.length === 1) {
37
- result = await itemsService.readOne(keys[0], queryObject);
38
+ result = await itemsService.readOne(keys[0], sanitizedQueryObject, { emitEvents });
38
39
  }
39
40
  else {
40
- result = await itemsService.readMany(keys, queryObject);
41
+ result = await itemsService.readMany(keys, sanitizedQueryObject, { emitEvents });
41
42
  }
42
43
  }
43
44
  return result;
@@ -4,6 +4,7 @@ declare type Options = {
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  payload?: Record<string, any> | string | null;
6
6
  query?: Record<string, any> | string | null;
7
+ emitEvents: boolean;
7
8
  permissions: string;
8
9
  };
9
10
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const services_1 = require("../../services");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  const get_accountability_for_role_1 = require("../../utils/get-accountability-for-role");
6
+ const sanitize_query_1 = require("../../utils/sanitize-query");
7
7
  exports.default = (0, utils_1.defineOperationApi)({
8
8
  id: 'item-update',
9
- handler: async ({ collection, key, payload, query, permissions }, { accountability, database, getSchema }) => {
9
+ handler: async ({ collection, key, payload, query, emitEvents, permissions }, { accountability, database, getSchema }) => {
10
10
  var _a;
11
11
  const schema = await getSchema({ database });
12
12
  let customAccountability;
@@ -27,22 +27,23 @@ exports.default = (0, utils_1.defineOperationApi)({
27
27
  accountability: customAccountability,
28
28
  knex: database,
29
29
  });
30
- const payloadObject = (_a = (0, operation_options_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
31
- const queryObject = query ? (0, operation_options_1.optionToObject)(query) : {};
30
+ const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
31
+ const queryObject = query ? (0, utils_1.optionToObject)(query) : {};
32
+ const sanitizedQueryObject = (0, sanitize_query_1.sanitizeQuery)(queryObject, customAccountability);
32
33
  if (!payloadObject) {
33
34
  return null;
34
35
  }
35
36
  let result;
36
- if (!key) {
37
- result = await itemsService.updateByQuery(queryObject, payloadObject);
37
+ if (!key || (Array.isArray(key) && key.length === 0)) {
38
+ result = await itemsService.updateByQuery(sanitizedQueryObject, payloadObject, { emitEvents });
38
39
  }
39
40
  else {
40
41
  const keys = (0, utils_1.toArray)(key);
41
42
  if (keys.length === 1) {
42
- result = await itemsService.updateOne(keys[0], payloadObject);
43
+ result = await itemsService.updateOne(keys[0], payloadObject, { emitEvents });
43
44
  }
44
45
  else {
45
- result = await itemsService.updateMany(keys, payloadObject);
46
+ result = await itemsService.updateMany(keys, payloadObject, { emitEvents });
46
47
  }
47
48
  }
48
49
  return result;
@@ -5,10 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const utils_1 = require("@directus/shared/utils");
7
7
  const logger_1 = __importDefault(require("../../logger"));
8
- const operation_options_1 = require("../../utils/operation-options");
9
8
  exports.default = (0, utils_1.defineOperationApi)({
10
9
  id: 'log',
11
10
  handler: ({ message }) => {
12
- logger_1.default.info((0, operation_options_1.optionToString)(message));
11
+ logger_1.default.info((0, utils_1.optionToString)(message));
13
12
  },
14
13
  });
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const services_1 = require("../../services");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  const get_accountability_for_role_1 = require("../../utils/get-accountability-for-role");
7
6
  exports.default = (0, utils_1.defineOperationApi)({
8
7
  id: 'notification',
@@ -27,7 +26,7 @@ exports.default = (0, utils_1.defineOperationApi)({
27
26
  accountability: customAccountability,
28
27
  knex: database,
29
28
  });
30
- const messageString = message ? (0, operation_options_1.optionToString)(message) : null;
29
+ const messageString = message ? (0, utils_1.optionToString)(message) : null;
31
30
  const result = await notificationsService.createOne({
32
31
  recipient,
33
32
  sender: (_a = customAccountability === null || customAccountability === void 0 ? void 0 : customAccountability.user) !== null && _a !== void 0 ? _a : null,
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
- const parse_json_1 = require("../../utils/parse-json");
5
4
  exports.default = (0, utils_1.defineOperationApi)({
6
5
  id: 'transform',
7
6
  handler: ({ json }) => {
8
- return (0, parse_json_1.parseJSON)(json);
7
+ return (0, utils_1.parseJSON)(json);
9
8
  },
10
9
  });
@@ -2,13 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
4
  const flows_1 = require("../../flows");
5
- const operation_options_1 = require("../../utils/operation-options");
6
5
  exports.default = (0, utils_1.defineOperationApi)({
7
6
  id: 'trigger',
8
7
  handler: async ({ flow, payload }, context) => {
9
8
  var _a;
10
9
  const flowManager = (0, flows_1.getFlowManager)();
11
- const payloadObject = (_a = (0, operation_options_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
10
+ const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
12
11
  let result;
13
12
  if (Array.isArray(payloadObject)) {
14
13
  result = await Promise.all(payloadObject.map((payload) => flowManager.runOperationFlow(flow, payload, context)));
package/dist/server.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];
@@ -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];
@@ -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];
@@ -1,12 +1,12 @@
1
1
  import SchemaInspector from '@directus/schema';
2
+ import { Accountability, Field, RawField, SchemaOverview, Type } from '@directus/shared/types';
3
+ import Keyv from 'keyv';
2
4
  import { Knex } from 'knex';
3
5
  import { Column } from 'knex-schema-inspector/dist/types/column';
6
+ import { Helpers } from '../database/helpers';
4
7
  import { ItemsService } from '../services/items';
5
8
  import { PayloadService } from '../services/payload';
6
9
  import { AbstractServiceOptions } from '../types';
7
- import { Field, RawField, Type, Accountability, SchemaOverview } from '@directus/shared/types';
8
- import { Helpers } from '../database/helpers';
9
- import Keyv from 'keyv';
10
10
  export declare class FieldsService {
11
11
  knex: Knex;
12
12
  helpers: Helpers;
@@ -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];
@@ -24,9 +28,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
28
  Object.defineProperty(exports, "__esModule", { value: true });
25
29
  exports.FieldsService = void 0;
26
30
  const schema_1 = __importDefault(require("@directus/schema"));
31
+ const constants_1 = require("@directus/shared/constants");
32
+ const utils_1 = require("@directus/shared/utils");
33
+ const lodash_1 = require("lodash");
27
34
  const cache_1 = require("../cache");
28
- const constants_1 = require("../constants");
35
+ const constants_2 = require("../constants");
29
36
  const database_1 = __importStar(require("../database"));
37
+ const helpers_1 = require("../database/helpers");
30
38
  const fields_1 = require("../database/system-data/fields/");
31
39
  const emitter_1 = __importDefault(require("../emitter"));
32
40
  const env_1 = __importDefault(require("../env"));
@@ -36,11 +44,8 @@ const items_1 = require("../services/items");
36
44
  const payload_1 = require("../services/payload");
37
45
  const get_default_value_1 = __importDefault(require("../utils/get-default-value"));
38
46
  const get_local_type_1 = __importDefault(require("../utils/get-local-type"));
39
- const utils_1 = require("@directus/shared/utils");
40
- const lodash_1 = require("lodash");
41
47
  const relations_1 = require("./relations");
42
- const helpers_1 = require("../database/helpers");
43
- const constants_2 = require("@directus/shared/constants");
48
+ const constants_3 = require("@directus/shared/constants");
44
49
  class FieldsService {
45
50
  constructor(options) {
46
51
  this.knex = options.knex || (0, database_1.default)();
@@ -112,7 +117,7 @@ class FieldsService {
112
117
  }
113
118
  aliasFields = aliasFields.filter((field) => {
114
119
  const specials = (0, utils_1.toArray)(field.special);
115
- for (const type of constants_1.ALIAS_TYPES) {
120
+ for (const type of constants_2.ALIAS_TYPES) {
116
121
  if (specials.includes(type))
117
122
  return true;
118
123
  }
@@ -190,7 +195,6 @@ class FieldsService {
190
195
  fields_1.systemFieldRows.find((fieldMeta) => fieldMeta.collection === collection && fieldMeta.field === field);
191
196
  try {
192
197
  column = await this.schemaInspector.columnInfo(collection, field);
193
- column.default_value = (0, get_default_value_1.default)(column);
194
198
  }
195
199
  catch {
196
200
  // Do nothing
@@ -198,12 +202,18 @@ class FieldsService {
198
202
  if (!column && !fieldInfo)
199
203
  throw new exceptions_1.ForbiddenException();
200
204
  const type = (0, get_local_type_1.default)(column, fieldInfo);
205
+ const columnWithCastDefaultValue = column
206
+ ? {
207
+ ...column,
208
+ default_value: (0, get_default_value_1.default)(column),
209
+ }
210
+ : null;
201
211
  const data = {
202
212
  collection,
203
213
  field,
204
214
  type,
205
215
  meta: fieldInfo || null,
206
- schema: type === 'alias' ? null : column,
216
+ schema: type === 'alias' ? null : columnWithCastDefaultValue,
207
217
  };
208
218
  return data;
209
219
  }
@@ -237,7 +247,7 @@ class FieldsService {
237
247
  schema: this.schema,
238
248
  accountability: this.accountability,
239
249
  });
240
- if (hookAdjustedField.type && constants_1.ALIAS_TYPES.includes(hookAdjustedField.type) === false) {
250
+ if (hookAdjustedField.type && constants_2.ALIAS_TYPES.includes(hookAdjustedField.type) === false) {
241
251
  if (table) {
242
252
  this.addColumnToTable(table, hookAdjustedField);
243
253
  }
@@ -472,10 +482,12 @@ class FieldsService {
472
482
  else if (field.type.startsWith('geometry')) {
473
483
  column = this.helpers.st.createColumn(table, field);
474
484
  }
475
- else {
476
- // @ts-ignore
485
+ else if (constants_3.KNEX_TYPES.includes(field.type)) {
477
486
  column = table[field.type](field.field);
478
487
  }
488
+ else {
489
+ throw new exceptions_1.InvalidPayloadException(`Illegal type passed: "${field.type}"`);
490
+ }
479
491
  if (((_f = field.schema) === null || _f === void 0 ? void 0 : _f.default_value) !== undefined) {
480
492
  if (typeof field.schema.default_value === 'string' &&
481
493
  (field.schema.default_value.toLowerCase() === 'now()' || field.schema.default_value === 'CURRENT_TIMESTAMP')) {
@@ -484,13 +496,9 @@ class FieldsService {
484
496
  else if (typeof field.schema.default_value === 'string' &&
485
497
  field.schema.default_value.includes('CURRENT_TIMESTAMP(') &&
486
498
  field.schema.default_value.includes(')')) {
487
- const precision = field.schema.default_value.match(constants_2.REGEX_BETWEEN_PARENS)[1];
499
+ const precision = field.schema.default_value.match(constants_1.REGEX_BETWEEN_PARENS)[1];
488
500
  column.defaultTo(this.knex.fn.now(Number(precision)));
489
501
  }
490
- else if (typeof field.schema.default_value === 'string' &&
491
- ['"null"', 'null'].includes(field.schema.default_value.toLowerCase())) {
492
- column.defaultTo(null);
493
- }
494
502
  else {
495
503
  column.defaultTo(field.schema.default_value);
496
504
  }