directus 9.20.4 → 9.21.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 (135) hide show
  1. package/dist/cli/utils/create-db-connection.d.ts +1 -1
  2. package/dist/controllers/extensions.js +4 -13
  3. package/dist/database/helpers/date/dialects/sqlite.d.ts +1 -1
  4. package/dist/database/helpers/date/dialects/sqlite.js +4 -0
  5. package/dist/database/helpers/date/types.d.ts +1 -1
  6. package/dist/database/helpers/date/types.js +4 -0
  7. package/dist/database/helpers/fn/dialects/mssql.d.ts +8 -8
  8. package/dist/database/helpers/fn/dialects/mssql.js +22 -16
  9. package/dist/database/helpers/fn/dialects/mysql.d.ts +8 -8
  10. package/dist/database/helpers/fn/dialects/mysql.js +22 -16
  11. package/dist/database/helpers/fn/dialects/postgres.d.ts +8 -8
  12. package/dist/database/helpers/fn/dialects/postgres.js +22 -16
  13. package/dist/database/helpers/fn/types.d.ts +1 -1
  14. package/dist/database/helpers/index.d.ts +1 -1
  15. package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +1 -0
  16. package/dist/database/helpers/schema/dialects/cockroachdb.js +11 -0
  17. package/dist/database/helpers/schema/types.d.ts +3 -2
  18. package/dist/database/helpers/schema/types.js +5 -0
  19. package/dist/database/migrations/run.js +29 -3
  20. package/dist/database/run-ast.d.ts +1 -1
  21. package/dist/database/run-ast.js +1 -1
  22. package/dist/env.d.ts +4 -0
  23. package/dist/env.js +9 -4
  24. package/dist/env.test.d.ts +1 -8
  25. package/dist/exceptions/database/contains-null-values.d.ts +1 -1
  26. package/dist/exceptions/database/dialects/types.d.ts +6 -6
  27. package/dist/exceptions/database/invalid-foreign-key.d.ts +1 -1
  28. package/dist/exceptions/database/not-null-violation.d.ts +1 -1
  29. package/dist/exceptions/database/record-not-unique.d.ts +1 -1
  30. package/dist/exceptions/database/value-out-of-range.d.ts +1 -1
  31. package/dist/exceptions/database/value-too-long.d.ts +1 -1
  32. package/dist/exceptions/hit-rate-limit.d.ts +1 -1
  33. package/dist/exceptions/method-not-allowed.d.ts +1 -1
  34. package/dist/exceptions/service-unavailable.d.ts +1 -1
  35. package/dist/extensions.d.ts +7 -7
  36. package/dist/extensions.js +92 -89
  37. package/dist/logger.d.ts +1 -0
  38. package/dist/messenger.d.ts +1 -1
  39. package/dist/middleware/authenticate.d.ts +1 -0
  40. package/dist/middleware/validate-batch.d.ts +2 -0
  41. package/dist/operations/condition/index.d.ts +1 -1
  42. package/dist/operations/condition/index.js +1 -1
  43. package/dist/operations/condition/index.test.d.ts +1 -0
  44. package/dist/operations/exec/index.d.ts +1 -1
  45. package/dist/operations/item-create/index.d.ts +1 -1
  46. package/dist/operations/item-delete/index.d.ts +1 -1
  47. package/dist/operations/item-read/index.d.ts +1 -1
  48. package/dist/operations/item-update/index.d.ts +1 -1
  49. package/dist/operations/log/index.d.ts +1 -1
  50. package/dist/operations/mail/index.d.ts +1 -1
  51. package/dist/operations/notification/index.d.ts +1 -1
  52. package/dist/operations/request/index.d.ts +1 -1
  53. package/dist/operations/sleep/index.d.ts +1 -1
  54. package/dist/operations/transform/index.d.ts +1 -1
  55. package/dist/operations/trigger/index.d.ts +1 -1
  56. package/dist/operations/trigger/index.js +5 -2
  57. package/dist/rate-limiter.d.ts +1 -1
  58. package/dist/services/authorization.js +7 -3
  59. package/dist/services/collections.d.ts +1 -1
  60. package/dist/services/collections.js +112 -13
  61. package/dist/services/fields.d.ts +2 -2
  62. package/dist/services/fields.js +89 -41
  63. package/dist/services/fields.test.d.ts +1 -0
  64. package/dist/services/graphql/index.js +4 -1
  65. package/dist/services/graphql/utils/process-error.d.ts +4 -0
  66. package/dist/services/graphql/utils/process-error.js +26 -0
  67. package/dist/services/graphql/utils/process-error.test.d.ts +1 -0
  68. package/dist/services/items.d.ts +1 -1
  69. package/dist/services/items.js +39 -13
  70. package/dist/services/mail/index.d.ts +2 -2
  71. package/dist/services/mail/index.js +2 -1
  72. package/dist/services/mail/templates/base.liquid +4 -4
  73. package/dist/services/notifications.js +9 -4
  74. package/dist/services/notifications.test.d.ts +1 -0
  75. package/dist/services/payload.d.ts +2 -2
  76. package/dist/services/payload.js +14 -12
  77. package/dist/services/relations.d.ts +2 -2
  78. package/dist/services/relations.js +54 -4
  79. package/dist/services/users.js +2 -2
  80. package/dist/services/users.test.d.ts +1 -0
  81. package/dist/types/assets.d.ts +7 -7
  82. package/dist/types/ast.d.ts +7 -7
  83. package/dist/types/auth.d.ts +4 -4
  84. package/dist/types/collection.d.ts +2 -2
  85. package/dist/types/events.d.ts +1 -1
  86. package/dist/types/files.d.ts +2 -2
  87. package/dist/types/items.d.ts +5 -5
  88. package/dist/types/migration.d.ts +1 -1
  89. package/dist/types/revision.d.ts +1 -1
  90. package/dist/types/services.d.ts +1 -1
  91. package/dist/types/snapshot.d.ts +4 -4
  92. package/dist/types/webhooks.d.ts +2 -2
  93. package/dist/utils/get-ast-from-query.d.ts +1 -1
  94. package/dist/utils/get-column-path.d.ts +2 -2
  95. package/dist/utils/get-module-default.d.ts +1 -1
  96. package/dist/utils/get-relation-info.d.ts +1 -1
  97. package/dist/utils/job-queue.d.ts +1 -1
  98. package/dist/utils/merge-permissions.d.ts +1 -0
  99. package/dist/utils/reduce-schema.js +3 -1
  100. package/package.json +70 -71
  101. package/dist/__mocks__/cache.d.ts +0 -5
  102. package/dist/__mocks__/cache.js +0 -7
  103. package/dist/__utils__/items-utils.d.ts +0 -2
  104. package/dist/__utils__/items-utils.js +0 -36
  105. package/dist/__utils__/schemas.d.ts +0 -13
  106. package/dist/__utils__/schemas.js +0 -304
  107. package/dist/__utils__/snapshots.d.ts +0 -5
  108. package/dist/__utils__/snapshots.js +0 -897
  109. package/dist/cli/index.test.js +0 -63
  110. package/dist/controllers/files.test.js +0 -49
  111. package/dist/database/migrations/run.test.js +0 -92
  112. package/dist/env.test.js +0 -40
  113. package/dist/middleware/authenticate.test.js +0 -214
  114. package/dist/middleware/extract-token.test.js +0 -60
  115. package/dist/middleware/validate-batch.test.js +0 -82
  116. package/dist/operations/exec/index.test.js +0 -95
  117. package/dist/services/files.test.js +0 -89
  118. package/dist/services/items.test.js +0 -765
  119. package/dist/services/payload.test.js +0 -196
  120. package/dist/services/specifications.test.js +0 -96
  121. package/dist/utils/apply-snapshot.test.js +0 -305
  122. package/dist/utils/async-handler.test.js +0 -18
  123. package/dist/utils/calculate-field-depth.test.js +0 -76
  124. package/dist/utils/filter-items.test.js +0 -60
  125. package/dist/utils/get-auth-providers.test.js +0 -72
  126. package/dist/utils/get-cache-key.test.js +0 -74
  127. package/dist/utils/get-column-path.test.js +0 -136
  128. package/dist/utils/get-config-from-env.test.js +0 -19
  129. package/dist/utils/get-relation-info.test.js +0 -88
  130. package/dist/utils/get-relation-type.test.js +0 -69
  131. package/dist/utils/get-string-byte-size.test.js +0 -8
  132. package/dist/utils/is-directus-jwt.test.js +0 -26
  133. package/dist/utils/jwt.test.js +0 -36
  134. package/dist/utils/merge-permissions.test.js +0 -80
  135. package/dist/utils/validate-keys.test.js +0 -97
@@ -1,5 +1,5 @@
1
1
  import { BaseException } from '@directus/shared/exceptions';
2
- declare type Extensions = {
2
+ type Extensions = {
3
3
  allow: string[];
4
4
  };
5
5
  export declare class MethodNotAllowedException extends BaseException {
@@ -1,5 +1,5 @@
1
1
  import { BaseException } from '@directus/shared/exceptions';
2
- declare type Extensions = {
2
+ type Extensions = {
3
3
  service: string;
4
4
  [key: string]: any;
5
5
  };
@@ -1,7 +1,7 @@
1
1
  import { Router } from 'express';
2
- import { AppExtensionType, ExtensionType, HybridExtensionType } from '@directus/shared/types';
2
+ import { ExtensionType } from '@directus/shared/types';
3
3
  export declare function getExtensionManager(): ExtensionManager;
4
- declare type Options = {
4
+ type Options = {
5
5
  schedule: boolean;
6
6
  watch: boolean;
7
7
  };
@@ -12,6 +12,7 @@ declare class ExtensionManager {
12
12
  private appExtensions;
13
13
  private apiExtensions;
14
14
  private apiEmitter;
15
+ private hookEvents;
15
16
  private endpointRouter;
16
17
  private reloadQueue;
17
18
  private watcher;
@@ -19,7 +20,7 @@ declare class ExtensionManager {
19
20
  initialize(options?: Partial<Options>): Promise<void>;
20
21
  reload(): void;
21
22
  getExtensionsList(type?: ExtensionType): string[];
22
- getAppExtensions(type: AppExtensionType | HybridExtensionType): string | undefined;
23
+ getAppExtensions(): string | null;
23
24
  getEndpointRouter(): Router;
24
25
  private load;
25
26
  private unload;
@@ -27,16 +28,15 @@ declare class ExtensionManager {
27
28
  private closeWatcher;
28
29
  private updateWatchedExtensions;
29
30
  private getExtensions;
30
- private generateExtensionBundles;
31
+ private generateExtensionBundle;
31
32
  private getSharedDepsMapping;
32
33
  private registerHooks;
33
34
  private registerEndpoints;
34
35
  private registerOperations;
36
+ private registerBundles;
35
37
  private registerHook;
36
38
  private registerEndpoint;
37
39
  private registerOperation;
38
- private unregisterHooks;
39
- private unregisterEndpoints;
40
- private unregisterOperations;
40
+ private unregisterApiExtensions;
41
41
  }
42
42
  export {};
@@ -69,8 +69,9 @@ class ExtensionManager {
69
69
  constructor() {
70
70
  this.isLoaded = false;
71
71
  this.extensions = [];
72
- this.appExtensions = {};
73
- this.apiExtensions = { hooks: [], endpoints: [], operations: [] };
72
+ this.appExtensions = null;
73
+ this.apiExtensions = [];
74
+ this.hookEvents = [];
74
75
  this.watcher = null;
75
76
  this.options = defaultOptions;
76
77
  this.apiEmitter = new emitter_1.Emitter();
@@ -132,8 +133,8 @@ class ExtensionManager {
132
133
  return this.extensions.filter((extension) => extension.type === type).map((extension) => extension.name);
133
134
  }
134
135
  }
135
- getAppExtensions(type) {
136
- return this.appExtensions[type];
136
+ getAppExtensions() {
137
+ return this.appExtensions;
137
138
  }
138
139
  getEndpointRouter() {
139
140
  return this.endpointRouter;
@@ -147,21 +148,20 @@ class ExtensionManager {
147
148
  logger_1.default.warn(`Couldn't load extensions`);
148
149
  logger_1.default.warn(err);
149
150
  }
150
- this.registerHooks();
151
- this.registerEndpoints();
151
+ await this.registerHooks();
152
+ await this.registerEndpoints();
152
153
  await this.registerOperations();
154
+ await this.registerBundles();
153
155
  if (env_1.default.SERVE_APP) {
154
- this.appExtensions = await this.generateExtensionBundles();
156
+ this.appExtensions = await this.generateExtensionBundle();
155
157
  }
156
158
  this.isLoaded = true;
157
159
  }
158
160
  async unload() {
159
- this.unregisterHooks();
160
- this.unregisterEndpoints();
161
- this.unregisterOperations();
161
+ this.unregisterApiExtensions();
162
162
  this.apiEmitter.offAll();
163
163
  if (env_1.default.SERVE_APP) {
164
- this.appExtensions = {};
164
+ this.appExtensions = null;
165
165
  }
166
166
  this.isLoaded = false;
167
167
  }
@@ -192,9 +192,9 @@ class ExtensionManager {
192
192
  if (this.watcher) {
193
193
  const toPackageExtensionPaths = (extensions) => extensions
194
194
  .filter((extension) => !extension.local)
195
- .flatMap((extension) => (0, utils_1.isTypeIn)(extension, constants_1.PACKAGE_EXTENSION_TYPES)
195
+ .flatMap((extension) => extension.type === 'pack'
196
196
  ? path_1.default.resolve(extension.path, 'package.json')
197
- : (0, utils_1.isTypeIn)(extension, constants_1.HYBRID_EXTENSION_TYPES)
197
+ : (0, utils_1.isTypeIn)(extension, constants_1.HYBRID_EXTENSION_TYPES) || extension.type === 'bundle'
198
198
  ? [
199
199
  path_1.default.resolve(extension.path, extension.entrypoint.app),
200
200
  path_1.default.resolve(extension.path, extension.entrypoint.api),
@@ -211,32 +211,29 @@ class ExtensionManager {
211
211
  const localExtensions = await (0, node_1.getLocalExtensions)(env_1.default.EXTENSIONS_PATH, env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_OR_HYBRID_EXTENSION_TYPES);
212
212
  return [...packageExtensions, ...localExtensions];
213
213
  }
214
- async generateExtensionBundles() {
214
+ async generateExtensionBundle() {
215
215
  const sharedDepsMapping = await this.getSharedDepsMapping(constants_1.APP_SHARED_DEPS);
216
216
  const internalImports = Object.entries(sharedDepsMapping).map(([name, path]) => ({
217
217
  find: name,
218
218
  replacement: path,
219
219
  }));
220
- const bundles = {};
221
- for (const extensionType of constants_1.APP_OR_HYBRID_EXTENSION_TYPES) {
222
- const entry = (0, node_1.generateExtensionsEntry)(extensionType, this.extensions);
223
- try {
224
- const bundle = await (0, rollup_1.rollup)({
225
- input: 'entry',
226
- external: Object.values(sharedDepsMapping),
227
- makeAbsoluteExternalsRelative: false,
228
- plugins: [(0, plugin_virtual_1.default)({ entry }), (0, plugin_alias_1.default)({ entries: internalImports })],
229
- });
230
- const { output } = await bundle.generate({ format: 'es', compact: true });
231
- bundles[extensionType] = output[0].code;
232
- await bundle.close();
233
- }
234
- catch (error) {
235
- logger_1.default.warn(`Couldn't bundle App extensions`);
236
- logger_1.default.warn(error);
237
- }
220
+ const entrypoint = (0, node_1.generateExtensionsEntrypoint)(this.extensions);
221
+ try {
222
+ const bundle = await (0, rollup_1.rollup)({
223
+ input: 'entry',
224
+ external: Object.values(sharedDepsMapping),
225
+ makeAbsoluteExternalsRelative: false,
226
+ plugins: [(0, plugin_virtual_1.default)({ entry: entrypoint }), (0, plugin_alias_1.default)({ entries: internalImports })],
227
+ });
228
+ const { output } = await bundle.generate({ format: 'es', compact: true });
229
+ await bundle.close();
230
+ return output[0].code;
231
+ }
232
+ catch (error) {
233
+ logger_1.default.warn(`Couldn't bundle App extensions`);
234
+ logger_1.default.warn(error);
238
235
  }
239
- return bundles;
236
+ return null;
240
237
  }
241
238
  async getSharedDepsMapping(deps) {
242
239
  const appDir = await fs_extra_1.default.readdir(path_1.default.join((0, node_1.resolvePackage)('@directus/app', __dirname), 'dist', 'assets'));
@@ -254,14 +251,16 @@ class ExtensionManager {
254
251
  }
255
252
  return depsMapping;
256
253
  }
257
- registerHooks() {
254
+ async registerHooks() {
255
+ var _a;
258
256
  const hooks = this.extensions.filter((extension) => extension.type === 'hook');
259
257
  for (const hook of hooks) {
260
258
  try {
261
259
  const hookPath = path_1.default.resolve(hook.path, hook.entrypoint);
262
- const hookInstance = require(hookPath);
260
+ const hookInstance = await (_a = hookPath, Promise.resolve().then(() => __importStar(require(_a))));
263
261
  const config = (0, get_module_default_1.default)(hookInstance);
264
- this.registerHook(config, hookPath);
262
+ this.registerHook(config);
263
+ this.apiExtensions.push({ path: hookPath });
265
264
  }
266
265
  catch (error) {
267
266
  logger_1.default.warn(`Couldn't register hook "${hook.name}"`);
@@ -269,14 +268,15 @@ class ExtensionManager {
269
268
  }
270
269
  }
271
270
  }
272
- registerEndpoints() {
271
+ async registerEndpoints() {
273
272
  const endpoints = this.extensions.filter((extension) => extension.type === 'endpoint');
274
273
  for (const endpoint of endpoints) {
275
274
  try {
276
275
  const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint);
277
276
  const endpointInstance = require(endpointPath);
278
277
  const config = (0, get_module_default_1.default)(endpointInstance);
279
- this.registerEndpoint(config, endpointPath, endpoint.name, this.endpointRouter);
278
+ this.registerEndpoint(config, endpoint.name);
279
+ this.apiExtensions.push({ path: endpointPath });
280
280
  }
281
281
  catch (error) {
282
282
  logger_1.default.warn(`Couldn't register endpoint "${endpoint.name}"`);
@@ -300,7 +300,8 @@ class ExtensionManager {
300
300
  const operationPath = path_1.default.resolve(operation.path, operation.entrypoint.api);
301
301
  const operationInstance = require(operationPath);
302
302
  const config = (0, get_module_default_1.default)(operationInstance);
303
- this.registerOperation(config, operationPath);
303
+ this.registerOperation(config);
304
+ this.apiExtensions.push({ path: operationPath });
304
305
  }
305
306
  catch (error) {
306
307
  logger_1.default.warn(`Couldn't register operation "${operation.name}"`);
@@ -308,15 +309,35 @@ class ExtensionManager {
308
309
  }
309
310
  }
310
311
  }
311
- registerHook(register, path) {
312
- const hookHandler = {
313
- path,
314
- events: [],
315
- };
312
+ async registerBundles() {
313
+ const bundles = this.extensions.filter((extension) => extension.type === 'bundle');
314
+ for (const bundle of bundles) {
315
+ try {
316
+ const bundlePath = path_1.default.resolve(bundle.path, bundle.entrypoint.api);
317
+ const bundleInstances = require(bundlePath);
318
+ const configs = (0, get_module_default_1.default)(bundleInstances);
319
+ for (const { config } of configs.hooks) {
320
+ this.registerHook(config);
321
+ }
322
+ for (const { config, name } of configs.endpoints) {
323
+ this.registerEndpoint(config, name);
324
+ }
325
+ for (const { config } of configs.operations) {
326
+ this.registerOperation(config);
327
+ }
328
+ this.apiExtensions.push({ path: bundlePath });
329
+ }
330
+ catch (error) {
331
+ logger_1.default.warn(`Couldn't register bundle "${bundle.name}"`);
332
+ logger_1.default.warn(error);
333
+ }
334
+ }
335
+ }
336
+ registerHook(register) {
316
337
  const registerFunctions = {
317
338
  filter: (event, handler) => {
318
339
  emitter_1.default.onFilter(event, handler);
319
- hookHandler.events.push({
340
+ this.hookEvents.push({
320
341
  type: 'filter',
321
342
  name: event,
322
343
  handler,
@@ -324,7 +345,7 @@ class ExtensionManager {
324
345
  },
325
346
  action: (event, handler) => {
326
347
  emitter_1.default.onAction(event, handler);
327
- hookHandler.events.push({
348
+ this.hookEvents.push({
328
349
  type: 'action',
329
350
  name: event,
330
351
  handler,
@@ -332,7 +353,7 @@ class ExtensionManager {
332
353
  },
333
354
  init: (event, handler) => {
334
355
  emitter_1.default.onInit(event, handler);
335
- hookHandler.events.push({
356
+ this.hookEvents.push({
336
357
  type: 'init',
337
358
  name: event,
338
359
  handler,
@@ -350,7 +371,7 @@ class ExtensionManager {
350
371
  }
351
372
  }
352
373
  });
353
- hookHandler.events.push({
374
+ this.hookEvents.push({
354
375
  type: 'schedule',
355
376
  task,
356
377
  });
@@ -369,13 +390,12 @@ class ExtensionManager {
369
390
  logger: logger_1.default,
370
391
  getSchema: get_schema_1.getSchema,
371
392
  });
372
- this.apiExtensions.hooks.push(hookHandler);
373
393
  }
374
- registerEndpoint(config, path, name, router) {
394
+ registerEndpoint(config, name) {
375
395
  const register = typeof config === 'function' ? config : config.handler;
376
396
  const routeName = typeof config === 'function' ? name : config.id;
377
397
  const scopedRouter = express_1.default.Router();
378
- router.use(`/${routeName}`, scopedRouter);
398
+ this.endpointRouter.use(`/${routeName}`, scopedRouter);
379
399
  register(scopedRouter, {
380
400
  services,
381
401
  exceptions: { ...exceptions, ...sharedExceptions },
@@ -385,52 +405,35 @@ class ExtensionManager {
385
405
  logger: logger_1.default,
386
406
  getSchema: get_schema_1.getSchema,
387
407
  });
388
- this.apiExtensions.endpoints.push({
389
- path,
390
- });
391
408
  }
392
- registerOperation(config, path) {
409
+ registerOperation(config) {
393
410
  const flowManager = (0, flows_1.getFlowManager)();
394
411
  flowManager.addOperation(config.id, config.handler);
395
- this.apiExtensions.operations.push({
396
- path,
397
- });
398
412
  }
399
- unregisterHooks() {
400
- for (const hook of this.apiExtensions.hooks) {
401
- for (const event of hook.events) {
402
- switch (event.type) {
403
- case 'filter':
404
- emitter_1.default.offFilter(event.name, event.handler);
405
- break;
406
- case 'action':
407
- emitter_1.default.offAction(event.name, event.handler);
408
- break;
409
- case 'init':
410
- emitter_1.default.offInit(event.name, event.handler);
411
- break;
412
- case 'schedule':
413
- event.task.stop();
414
- break;
415
- }
413
+ unregisterApiExtensions() {
414
+ for (const event of this.hookEvents) {
415
+ switch (event.type) {
416
+ case 'filter':
417
+ emitter_1.default.offFilter(event.name, event.handler);
418
+ break;
419
+ case 'action':
420
+ emitter_1.default.offAction(event.name, event.handler);
421
+ break;
422
+ case 'init':
423
+ emitter_1.default.offInit(event.name, event.handler);
424
+ break;
425
+ case 'schedule':
426
+ event.task.stop();
427
+ break;
416
428
  }
417
- delete require.cache[require.resolve(hook.path)];
418
- }
419
- this.apiExtensions.hooks = [];
420
- }
421
- unregisterEndpoints() {
422
- for (const endpoint of this.apiExtensions.endpoints) {
423
- delete require.cache[require.resolve(endpoint.path)];
424
429
  }
430
+ this.hookEvents = [];
425
431
  this.endpointRouter.stack = [];
426
- this.apiExtensions.endpoints = [];
427
- }
428
- unregisterOperations() {
429
- for (const operation of this.apiExtensions.operations) {
430
- delete require.cache[require.resolve(operation.path)];
431
- }
432
432
  const flowManager = (0, flows_1.getFlowManager)();
433
433
  flowManager.clearOperations();
434
- this.apiExtensions.operations = [];
434
+ for (const apiExtension of this.apiExtensions) {
435
+ delete require.cache[require.resolve(apiExtension.path)];
436
+ }
437
+ this.apiExtensions = [];
435
438
  }
436
439
  }
package/dist/logger.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="qs" />
1
2
  import { RequestHandler } from 'express';
2
3
  import { LoggerOptions } from 'pino';
3
4
  declare const logger: import("pino").Logger<LoggerOptions & Record<string, any>>;
@@ -1,5 +1,5 @@
1
1
  import type { Redis } from 'ioredis';
2
- export declare type MessengerSubscriptionCallback = (payload: Record<string, any>) => void;
2
+ export type MessengerSubscriptionCallback = (payload: Record<string, any>) => void;
3
3
  export interface Messenger {
4
4
  publish: (channel: string, payload: Record<string, any>) => void;
5
5
  subscribe: (channel: string, callback: MessengerSubscriptionCallback) => void;
@@ -1,3 +1,4 @@
1
+ /// <reference types="qs" />
1
2
  import { NextFunction, Request, Response } from 'express';
2
3
  /**
3
4
  * Verify the passed JWT and assign the user ID and role to `req`
@@ -1 +1,3 @@
1
+ /// <reference types="qs" />
2
+ /// <reference types="express" />
1
3
  export declare const validateBatch: (scope: 'read' | 'update' | 'delete') => (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: import("express").Response<any, Record<string, any>>, next: import("express").NextFunction) => Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import { Filter } from '@directus/shared/types';
2
- declare type Options = {
2
+ type Options = {
3
3
  filter: Filter;
4
4
  };
5
5
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -4,7 +4,7 @@ const utils_1 = require("@directus/shared/utils");
4
4
  exports.default = (0, utils_1.defineOperationApi)({
5
5
  id: 'condition',
6
6
  handler: ({ filter }, { data }) => {
7
- const errors = (0, utils_1.validatePayload)(filter, data);
7
+ const errors = (0, utils_1.validatePayload)(filter, data, { requireAll: true });
8
8
  if (errors.length > 0) {
9
9
  throw errors;
10
10
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  code: string;
3
3
  };
4
4
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  collection: string;
3
3
  payload?: Record<string, any> | string | null;
4
4
  emitEvents: boolean;
@@ -1,5 +1,5 @@
1
1
  import { PrimaryKey } from '@directus/shared/types';
2
- declare type Options = {
2
+ type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  query?: Record<string, any> | string | null;
@@ -1,5 +1,5 @@
1
1
  import { PrimaryKey } from '@directus/shared/types';
2
- declare type Options = {
2
+ type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  query?: Record<string, any> | string | null;
@@ -1,5 +1,5 @@
1
1
  import { PrimaryKey } from '@directus/shared/types';
2
- declare type Options = {
2
+ type Options = {
3
3
  collection: string;
4
4
  key?: PrimaryKey | PrimaryKey[] | null;
5
5
  payload?: Record<string, any> | string | null;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  message: unknown;
3
3
  };
4
4
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  body: string;
3
3
  to: string;
4
4
  type: 'wysiwyg' | 'markdown';
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  recipient: string;
3
3
  subject: string;
4
4
  message?: unknown | null;
@@ -1,5 +1,5 @@
1
1
  import { Method } from 'axios';
2
- declare type Options = {
2
+ type Options = {
3
3
  url: string;
4
4
  method: Method;
5
5
  body: Record<string, any> | string | null;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  milliseconds: string | number;
3
3
  };
4
4
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  json: string | Record<string, any>;
3
3
  };
4
4
  declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
@@ -1,4 +1,4 @@
1
- declare type Options = {
1
+ type Options = {
2
2
  flow: string;
3
3
  payload?: Record<string, any> | Record<string, any>[] | string | null;
4
4
  };
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@directus/shared/utils");
4
+ const lodash_1 = require("lodash");
4
5
  const flows_1 = require("../../flows");
5
6
  exports.default = (0, utils_1.defineOperationApi)({
6
7
  id: 'trigger',
@@ -10,10 +11,12 @@ exports.default = (0, utils_1.defineOperationApi)({
10
11
  const payloadObject = (_a = (0, utils_1.optionToObject)(payload)) !== null && _a !== void 0 ? _a : null;
11
12
  let result;
12
13
  if (Array.isArray(payloadObject)) {
13
- result = await Promise.all(payloadObject.map((payload) => flowManager.runOperationFlow(flow, payload, context)));
14
+ result = await Promise.all(payloadObject.map((payload) => {
15
+ return flowManager.runOperationFlow(flow, payload, (0, lodash_1.omit)(context, 'data'));
16
+ }));
14
17
  }
15
18
  else {
16
- result = await flowManager.runOperationFlow(flow, payloadObject, context);
19
+ result = await flowManager.runOperationFlow(flow, payloadObject, (0, lodash_1.omit)(context, 'data'));
17
20
  }
18
21
  return result;
19
22
  },
@@ -1,4 +1,4 @@
1
1
  import { IRateLimiterOptions, IRateLimiterStoreOptions, RateLimiterAbstract } from 'rate-limiter-flexible';
2
- declare type IRateLimiterOptionsOverrides = Partial<IRateLimiterOptions> | Partial<IRateLimiterStoreOptions>;
2
+ type IRateLimiterOptionsOverrides = Partial<IRateLimiterOptions> | Partial<IRateLimiterStoreOptions>;
3
3
  export declare function createRateLimiter(configOverrides?: IRateLimiterOptionsOverrides): RateLimiterAbstract;
4
4
  export {};
@@ -151,7 +151,7 @@ class AuthorizationService {
151
151
  }
152
152
  if (ast.type === 'root') {
153
153
  // Validate all required permissions once at the root level
154
- checkFieldPermissions(ast.name, schema, action, requiredFieldPermissions);
154
+ checkFieldPermissions(ast.name, schema, action, requiredFieldPermissions, ast.query.alias);
155
155
  }
156
156
  return requiredFieldPermissions;
157
157
  function extractRequiredFieldPermissions(collection, filter, parentCollection, parentField) {
@@ -259,7 +259,7 @@ class AuthorizationService {
259
259
  }
260
260
  return current;
261
261
  }
262
- function checkFieldPermissions(rootCollection, schema, action, requiredPermissions) {
262
+ function checkFieldPermissions(rootCollection, schema, action, requiredPermissions, aliasMap) {
263
263
  var _a, _b;
264
264
  if ((accountability === null || accountability === void 0 ? void 0 : accountability.admin) === true)
265
265
  return;
@@ -291,7 +291,11 @@ class AuthorizationService {
291
291
  if (field.startsWith('$FOLLOW'))
292
292
  continue;
293
293
  const fieldName = (0, strip_function_1.stripFunction)(field);
294
- if (!allowedFields.includes(fieldName)) {
294
+ let originalFieldName = fieldName;
295
+ if (collection === rootCollection && (aliasMap === null || aliasMap === void 0 ? void 0 : aliasMap[fieldName])) {
296
+ originalFieldName = aliasMap[fieldName];
297
+ }
298
+ if (!allowedFields.includes(originalFieldName)) {
295
299
  throw new exceptions_2.ForbiddenException();
296
300
  }
297
301
  }
@@ -5,7 +5,7 @@ import { AbstractServiceOptions, Collection, CollectionMeta, MutationOptions } f
5
5
  import { Accountability, RawField, SchemaOverview } from '@directus/shared/types';
6
6
  import { Table } from 'knex-schema-inspector/dist/types/table';
7
7
  import { Helpers } from '../database/helpers';
8
- export declare type RawCollection = {
8
+ export type RawCollection = {
9
9
  collection: string;
10
10
  fields?: RawField[];
11
11
  schema?: Partial<Table> | null;