directus 9.11.1 → 9.12.2

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 (104) hide show
  1. package/dist/app.js +14 -1
  2. package/dist/cli/utils/create-env/env-stub.liquid +266 -9
  3. package/dist/constants.d.ts +1 -0
  4. package/dist/constants.js +5 -1
  5. package/dist/controllers/activity.js +1 -1
  6. package/dist/controllers/flows.d.ts +2 -0
  7. package/dist/controllers/flows.js +157 -0
  8. package/dist/controllers/folders.js +1 -1
  9. package/dist/controllers/notifications.js +1 -1
  10. package/dist/controllers/operations.d.ts +2 -0
  11. package/dist/controllers/operations.js +138 -0
  12. package/dist/database/helpers/fn/dialects/oracle.d.ts +9 -9
  13. package/dist/database/helpers/fn/dialects/oracle.js +22 -16
  14. package/dist/database/helpers/fn/dialects/sqlite.d.ts +9 -9
  15. package/dist/database/helpers/fn/dialects/sqlite.js +46 -16
  16. package/dist/database/helpers/fn/types.d.ts +12 -9
  17. package/dist/database/index.js +10 -19
  18. package/dist/database/migrations/20220429A-add-flows.d.ts +3 -0
  19. package/dist/database/migrations/20220429A-add-flows.js +83 -0
  20. package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +3 -0
  21. package/dist/database/migrations/20220429B-add-color-to-insights-icon.js +15 -0
  22. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +3 -0
  23. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.js +15 -0
  24. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +3 -0
  25. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.js +15 -0
  26. package/dist/database/seeds/05-activity.yaml +0 -1
  27. package/dist/database/system-data/collections/collections.yaml +4 -0
  28. package/dist/database/system-data/fields/flows.yaml +21 -0
  29. package/dist/database/system-data/fields/operations.yaml +19 -0
  30. package/dist/database/system-data/fields/users.yaml +2 -4
  31. package/dist/database/system-data/relations/relations.yaml +20 -0
  32. package/dist/env.d.ts +1 -1
  33. package/dist/env.js +6 -30
  34. package/dist/extensions.d.ts +5 -1
  35. package/dist/extensions.js +96 -39
  36. package/dist/flows.d.ts +22 -0
  37. package/dist/flows.js +332 -0
  38. package/dist/messenger.d.ts +24 -0
  39. package/dist/messenger.js +64 -0
  40. package/dist/operations/condition/index.d.ts +6 -0
  41. package/dist/operations/condition/index.js +15 -0
  42. package/dist/operations/item-create/index.d.ts +8 -0
  43. package/dist/operations/item-create/index.js +40 -0
  44. package/dist/operations/item-delete/index.d.ts +9 -0
  45. package/dist/operations/item-delete/index.js +45 -0
  46. package/dist/operations/item-read/index.d.ts +9 -0
  47. package/dist/operations/item-read/index.js +45 -0
  48. package/dist/operations/item-update/index.d.ts +10 -0
  49. package/dist/operations/item-update/index.js +50 -0
  50. package/dist/operations/log/index.d.ts +5 -0
  51. package/dist/operations/log/index.js +14 -0
  52. package/dist/operations/mail/index.d.ts +7 -0
  53. package/dist/operations/mail/index.js +16 -0
  54. package/dist/operations/notification/index.d.ts +8 -0
  55. package/dist/operations/notification/index.js +39 -0
  56. package/dist/operations/request/index.d.ts +12 -0
  57. package/dist/operations/request/index.js +18 -0
  58. package/dist/operations/sleep/index.d.ts +5 -0
  59. package/dist/operations/sleep/index.js +9 -0
  60. package/dist/operations/transform/index.d.ts +5 -0
  61. package/dist/operations/transform/index.js +10 -0
  62. package/dist/operations/trigger/index.d.ts +6 -0
  63. package/dist/operations/trigger/index.js +21 -0
  64. package/dist/services/activity.d.ts +1 -2
  65. package/dist/services/activity.js +10 -10
  66. package/dist/services/authentication.d.ts +2 -2
  67. package/dist/services/authentication.js +7 -7
  68. package/dist/services/authorization.js +12 -0
  69. package/dist/services/flows.d.ts +12 -0
  70. package/dist/services/flows.js +47 -0
  71. package/dist/services/graphql.js +13 -2
  72. package/dist/services/import-export.js +7 -3
  73. package/dist/services/index.d.ts +2 -0
  74. package/dist/services/index.js +2 -0
  75. package/dist/services/items.js +1 -1
  76. package/dist/services/mail/index.js +2 -1
  77. package/dist/services/notifications.d.ts +2 -1
  78. package/dist/services/notifications.js +4 -3
  79. package/dist/services/operations.d.ts +12 -0
  80. package/dist/services/operations.js +47 -0
  81. package/dist/services/users.js +5 -0
  82. package/dist/services/webhooks.d.ts +2 -0
  83. package/dist/services/webhooks.js +8 -7
  84. package/dist/types/events.d.ts +18 -0
  85. package/dist/types/events.js +2 -0
  86. package/dist/types/index.d.ts +1 -1
  87. package/dist/types/index.js +1 -1
  88. package/dist/utils/apply-snapshot.js +3 -0
  89. package/dist/utils/construct-flow-tree.d.ts +2 -0
  90. package/dist/utils/construct-flow-tree.js +31 -0
  91. package/dist/utils/get-accountability-for-role.d.ts +7 -0
  92. package/dist/utils/get-accountability-for-role.js +36 -0
  93. package/dist/utils/get-column.js +1 -1
  94. package/dist/utils/job-queue.d.ts +9 -0
  95. package/dist/utils/job-queue.js +24 -0
  96. package/dist/utils/operation-options.d.ts +3 -0
  97. package/dist/utils/operation-options.js +45 -0
  98. package/dist/utils/validate-query.js +1 -1
  99. package/dist/webhooks.d.ts +2 -0
  100. package/dist/webhooks.js +17 -2
  101. package/package.json +19 -15
  102. package/dist/types/activity.d.ts +0 -9
  103. package/dist/types/activity.js +0 -13
  104. package/example.env +0 -202
@@ -61,6 +61,20 @@ data:
61
61
  many_field: dashboard
62
62
  one_collection: directus_dashboards
63
63
  one_field: panels
64
+ - many_collection: directus_flows
65
+ many_field: operation
66
+ one_collection: directus_operations
67
+ - many_collection: directus_operations
68
+ many_field: flow
69
+ one_collection: directus_flows
70
+ one_field: operations
71
+ one_deselect_action: delete
72
+ - many_collection: directus_operations
73
+ many_field: resolve
74
+ one_collection: directus_operations
75
+ - many_collection: directus_operations
76
+ many_field: reject
77
+ one_collection: directus_operations
64
78
  - many_collection: directus_files
65
79
  many_field: modified_by
66
80
  one_collection: directus_users
@@ -88,6 +102,12 @@ data:
88
102
  - many_collection: directus_panels
89
103
  many_field: user_created
90
104
  one_collection: directus_users
105
+ - many_collection: directus_flows
106
+ many_field: user_created
107
+ one_collection: directus_users
108
+ - many_collection: directus_operations
109
+ many_field: user_created
110
+ one_collection: directus_users
91
111
  - many_collection: directus_notifications
92
112
  many_field: recipient
93
113
  one_collection: directus_users
package/dist/env.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @NOTE
3
- * See example.env for all possible keys
3
+ * For all possible keys, see: https://docs.directus.io/configuration/config-options/
4
4
  */
5
5
  declare let env: Record<string, any>;
6
6
  export default env;
package/dist/env.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @NOTE
4
- * See example.env for all possible keys
4
+ * For all possible keys, see: https://docs.directus.io/configuration/config-options/
5
5
  */
6
6
  var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -28,22 +28,11 @@ const allowedEnvironmentVars = [
28
28
  'ROOT_REDIRECT',
29
29
  'SERVE_APP',
30
30
  'GRAPHQL_INTROSPECTION',
31
+ 'LOGGER_.+',
31
32
  // server
32
- 'SERVER_KEEP_ALIVE_TIMEOUT',
33
- 'SERVER_HEADERS_TIMEOUT',
33
+ 'SERVER_.+',
34
34
  // database
35
- 'DB_CLIENT',
36
- 'DB_HOST',
37
- 'DB_PORT',
38
- 'DB_DATABASE',
39
- 'DB_USER',
40
- 'DB_PASSWORD',
41
- 'DB_FILENAME',
42
- 'DB_CONNECTION_STRING',
43
- 'DB_POOL_.+',
44
- 'DB_EXCLUDE_TABLES',
45
- 'DB_CHARSET',
46
- 'DB_VERSION',
35
+ 'DB_.+',
47
36
  // security
48
37
  'KEY',
49
38
  'SECRET',
@@ -62,12 +51,7 @@ const allowedEnvironmentVars = [
62
51
  'CONTENT_SECURITY_POLICY_.+',
63
52
  'HSTS_.+',
64
53
  // hashing
65
- 'HASH_MEMORY_COST',
66
- 'HASH_LENGTH',
67
- 'HASH_TIME_COST',
68
- 'HASH_PARALLELISM',
69
- 'HASH_TYPE',
70
- 'HASH_ASSOCIATED_DATA',
54
+ 'HASH_.+',
71
55
  // cors
72
56
  'CORS_ENABLED',
73
57
  'CORS_ORIGIN',
@@ -77,15 +61,7 @@ const allowedEnvironmentVars = [
77
61
  'CORS_CREDENTIALS',
78
62
  'CORS_MAX_AGE',
79
63
  // rate limiting
80
- 'RATE_LIMITER_ENABLED',
81
- 'RATE_LIMITER_POINTS',
82
- 'RATE_LIMITER_DURATION',
83
- 'RATE_LIMITER_STORE',
84
- 'RATE_LIMITER_REDIS',
85
- 'RATE_LIMITER_REDIS_HOST',
86
- 'RATE_LIMITER_REDIS_PORT',
87
- 'RATE_LIMITER_REDIS_PASSWORD',
88
- 'RATE_LIMITER_MEMCACHE',
64
+ 'RATE_LIMITER_.+',
89
65
  // cache
90
66
  'CACHE_ENABLED',
91
67
  'CACHE_TTL',
@@ -13,10 +13,11 @@ declare class ExtensionManager {
13
13
  private apiExtensions;
14
14
  private apiEmitter;
15
15
  private endpointRouter;
16
+ private reloadQueue;
16
17
  private watcher;
17
18
  constructor();
18
19
  initialize(options?: Partial<Options>): Promise<void>;
19
- reload(): Promise<void>;
20
+ reload(): void;
20
21
  getExtensionsList(type?: ExtensionType): string[];
21
22
  getAppExtensions(type: AppExtensionType): string | undefined;
22
23
  getEndpointRouter(): Router;
@@ -29,9 +30,12 @@ declare class ExtensionManager {
29
30
  private getSharedDepsMapping;
30
31
  private registerHooks;
31
32
  private registerEndpoints;
33
+ private registerOperations;
32
34
  private registerHook;
33
35
  private registerEndpoint;
36
+ private registerOperation;
34
37
  private unregisterHooks;
35
38
  private unregisterEndpoints;
39
+ private unregisterOperations;
36
40
  }
37
41
  export {};
@@ -45,6 +45,9 @@ const get_module_default_1 = __importDefault(require("./utils/get-module-default
45
45
  const lodash_1 = require("lodash");
46
46
  const chokidar_1 = __importDefault(require("chokidar"));
47
47
  const utils_1 = require("@directus/shared/utils");
48
+ const flows_1 = require("./flows");
49
+ const globby_1 = __importDefault(require("globby"));
50
+ const job_queue_1 = require("./utils/job-queue");
48
51
  let extensionManager;
49
52
  function getExtensionManager() {
50
53
  if (extensionManager) {
@@ -63,11 +66,12 @@ class ExtensionManager {
63
66
  this.isLoaded = false;
64
67
  this.extensions = [];
65
68
  this.appExtensions = {};
66
- this.apiExtensions = { hooks: [], endpoints: [] };
69
+ this.apiExtensions = { hooks: [], endpoints: [], operations: [] };
67
70
  this.watcher = null;
68
71
  this.options = defaultOptions;
69
72
  this.apiEmitter = new emitter_1.Emitter();
70
73
  this.endpointRouter = (0, express_1.Router)();
74
+ this.reloadQueue = new job_queue_1.JobQueue();
71
75
  }
72
76
  async initialize(options = {}) {
73
77
  this.options = {
@@ -84,27 +88,29 @@ class ExtensionManager {
84
88
  }
85
89
  }
86
90
  }
87
- async reload() {
88
- if (this.isLoaded) {
89
- logger_1.default.info('Reloading extensions');
90
- const prevExtensions = (0, lodash_1.clone)(this.extensions);
91
- await this.unload();
92
- await this.load();
93
- const added = this.extensions.filter((extension) => !prevExtensions.some((prevExtension) => extension.path === prevExtension.path));
94
- const removed = prevExtensions.filter((prevExtension) => !this.extensions.some((extension) => prevExtension.path === extension.path));
95
- this.updateWatchedExtensions(added, removed);
96
- const addedExtensions = added.map((extension) => extension.name);
97
- const removedExtensions = removed.map((extension) => extension.name);
98
- if (addedExtensions.length > 0) {
99
- logger_1.default.info(`Added extensions: ${addedExtensions.join(', ')}`);
91
+ reload() {
92
+ this.reloadQueue.enqueue(async () => {
93
+ if (this.isLoaded) {
94
+ logger_1.default.info('Reloading extensions');
95
+ const prevExtensions = (0, lodash_1.clone)(this.extensions);
96
+ await this.unload();
97
+ await this.load();
98
+ const added = this.extensions.filter((extension) => !prevExtensions.some((prevExtension) => extension.path === prevExtension.path));
99
+ const removed = prevExtensions.filter((prevExtension) => !this.extensions.some((extension) => prevExtension.path === extension.path));
100
+ this.updateWatchedExtensions(added, removed);
101
+ const addedExtensions = added.map((extension) => extension.name);
102
+ const removedExtensions = removed.map((extension) => extension.name);
103
+ if (addedExtensions.length > 0) {
104
+ logger_1.default.info(`Added extensions: ${addedExtensions.join(', ')}`);
105
+ }
106
+ if (removedExtensions.length > 0) {
107
+ logger_1.default.info(`Removed extensions: ${removedExtensions.join(', ')}`);
108
+ }
100
109
  }
101
- if (removedExtensions.length > 0) {
102
- logger_1.default.info(`Removed extensions: ${removedExtensions.join(', ')}`);
110
+ else {
111
+ logger_1.default.warn('Extensions have to be loaded before they can be reloaded');
103
112
  }
104
- }
105
- else {
106
- logger_1.default.warn('Extensions have to be loaded before they can be reloaded');
107
- }
113
+ });
108
114
  }
109
115
  getExtensionsList(type) {
110
116
  if (type === undefined) {
@@ -131,6 +137,7 @@ class ExtensionManager {
131
137
  }
132
138
  this.registerHooks();
133
139
  this.registerEndpoints();
140
+ await this.registerOperations();
134
141
  if (env_1.default.SERVE_APP) {
135
142
  this.appExtensions = await this.generateExtensionBundles();
136
143
  }
@@ -139,6 +146,7 @@ class ExtensionManager {
139
146
  async unload() {
140
147
  this.unregisterHooks();
141
148
  this.unregisterEndpoints();
149
+ this.unregisterOperations();
142
150
  this.apiEmitter.offAll();
143
151
  if (env_1.default.SERVE_APP) {
144
152
  this.appExtensions = {};
@@ -148,8 +156,13 @@ class ExtensionManager {
148
156
  initializeWatcher() {
149
157
  if (this.options.watch && !this.watcher) {
150
158
  logger_1.default.info('Watching extensions for changes...');
151
- 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'));
152
- this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
159
+ const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).flatMap((type) => {
160
+ const typeDir = 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));
161
+ return (0, utils_1.isHybridExtension)(type)
162
+ ? [path_1.default.posix.join(typeDir, '*', 'app.js'), path_1.default.posix.join(typeDir, '*', 'api.js')]
163
+ : path_1.default.posix.join(typeDir, '*', 'index.js');
164
+ });
165
+ this.watcher = chokidar_1.default.watch([path_1.default.resolve('package.json'), ...localExtensionPaths], {
153
166
  ignoreInitial: true,
154
167
  });
155
168
  this.watcher
@@ -162,9 +175,14 @@ class ExtensionManager {
162
175
  if (this.watcher) {
163
176
  const toPackageExtensionPaths = (extensions) => extensions
164
177
  .filter((extension) => !extension.local)
165
- .map((extension) => extension.type !== 'pack'
166
- ? path_1.default.resolve(extension.path, extension.entrypoint || '')
167
- : path_1.default.resolve(extension.path, 'package.json'));
178
+ .flatMap((extension) => extension.type === constants_1.PACK_EXTENSION_TYPE
179
+ ? path_1.default.resolve(extension.path, 'package.json')
180
+ : (0, utils_1.isExtensionObject)(extension, constants_1.HYBRID_EXTENSION_TYPES)
181
+ ? [
182
+ path_1.default.resolve(extension.path, extension.entrypoint.app),
183
+ path_1.default.resolve(extension.path, extension.entrypoint.api),
184
+ ]
185
+ : path_1.default.resolve(extension.path, extension.entrypoint));
168
186
  const addedPackageExtensionPaths = toPackageExtensionPaths(added);
169
187
  const removedPackageExtensionPaths = toPackageExtensionPaths(removed);
170
188
  this.watcher.add(addedPackageExtensionPaths);
@@ -223,7 +241,10 @@ class ExtensionManager {
223
241
  const hooks = this.extensions.filter((extension) => extension.type === 'hook');
224
242
  for (const hook of hooks) {
225
243
  try {
226
- this.registerHook(hook);
244
+ const hookPath = path_1.default.resolve(hook.path, hook.entrypoint);
245
+ const hookInstance = require(hookPath);
246
+ const config = (0, get_module_default_1.default)(hookInstance);
247
+ this.registerHook(config, hookPath);
227
248
  }
228
249
  catch (error) {
229
250
  logger_1.default.warn(`Couldn't register hook "${hook.name}"`);
@@ -235,7 +256,10 @@ class ExtensionManager {
235
256
  const endpoints = this.extensions.filter((extension) => extension.type === 'endpoint');
236
257
  for (const endpoint of endpoints) {
237
258
  try {
238
- this.registerEndpoint(endpoint, this.endpointRouter);
259
+ const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint);
260
+ const endpointInstance = require(endpointPath);
261
+ const config = (0, get_module_default_1.default)(endpointInstance);
262
+ this.registerEndpoint(config, endpointPath, endpoint.name, this.endpointRouter);
239
263
  }
240
264
  catch (error) {
241
265
  logger_1.default.warn(`Couldn't register endpoint "${endpoint.name}"`);
@@ -243,12 +267,33 @@ class ExtensionManager {
243
267
  }
244
268
  }
245
269
  }
246
- registerHook(hook) {
247
- const hookPath = path_1.default.resolve(hook.path, hook.entrypoint || '');
248
- const hookInstance = require(hookPath);
249
- const register = (0, get_module_default_1.default)(hookInstance);
270
+ async registerOperations() {
271
+ const internalPaths = await (0, globby_1.default)(path_1.default.posix.join(path_1.default.relative('.', __dirname).split(path_1.default.sep).join(path_1.default.posix.sep), 'operations/*/index.(js|ts)'));
272
+ const internalOperations = internalPaths.map((internalPath) => {
273
+ const dirs = internalPath.split(path_1.default.sep);
274
+ return {
275
+ name: dirs[dirs.length - 2],
276
+ path: dirs.slice(0, -1).join(path_1.default.sep),
277
+ entrypoint: { api: dirs[dirs.length - 1] },
278
+ };
279
+ });
280
+ const operations = this.extensions.filter((extension) => extension.type === 'operation');
281
+ for (const operation of [...internalOperations, ...operations]) {
282
+ try {
283
+ const operationPath = path_1.default.resolve(operation.path, operation.entrypoint.api);
284
+ const operationInstance = require(operationPath);
285
+ const config = (0, get_module_default_1.default)(operationInstance);
286
+ this.registerOperation(config, operationPath);
287
+ }
288
+ catch (error) {
289
+ logger_1.default.warn(`Couldn't register operation "${operation.name}"`);
290
+ logger_1.default.warn(error);
291
+ }
292
+ }
293
+ }
294
+ registerHook(register, path) {
250
295
  const hookHandler = {
251
- path: hookPath,
296
+ path,
252
297
  events: [],
253
298
  };
254
299
  const registerFunctions = {
@@ -309,12 +354,9 @@ class ExtensionManager {
309
354
  });
310
355
  this.apiExtensions.hooks.push(hookHandler);
311
356
  }
312
- registerEndpoint(endpoint, router) {
313
- const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint || '');
314
- const endpointInstance = require(endpointPath);
315
- const mod = (0, get_module_default_1.default)(endpointInstance);
316
- const register = typeof mod === 'function' ? mod : mod.handler;
317
- const routeName = typeof mod === 'function' ? endpoint.name : mod.id;
357
+ registerEndpoint(config, path, name, router) {
358
+ const register = typeof config === 'function' ? config : config.handler;
359
+ const routeName = typeof config === 'function' ? name : config.id;
318
360
  const scopedRouter = express_1.default.Router();
319
361
  router.use(`/${routeName}`, scopedRouter);
320
362
  register(scopedRouter, {
@@ -327,7 +369,14 @@ class ExtensionManager {
327
369
  getSchema: get_schema_1.getSchema,
328
370
  });
329
371
  this.apiExtensions.endpoints.push({
330
- path: endpointPath,
372
+ path,
373
+ });
374
+ }
375
+ registerOperation(config, path) {
376
+ const flowManager = (0, flows_1.getFlowManager)();
377
+ flowManager.addOperation(config.id, config.handler);
378
+ this.apiExtensions.operations.push({
379
+ path,
331
380
  });
332
381
  }
333
382
  unregisterHooks() {
@@ -359,4 +408,12 @@ class ExtensionManager {
359
408
  this.endpointRouter.stack = [];
360
409
  this.apiExtensions.endpoints = [];
361
410
  }
411
+ unregisterOperations() {
412
+ for (const operation of this.apiExtensions.operations) {
413
+ delete require.cache[require.resolve(operation.path)];
414
+ }
415
+ const flowManager = (0, flows_1.getFlowManager)();
416
+ flowManager.clearOperations();
417
+ this.apiExtensions.operations = [];
418
+ }
362
419
  }
@@ -0,0 +1,22 @@
1
+ import { OperationHandler } from '@directus/shared/types';
2
+ export declare function getFlowManager(): FlowManager;
3
+ declare class FlowManager {
4
+ private isLoaded;
5
+ private operations;
6
+ private triggerHandlers;
7
+ private operationFlowHandlers;
8
+ private webhookFlowHandlers;
9
+ private reloadQueue;
10
+ constructor();
11
+ initialize(): Promise<void>;
12
+ reload(): Promise<void>;
13
+ addOperation(id: string, operation: OperationHandler): void;
14
+ clearOperations(): void;
15
+ runOperationFlow(id: string, data: unknown, context: Record<string, unknown>): Promise<unknown>;
16
+ runWebhookFlow(id: string, data: unknown, context: Record<string, unknown>): Promise<unknown>;
17
+ private load;
18
+ private unload;
19
+ private executeFlow;
20
+ private executeOperation;
21
+ }
22
+ export {};