directus 9.4.3 → 9.5.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 (108) hide show
  1. package/README.md +1 -1
  2. package/dist/auth/auth.d.ts +2 -1
  3. package/dist/auth/drivers/oauth2.js +10 -20
  4. package/dist/auth/drivers/openid.js +12 -2
  5. package/dist/cli/commands/init/questions.d.ts +3 -0
  6. package/dist/cli/commands/init/questions.js +2 -0
  7. package/dist/cli/utils/create-db-connection.d.ts +1 -1
  8. package/dist/cli/utils/create-db-connection.js +11 -1
  9. package/dist/cli/utils/drivers.d.ts +1 -0
  10. package/dist/cli/utils/drivers.js +2 -1
  11. package/dist/controllers/files.js +1 -1
  12. package/dist/controllers/utils.js +2 -0
  13. package/dist/database/helpers/date/index.d.ts +1 -0
  14. package/dist/database/helpers/date/index.js +3 -1
  15. package/dist/database/helpers/geometry/index.d.ts +1 -0
  16. package/dist/database/helpers/geometry/index.js +3 -1
  17. package/dist/database/helpers/index.d.ts +2 -0
  18. package/dist/database/helpers/index.js +2 -0
  19. package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +16 -0
  20. package/dist/database/helpers/schema/dialects/cockroachdb.js +16 -0
  21. package/dist/database/helpers/schema/dialects/default.d.ts +3 -0
  22. package/dist/database/helpers/schema/dialects/default.js +7 -0
  23. package/dist/database/helpers/schema/dialects/oracle.d.ts +12 -0
  24. package/dist/database/helpers/schema/dialects/oracle.js +13 -0
  25. package/dist/database/helpers/schema/index.d.ts +7 -0
  26. package/dist/database/helpers/schema/index.js +17 -0
  27. package/dist/database/helpers/schema/types.d.ts +25 -0
  28. package/dist/database/helpers/schema/types.js +89 -0
  29. package/dist/database/index.d.ts +1 -1
  30. package/dist/database/index.js +33 -16
  31. package/dist/database/migrations/20201105B-change-webhook-url-type.js +6 -25
  32. package/dist/database/migrations/20210312A-webhooks-collections-text.js +6 -25
  33. package/dist/database/migrations/20210415A-make-filesize-nullable.js +9 -4
  34. package/dist/database/migrations/20210506A-rename-interfaces.js +1 -1
  35. package/dist/database/migrations/20210510A-restructure-relations.js +12 -4
  36. package/dist/database/migrations/20210525A-add-insights.js +2 -2
  37. package/dist/database/migrations/20210626A-change-filesize-bigint.js +5 -7
  38. package/dist/database/migrations/20210903A-add-auth-provider.js +11 -2
  39. package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +6 -20
  40. package/dist/database/migrations/20210920A-webhooks-url-not-null.js +10 -14
  41. package/dist/database/migrations/20211211A-add-shares.js +2 -2
  42. package/dist/database/run-ast.d.ts +1 -1
  43. package/dist/database/seeds/01-collections.yaml +1 -0
  44. package/dist/database/seeds/02-roles.yaml +1 -0
  45. package/dist/database/seeds/03-users.yaml +1 -0
  46. package/dist/database/system-data/relations/index.d.ts +1 -1
  47. package/dist/emitter.d.ts +3 -4
  48. package/dist/emitter.js +2 -8
  49. package/dist/exceptions/database/translate.js +1 -0
  50. package/dist/exceptions/index.d.ts +1 -0
  51. package/dist/exceptions/index.js +1 -0
  52. package/dist/exceptions/unsupported-media-type.d.ts +4 -0
  53. package/dist/exceptions/unsupported-media-type.js +10 -0
  54. package/dist/extensions.d.ts +6 -5
  55. package/dist/extensions.js +56 -42
  56. package/dist/logger.js +22 -1
  57. package/dist/services/authentication.d.ts +2 -2
  58. package/dist/services/authentication.js +3 -1
  59. package/dist/services/authorization.d.ts +2 -3
  60. package/dist/services/collections.d.ts +2 -2
  61. package/dist/services/collections.js +10 -6
  62. package/dist/services/fields.d.ts +2 -3
  63. package/dist/services/fields.js +8 -4
  64. package/dist/services/graphql.d.ts +2 -1
  65. package/dist/services/import.d.ts +2 -2
  66. package/dist/services/import.js +2 -1
  67. package/dist/services/items.d.ts +2 -2
  68. package/dist/services/items.js +22 -18
  69. package/dist/services/mail/index.d.ts +2 -2
  70. package/dist/services/meta.d.ts +2 -2
  71. package/dist/services/payload.d.ts +2 -2
  72. package/dist/services/relations.d.ts +2 -2
  73. package/dist/services/server.d.ts +2 -2
  74. package/dist/services/specifications.d.ts +2 -2
  75. package/dist/services/users.d.ts +2 -3
  76. package/dist/services/utils.d.ts +2 -2
  77. package/dist/types/ast.d.ts +1 -2
  78. package/dist/types/auth.d.ts +1 -3
  79. package/dist/types/index.d.ts +0 -3
  80. package/dist/types/index.js +0 -3
  81. package/dist/types/services.d.ts +1 -3
  82. package/dist/types/snapshot.d.ts +1 -2
  83. package/dist/utils/apply-query.d.ts +1 -2
  84. package/dist/utils/apply-query.js +1 -1
  85. package/dist/utils/apply-snapshot.d.ts +2 -1
  86. package/dist/utils/get-ast-from-query.d.ts +2 -3
  87. package/dist/utils/get-permissions.d.ts +1 -2
  88. package/dist/utils/get-relation-type.d.ts +1 -1
  89. package/dist/utils/get-schema.d.ts +1 -2
  90. package/dist/utils/get-snapshot.d.ts +2 -1
  91. package/dist/utils/merge-permissions-for-share.d.ts +1 -2
  92. package/dist/utils/reduce-schema.d.ts +1 -2
  93. package/example.env +8 -0
  94. package/package.json +15 -14
  95. package/dist/cli/index.test.d.ts +0 -1
  96. package/dist/cli/index.test.js +0 -58
  97. package/dist/middleware/cache.test.d.ts +0 -1
  98. package/dist/middleware/cache.test.js +0 -62
  99. package/dist/tests/database/migrations/run.test.d.ts +0 -1
  100. package/dist/tests/database/migrations/run.test.js +0 -29
  101. package/dist/types/extensions.d.ts +0 -43
  102. package/dist/types/extensions.js +0 -2
  103. package/dist/types/relation.d.ts +0 -21
  104. package/dist/types/relation.js +0 -2
  105. package/dist/types/schema.d.ts +0 -32
  106. package/dist/types/schema.js +0 -2
  107. package/dist/utils/get-cache-key.test.d.ts +0 -1
  108. package/dist/utils/get-cache-key.test.js +0 -53
@@ -56,22 +56,27 @@ function getExtensionManager() {
56
56
  return extensionManager;
57
57
  }
58
58
  exports.getExtensionManager = getExtensionManager;
59
+ const defaultOptions = {
60
+ schedule: true,
61
+ watch: env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development',
62
+ };
59
63
  class ExtensionManager {
60
64
  constructor() {
61
65
  this.isLoaded = false;
62
- this.isScheduleHookEnabled = true;
63
66
  this.extensions = [];
64
67
  this.appExtensions = {};
65
68
  this.apiExtensions = { hooks: [], endpoints: [] };
66
69
  this.watcher = null;
70
+ this.options = defaultOptions;
67
71
  this.apiEmitter = new emitter_1.Emitter();
68
72
  this.endpointRouter = (0, express_1.Router)();
69
73
  }
70
- async initialize({ schedule, watch } = { schedule: true, watch: true }) {
71
- this.isScheduleHookEnabled = schedule;
72
- if (watch) {
73
- this.initializeWatcher();
74
- }
74
+ async initialize(options = {}) {
75
+ this.options = {
76
+ ...defaultOptions,
77
+ ...options,
78
+ };
79
+ this.initializeWatcher();
75
80
  if (!this.isLoaded) {
76
81
  await this.load();
77
82
  this.updateWatchedExtensions(this.extensions);
@@ -143,9 +148,9 @@ class ExtensionManager {
143
148
  this.isLoaded = false;
144
149
  }
145
150
  initializeWatcher() {
146
- if (env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development' && !this.watcher) {
151
+ if (this.options.watch && !this.watcher) {
147
152
  logger_1.default.info('Watching extensions for changes...');
148
- const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.resolve(env_1.default.EXTENSIONS_PATH, (0, utils_1.pluralize)(type)));
153
+ const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.posix.join(path_1.default.relative('.', env_1.default.EXTENSIONS_PATH).split(path_1.default.sep).join(path_1.default.posix.sep), (0, utils_1.pluralize)(type), '*', 'index.js'));
149
154
  this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
150
155
  ignoreInitial: true,
151
156
  });
@@ -182,15 +187,21 @@ class ExtensionManager {
182
187
  const bundles = {};
183
188
  for (const extensionType of constants_1.APP_EXTENSION_TYPES) {
184
189
  const entry = (0, node_1.generateExtensionsEntry)(extensionType, this.extensions);
185
- const bundle = await (0, rollup_1.rollup)({
186
- input: 'entry',
187
- external: Object.values(sharedDepsMapping),
188
- makeAbsoluteExternalsRelative: false,
189
- plugins: [(0, plugin_virtual_1.default)({ entry }), (0, plugin_alias_1.default)({ entries: internalImports })],
190
- });
191
- const { output } = await bundle.generate({ format: 'es', compact: true });
192
- bundles[extensionType] = output[0].code;
193
- await bundle.close();
190
+ try {
191
+ const bundle = await (0, rollup_1.rollup)({
192
+ input: 'entry',
193
+ external: Object.values(sharedDepsMapping),
194
+ makeAbsoluteExternalsRelative: false,
195
+ plugins: [(0, plugin_virtual_1.default)({ entry }), (0, plugin_alias_1.default)({ entries: internalImports })],
196
+ });
197
+ const { output } = await bundle.generate({ format: 'es', compact: true });
198
+ bundles[extensionType] = output[0].code;
199
+ await bundle.close();
200
+ }
201
+ catch (error) {
202
+ logger_1.default.warn(`Couldn't bundle App extensions`);
203
+ logger_1.default.warn(error);
204
+ }
194
205
  }
195
206
  return bundles;
196
207
  }
@@ -238,38 +249,39 @@ class ExtensionManager {
238
249
  const hookPath = path_1.default.resolve(hook.path, hook.entrypoint || '');
239
250
  const hookInstance = require(hookPath);
240
251
  const register = (0, get_module_default_1.default)(hookInstance);
252
+ const hookHandler = {
253
+ path: hookPath,
254
+ events: [],
255
+ };
241
256
  const registerFunctions = {
242
257
  filter: (event, handler) => {
243
258
  emitter_1.default.onFilter(event, handler);
244
- this.apiExtensions.hooks.push({
259
+ hookHandler.events.push({
245
260
  type: 'filter',
246
- path: hookPath,
247
- event,
261
+ name: event,
248
262
  handler,
249
263
  });
250
264
  },
251
265
  action: (event, handler) => {
252
266
  emitter_1.default.onAction(event, handler);
253
- this.apiExtensions.hooks.push({
267
+ hookHandler.events.push({
254
268
  type: 'action',
255
- path: hookPath,
256
- event,
269
+ name: event,
257
270
  handler,
258
271
  });
259
272
  },
260
273
  init: (event, handler) => {
261
274
  emitter_1.default.onInit(event, handler);
262
- this.apiExtensions.hooks.push({
275
+ hookHandler.events.push({
263
276
  type: 'init',
264
- path: hookPath,
265
- event,
277
+ name: event,
266
278
  handler,
267
279
  });
268
280
  },
269
281
  schedule: (cron, handler) => {
270
282
  if ((0, node_cron_1.validate)(cron)) {
271
283
  const task = (0, node_cron_1.schedule)(cron, async () => {
272
- if (this.isScheduleHookEnabled) {
284
+ if (this.options.schedule) {
273
285
  try {
274
286
  await handler();
275
287
  }
@@ -278,9 +290,8 @@ class ExtensionManager {
278
290
  }
279
291
  }
280
292
  });
281
- this.apiExtensions.hooks.push({
293
+ hookHandler.events.push({
282
294
  type: 'schedule',
283
- path: hookPath,
284
295
  task,
285
296
  });
286
297
  }
@@ -298,6 +309,7 @@ class ExtensionManager {
298
309
  logger: logger_1.default,
299
310
  getSchema: get_schema_1.getSchema,
300
311
  });
312
+ this.apiExtensions.hooks.push(hookHandler);
301
313
  }
302
314
  registerEndpoint(endpoint, router) {
303
315
  const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint || '');
@@ -322,19 +334,21 @@ class ExtensionManager {
322
334
  }
323
335
  unregisterHooks() {
324
336
  for (const hook of this.apiExtensions.hooks) {
325
- switch (hook.type) {
326
- case 'filter':
327
- emitter_1.default.offFilter(hook.event, hook.handler);
328
- break;
329
- case 'action':
330
- emitter_1.default.offAction(hook.event, hook.handler);
331
- break;
332
- case 'init':
333
- emitter_1.default.offInit(hook.event, hook.handler);
334
- break;
335
- case 'schedule':
336
- hook.task.stop();
337
- break;
337
+ for (const event of hook.events) {
338
+ switch (event.type) {
339
+ case 'filter':
340
+ emitter_1.default.offFilter(event.name, event.handler);
341
+ break;
342
+ case 'action':
343
+ emitter_1.default.offAction(event.name, event.handler);
344
+ break;
345
+ case 'init':
346
+ emitter_1.default.offInit(event.name, event.handler);
347
+ break;
348
+ case 'schedule':
349
+ event.task.stop();
350
+ break;
351
+ }
338
352
  }
339
353
  delete require.cache[require.resolve(hook.path)];
340
354
  }
package/dist/logger.js CHANGED
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.expressLogger = void 0;
26
26
  const pino_1 = __importDefault(require("pino"));
27
27
  const pino_http_1 = __importStar(require("pino-http"));
28
+ const get_config_from_env_1 = require("./utils/get-config-from-env");
28
29
  const url_1 = require("url");
29
30
  const env_1 = __importDefault(require("./env"));
30
31
  const pinoOptions = {
@@ -38,9 +39,29 @@ if (env_1.default.LOG_STYLE !== 'raw') {
38
39
  pinoOptions.prettyPrint = true;
39
40
  pinoOptions.prettifier = require('pino-colada');
40
41
  }
41
- const logger = (0, pino_1.default)(pinoOptions);
42
+ const loggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_', 'LOGGER_HTTP');
43
+ // Expose custom log levels into formatter function
44
+ if (loggerEnvConfig.levels) {
45
+ const customLogLevels = {};
46
+ for (const el of loggerEnvConfig.levels.split(',')) {
47
+ const key_val = el.split(':');
48
+ customLogLevels[key_val[0].trim()] = key_val[1].trim();
49
+ }
50
+ pinoOptions.formatters = {
51
+ level(label, number) {
52
+ return {
53
+ severity: customLogLevels[label] || 'info',
54
+ level: number,
55
+ };
56
+ },
57
+ };
58
+ delete loggerEnvConfig.levels;
59
+ }
60
+ const logger = (0, pino_1.default)(Object.assign(pinoOptions, loggerEnvConfig));
61
+ const httpLoggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_HTTP', ['LOGGER_HTTP_LOGGER']);
42
62
  exports.expressLogger = (0, pino_http_1.default)({
43
63
  logger,
64
+ ...httpLoggerEnvConfig,
44
65
  }, {
45
66
  serializers: {
46
67
  req(request) {
@@ -1,7 +1,7 @@
1
1
  import { Knex } from 'knex';
2
2
  import { ActivityService } from './activity';
3
- import { AbstractServiceOptions, SchemaOverview, LoginResult } from '../types';
4
- import { Accountability } from '@directus/shared/types';
3
+ import { AbstractServiceOptions, LoginResult } from '../types';
4
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
5
5
  export declare class AuthenticationService {
6
6
  knex: Knex;
7
7
  accountability: Accountability | null;
@@ -204,7 +204,9 @@ class AuthenticationService {
204
204
  .from('directus_sessions AS s')
205
205
  .leftJoin('directus_users AS u', 's.user', 'u.id')
206
206
  .leftJoin('directus_shares AS d', 's.share', 'd.id')
207
- .joinRaw('LEFT JOIN directus_roles AS r ON r.id IN (u.role, d.role)')
207
+ .leftJoin('directus_roles AS r', (join) => {
208
+ join.onIn('r.id', [this.knex.ref('u.role'), this.knex.ref('d.role')]);
209
+ })
208
210
  .where('s.token', refreshToken)
209
211
  .andWhere('s.expires', '>=', new Date())
210
212
  .andWhere((subQuery) => {
@@ -1,7 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { Accountability } from '@directus/shared/types';
3
- import { AbstractServiceOptions, AST, Item, PrimaryKey, SchemaOverview } from '../types';
4
- import { PermissionsAction } from '@directus/shared/types';
2
+ import { AbstractServiceOptions, AST, Item, PrimaryKey } from '../types';
3
+ import { PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types';
5
4
  import { PayloadService } from './payload';
6
5
  export declare class AuthorizationService {
7
6
  knex: Knex;
@@ -1,8 +1,8 @@
1
1
  import SchemaInspector from '@directus/schema';
2
2
  import { Knex } from 'knex';
3
3
  import Keyv from 'keyv';
4
- import { AbstractServiceOptions, Collection, CollectionMeta, SchemaOverview, MutationOptions } from '../types';
5
- import { Accountability, RawField } from '@directus/shared/types';
4
+ import { AbstractServiceOptions, Collection, CollectionMeta, MutationOptions } from '../types';
5
+ import { Accountability, RawField, SchemaOverview } from '@directus/shared/types';
6
6
  import { Table } from 'knex-schema-inspector/dist/types/table';
7
7
  export declare type RawCollection = {
8
8
  collection: string;
@@ -114,12 +114,14 @@ class CollectionsService {
114
114
  }
115
115
  return field;
116
116
  });
117
- await trx.schema.createTable(payload.collection, (table) => {
118
- for (const field of payload.fields) {
119
- if (field.type && constants_1.ALIAS_TYPES.includes(field.type) === false) {
120
- fieldsService.addColumnToTable(table, field);
117
+ await trx.transaction(async (schemaTrx) => {
118
+ await schemaTrx.schema.createTable(payload.collection, (table) => {
119
+ for (const field of payload.fields) {
120
+ if (field.type && constants_1.ALIAS_TYPES.includes(field.type) === false) {
121
+ fieldsService.addColumnToTable(table, field);
122
+ }
121
123
  }
122
- }
124
+ });
123
125
  });
124
126
  const fieldPayloads = payload.fields.filter((field) => field.meta).map((field) => field.meta);
125
127
  await fieldItemsService.createMany(fieldPayloads);
@@ -371,7 +373,9 @@ class CollectionsService {
371
373
  .update({ one_allowed_collections: newAllowedCollections })
372
374
  .where({ id: relation.meta.id });
373
375
  }
374
- await trx.schema.dropTable(collectionKey);
376
+ await trx.transaction(async (schemaTrx) => {
377
+ await schemaTrx.schema.dropTable(collectionKey);
378
+ });
375
379
  }
376
380
  });
377
381
  if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
@@ -3,9 +3,8 @@ import { Knex } from 'knex';
3
3
  import { Column } from 'knex-schema-inspector/dist/types/column';
4
4
  import { ItemsService } from '../services/items';
5
5
  import { PayloadService } from '../services/payload';
6
- import { AbstractServiceOptions, SchemaOverview } from '../types';
7
- import { Accountability } from '@directus/shared/types';
8
- import { Field, RawField, Type } from '@directus/shared/types';
6
+ import { AbstractServiceOptions } from '../types';
7
+ import { Field, RawField, Type, Accountability, SchemaOverview } from '@directus/shared/types';
9
8
  import { Helpers } from '../database/helpers';
10
9
  import Keyv from 'keyv';
11
10
  export declare class FieldsService {
@@ -224,8 +224,10 @@ class FieldsService {
224
224
  this.addColumnToTable(table, hookAdjustedField);
225
225
  }
226
226
  else {
227
- await trx.schema.alterTable(collection, (table) => {
228
- this.addColumnToTable(table, hookAdjustedField);
227
+ await trx.transaction(async (schemaTrx) => {
228
+ await schemaTrx.schema.alterTable(collection, (table) => {
229
+ this.addColumnToTable(table, hookAdjustedField);
230
+ });
229
231
  });
230
232
  }
231
233
  }
@@ -387,8 +389,10 @@ class FieldsService {
387
389
  if (this.schema.collections[collection] &&
388
390
  field in this.schema.collections[collection].fields &&
389
391
  this.schema.collections[collection].fields[field].alias === false) {
390
- await trx.schema.table(collection, (table) => {
391
- table.dropColumn(field);
392
+ await trx.transaction(async (schemaTrx) => {
393
+ await schemaTrx.schema.table(collection, (table) => {
394
+ table.dropColumn(field);
395
+ });
392
396
  });
393
397
  }
394
398
  });
@@ -1,9 +1,10 @@
1
1
  import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema, ObjectFieldNode, SelectionNode } from 'graphql';
2
+ import { SchemaOverview } from '@directus/shared/types';
2
3
  import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
3
4
  import { Knex } from 'knex';
4
5
  import { BaseException } from '@directus/shared/exceptions';
5
6
  import { Accountability, Query } from '@directus/shared/types';
6
- import { AbstractServiceOptions, GraphQLParams, Item, SchemaOverview } from '../types';
7
+ import { AbstractServiceOptions, GraphQLParams, Item } from '../types';
7
8
  import { ItemsService } from './items';
8
9
  export declare const GraphQLGeoJSON: GraphQLScalarType;
9
10
  export declare const GraphQLDate: GraphQLScalarType;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { Knex } from 'knex';
3
- import { AbstractServiceOptions, SchemaOverview } from '../types';
4
- import { Accountability } from '@directus/shared/types';
3
+ import { AbstractServiceOptions } from '../types';
4
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
5
5
  export declare class ImportService {
6
6
  knex: Knex;
7
7
  accountability: Accountability | null;
@@ -31,9 +31,10 @@ class ImportService {
31
31
  case 'application/json':
32
32
  return await this.importJSON(collection, stream);
33
33
  case 'text/csv':
34
+ case 'application/vnd.ms-excel':
34
35
  return await this.importCSV(collection, stream);
35
36
  default:
36
- throw new exceptions_1.InvalidPayloadException(`Can't import files of type "${mimetype}"`);
37
+ throw new exceptions_1.UnsupportedMediaTypeException(`Can't import files of type "${mimetype}"`);
37
38
  }
38
39
  }
39
40
  importJSON(collection, stream) {
@@ -1,7 +1,7 @@
1
1
  import { Knex } from 'knex';
2
2
  import Keyv from 'keyv';
3
- import { Accountability, Query, PermissionsAction } from '@directus/shared/types';
4
- import { AbstractService, AbstractServiceOptions, Item as AnyItem, PrimaryKey, SchemaOverview, MutationOptions } from '../types';
3
+ import { Accountability, Query, PermissionsAction, SchemaOverview } from '@directus/shared/types';
4
+ import { AbstractService, AbstractServiceOptions, Item as AnyItem, PrimaryKey, MutationOptions } from '../types';
5
5
  export declare type QueryOptions = {
6
6
  stripNonRequested?: boolean;
7
7
  permissionsAction?: PermissionsAction;
@@ -70,7 +70,9 @@ class ItemsService {
70
70
  // Run all hooks that are attached to this event so the end user has the chance to augment the
71
71
  // item that is about to be saved
72
72
  const payloadAfterHooks = (opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false
73
- ? await emitter_1.default.emitFilter(`${this.eventScope}.create`, payload, {
73
+ ? await emitter_1.default.emitFilter(this.eventScope === 'items'
74
+ ? ['items.create', `${this.collection}.items.create`]
75
+ : `${this.eventScope}.create`, payload, {
74
76
  collection: this.collection,
75
77
  }, {
76
78
  database: trx,
@@ -85,7 +87,7 @@ class ItemsService {
85
87
  const { payload: payloadWithA2O, revisions: revisionsA2O } = await payloadService.processA2O(payloadWithM2O);
86
88
  const payloadWithoutAliases = (0, lodash_1.pick)(payloadWithA2O, (0, lodash_1.without)(fields, ...aliases));
87
89
  const payloadWithTypeCasting = await payloadService.processValues('create', payloadWithoutAliases);
88
- // In case of manual string / UUID primary keys, they PK already exists in the object we're saving.
90
+ // In case of manual string / UUID primary keys, the PK already exists in the object we're saving.
89
91
  let primaryKey = payloadWithTypeCasting[primaryKeyField];
90
92
  try {
91
93
  const result = await trx.insert(payloadWithoutAliases).into(this.collection).returning(primaryKeyField);
@@ -146,14 +148,14 @@ class ItemsService {
146
148
  return primaryKey;
147
149
  });
148
150
  if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
149
- emitter_1.default.emitAction(`${this.eventScope}.create`, {
151
+ emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.create', `${this.collection}.items.create`] : `${this.eventScope}.create`, {
150
152
  payload,
151
153
  key: primaryKey,
152
154
  collection: this.collection,
153
155
  }, {
154
156
  // This hook is called async. If we would pass the transaction here, the hook can be
155
157
  // called after the transaction is done #5460
156
- database: (0, database_1.default)(),
158
+ database: this.knex || (0, database_1.default)(),
157
159
  schema: this.schema,
158
160
  accountability: this.accountability,
159
161
  });
@@ -189,11 +191,6 @@ class ItemsService {
189
191
  * Get items by query
190
192
  */
191
193
  async readByQuery(query, opts) {
192
- const authorizationService = new authorization_1.AuthorizationService({
193
- accountability: this.accountability,
194
- knex: this.knex,
195
- schema: this.schema,
196
- });
197
194
  let ast = await (0, get_ast_from_query_1.default)(this.collection, query, this.schema, {
198
195
  accountability: this.accountability,
199
196
  // By setting the permissions action, you can read items using the permissions for another
@@ -203,6 +200,11 @@ class ItemsService {
203
200
  knex: this.knex,
204
201
  });
205
202
  if (this.accountability && this.accountability.admin !== true) {
203
+ const authorizationService = new authorization_1.AuthorizationService({
204
+ accountability: this.accountability,
205
+ knex: this.knex,
206
+ schema: this.schema,
207
+ });
206
208
  ast = await authorizationService.processAST(ast, opts === null || opts === void 0 ? void 0 : opts.permissionsAction);
207
209
  }
208
210
  const records = await (0, run_ast_1.default)(ast, this.schema, {
@@ -213,7 +215,7 @@ class ItemsService {
213
215
  if (records === null) {
214
216
  throw new exceptions_1.ForbiddenException();
215
217
  }
216
- const filteredRecords = await emitter_1.default.emitFilter(`${this.eventScope}.read`, records, {
218
+ const filteredRecords = await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, records, {
217
219
  query,
218
220
  collection: this.collection,
219
221
  }, {
@@ -221,12 +223,12 @@ class ItemsService {
221
223
  schema: this.schema,
222
224
  accountability: this.accountability,
223
225
  });
224
- emitter_1.default.emitAction(`${this.eventScope}.read`, {
226
+ emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, {
225
227
  payload: filteredRecords,
226
228
  query,
227
229
  collection: this.collection,
228
230
  }, {
229
- database: (0, database_1.default)(),
231
+ database: this.knex || (0, database_1.default)(),
230
232
  schema: this.schema,
231
233
  accountability: this.accountability,
232
234
  });
@@ -288,7 +290,9 @@ class ItemsService {
288
290
  // Run all hooks that are attached to this event so the end user has the chance to augment the
289
291
  // item that is about to be saved
290
292
  const payloadAfterHooks = (opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false
291
- ? await emitter_1.default.emitFilter(`${this.eventScope}.update`, payload, {
293
+ ? await emitter_1.default.emitFilter(this.eventScope === 'items'
294
+ ? ['items.update', `${this.collection}.items.update`]
295
+ : `${this.eventScope}.update`, payload, {
292
296
  keys,
293
297
  collection: this.collection,
294
298
  }, {
@@ -379,14 +383,14 @@ class ItemsService {
379
383
  await this.cache.clear();
380
384
  }
381
385
  if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
382
- emitter_1.default.emitAction(`${this.eventScope}.update`, {
386
+ emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.update', `${this.collection}.items.update`] : `${this.eventScope}.update`, {
383
387
  payload,
384
388
  keys,
385
389
  collection: this.collection,
386
390
  }, {
387
391
  // This hook is called async. If we would pass the transaction here, the hook can be
388
392
  // called after the transaction is done #5460
389
- database: (0, database_1.default)(),
393
+ database: this.knex || (0, database_1.default)(),
390
394
  schema: this.schema,
391
395
  accountability: this.accountability,
392
396
  });
@@ -461,7 +465,7 @@ class ItemsService {
461
465
  await authorizationService.checkAccess('delete', this.collection, keys);
462
466
  }
463
467
  if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
464
- await emitter_1.default.emitFilter(`${this.eventScope}.delete`, keys, {
468
+ await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.delete', `${this.collection}.items.delete`] : `${this.eventScope}.delete`, keys, {
465
469
  collection: this.collection,
466
470
  }, {
467
471
  database: this.knex,
@@ -490,13 +494,13 @@ class ItemsService {
490
494
  await this.cache.clear();
491
495
  }
492
496
  if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
493
- emitter_1.default.emitAction(`${this.eventScope}.delete`, {
497
+ emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.delete', `${this.collection}.items.delete`] : `${this.eventScope}.delete`, {
494
498
  payload: keys,
495
499
  collection: this.collection,
496
500
  }, {
497
501
  // This hook is called async. If we would pass the transaction here, the hook can be
498
502
  // called after the transaction is done #5460
499
- database: (0, database_1.default)(),
503
+ database: this.knex || (0, database_1.default)(),
500
504
  schema: this.schema,
501
505
  accountability: this.accountability,
502
506
  });
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, SchemaOverview } from '../../types';
3
- import { Accountability } from '@directus/shared/types';
2
+ import { AbstractServiceOptions } from '../../types';
3
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
4
4
  import { Transporter, SendMailOptions } from 'nodemailer';
5
5
  export declare type EmailOptions = SendMailOptions & {
6
6
  template?: {
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, SchemaOverview } from '../types';
3
- import { Accountability, Query } from '@directus/shared/types';
2
+ import { AbstractServiceOptions } from '../types';
3
+ import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
4
4
  export declare class MetaService {
5
5
  knex: Knex;
6
6
  accountability: Accountability | null;
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, Item, PrimaryKey, SchemaOverview } from '../types';
3
- import { Accountability } from '@directus/shared/types';
2
+ import { AbstractServiceOptions, Item, PrimaryKey } from '../types';
3
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
4
4
  import { Helpers } from '../database/helpers';
5
5
  declare type Action = 'create' | 'read' | 'update';
6
6
  declare type Transformers = {
@@ -1,10 +1,10 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, SchemaOverview, Relation, RelationMeta } from '../types';
3
- import { Accountability } from '@directus/shared/types';
2
+ import { SchemaOverview, Relation, RelationMeta, Accountability } from '@directus/shared/types';
4
3
  import { ItemsService, QueryOptions } from './items';
5
4
  import { PermissionsService } from './permissions';
6
5
  import SchemaInspector from '@directus/schema';
7
6
  import Keyv from 'keyv';
7
+ import { AbstractServiceOptions } from '../types';
8
8
  export declare class RelationsService {
9
9
  knex: Knex;
10
10
  permissionsService: PermissionsService;
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, SchemaOverview } from '../types';
3
- import { Accountability } from '@directus/shared/types';
2
+ import { AbstractServiceOptions } from '../types';
3
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
4
4
  import { SettingsService } from './settings';
5
5
  export declare class ServerService {
6
6
  knex: Knex;
@@ -1,7 +1,7 @@
1
1
  import { Knex } from 'knex';
2
2
  import { OpenAPIObject } from 'openapi3-ts';
3
- import { AbstractServiceOptions, SchemaOverview } from '../types';
4
- import { Accountability } from '@directus/shared/types';
3
+ import { AbstractServiceOptions } from '../types';
4
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
5
5
  import { CollectionsService } from './collections';
6
6
  import { FieldsService } from './fields';
7
7
  import { GraphQLService } from './graphql';
@@ -1,7 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, Item, PrimaryKey, SchemaOverview, MutationOptions } from '../types';
3
- import { Query } from '@directus/shared/types';
4
- import { Accountability } from '@directus/shared/types';
2
+ import { AbstractServiceOptions, Item, PrimaryKey, MutationOptions } from '../types';
3
+ import { Query, SchemaOverview, Accountability } from '@directus/shared/types';
5
4
  import { ItemsService } from './items';
6
5
  export declare class UsersService extends ItemsService {
7
6
  knex: Knex;
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
- import { AbstractServiceOptions, PrimaryKey, SchemaOverview } from '../types';
3
- import { Accountability } from '@directus/shared/types';
2
+ import { AbstractServiceOptions, PrimaryKey } from '../types';
3
+ import { Accountability, SchemaOverview } from '@directus/shared/types';
4
4
  export declare class UtilsService {
5
5
  knex: Knex;
6
6
  accountability: Accountability | null;
@@ -1,5 +1,4 @@
1
- import { Query } from '@directus/shared/types';
2
- import { Relation } from './relation';
1
+ import { Query, Relation } from '@directus/shared/types';
3
2
  export declare type M2ONode = {
4
3
  type: 'm2o';
5
4
  name: string;
@@ -1,5 +1,5 @@
1
+ import { SchemaOverview } from '@directus/shared/types';
1
2
  import { Knex } from 'knex';
2
- import { SchemaOverview } from './schema';
3
3
  export interface AuthDriverOptions {
4
4
  knex: Knex;
5
5
  schema: SchemaOverview;
@@ -22,10 +22,8 @@ export declare type AuthData = Record<string, any> | null;
22
22
  export interface Session {
23
23
  token: string;
24
24
  expires: Date;
25
- data: string | Record<string, unknown> | null;
26
25
  share: string;
27
26
  }
28
- export declare type SessionData = Record<string, any> | null;
29
27
  export declare type DirectusTokenPayload = {
30
28
  id?: string;
31
29
  role: string | null;