@nocobase/plugin-workflow 0.9.3-alpha.1 → 0.9.4-alpha.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 (74) hide show
  1. package/lib/client/CanvasContent.d.ts +4 -0
  2. package/lib/client/CanvasContent.js +49 -0
  3. package/lib/client/ExecutionCanvas.js +110 -44
  4. package/lib/client/WorkflowCanvas.js +35 -18
  5. package/lib/client/components/CollectionFieldset.js +2 -2
  6. package/lib/client/components/NodeDescription.d.ts +2 -0
  7. package/lib/client/components/NodeDescription.js +59 -0
  8. package/lib/client/components/ValueBlock.d.ts +5 -0
  9. package/lib/client/components/ValueBlock.js +110 -0
  10. package/lib/client/index.d.ts +1 -0
  11. package/lib/client/index.js +12 -0
  12. package/lib/client/locale/es-ES.d.ts +130 -0
  13. package/lib/client/locale/es-ES.js +136 -0
  14. package/lib/client/locale/zh-CN.d.ts +35 -6
  15. package/lib/client/locale/zh-CN.js +35 -6
  16. package/lib/client/nodes/aggregate.d.ts +186 -0
  17. package/lib/client/nodes/aggregate.js +349 -0
  18. package/lib/client/nodes/calculation.d.ts +2 -1
  19. package/lib/client/nodes/calculation.js +28 -53
  20. package/lib/client/nodes/condition.d.ts +2 -6
  21. package/lib/client/nodes/condition.js +4 -3
  22. package/lib/client/nodes/create.d.ts +5 -3
  23. package/lib/client/nodes/create.js +16 -7
  24. package/lib/client/nodes/delay.d.ts +1 -0
  25. package/lib/client/nodes/delay.js +1 -0
  26. package/lib/client/nodes/destroy.d.ts +2 -2
  27. package/lib/client/nodes/destroy.js +1 -0
  28. package/lib/client/nodes/index.d.ts +5 -2
  29. package/lib/client/nodes/index.js +95 -97
  30. package/lib/client/nodes/loop.d.ts +29 -0
  31. package/lib/client/nodes/loop.js +165 -0
  32. package/lib/client/nodes/manual/AssigneesSelect.js +8 -6
  33. package/lib/client/nodes/manual/index.d.ts +6 -1
  34. package/lib/client/nodes/manual/index.js +6 -1
  35. package/lib/client/nodes/parallel.d.ts +1 -0
  36. package/lib/client/nodes/parallel.js +2 -1
  37. package/lib/client/nodes/query.d.ts +12 -3
  38. package/lib/client/nodes/query.js +24 -17
  39. package/lib/client/nodes/request.d.ts +1 -0
  40. package/lib/client/nodes/request.js +1 -0
  41. package/lib/client/nodes/update.d.ts +2 -2
  42. package/lib/client/nodes/update.js +1 -0
  43. package/lib/client/schemas/collection.d.ts +1 -2
  44. package/lib/client/schemas/collection.js +5 -6
  45. package/lib/client/style.d.ts +1 -0
  46. package/lib/client/style.js +40 -26
  47. package/lib/client/triggers/collection.d.ts +2 -11
  48. package/lib/client/triggers/collection.js +6 -7
  49. package/lib/client/triggers/index.d.ts +1 -1
  50. package/lib/client/triggers/index.js +5 -3
  51. package/lib/client/triggers/schedule/index.d.ts +3 -1
  52. package/lib/client/triggers/schedule/index.js +6 -4
  53. package/lib/client/variable.d.ts +27 -1
  54. package/lib/client/variable.js +65 -34
  55. package/lib/server/Plugin.js +2 -14
  56. package/lib/server/Processor.d.ts +3 -0
  57. package/lib/server/Processor.js +30 -3
  58. package/lib/server/actions/workflows.js +2 -2
  59. package/lib/server/collections/workflows.js +2 -1
  60. package/lib/server/instructions/aggregate.d.ts +9 -0
  61. package/lib/server/instructions/aggregate.js +57 -0
  62. package/lib/server/instructions/calculation.js +1 -1
  63. package/lib/server/instructions/condition.js +1 -1
  64. package/lib/server/instructions/create.js +1 -1
  65. package/lib/server/instructions/destroy.js +1 -1
  66. package/lib/server/instructions/index.d.ts +1 -0
  67. package/lib/server/instructions/index.js +1 -1
  68. package/lib/server/instructions/loop.d.ts +16 -0
  69. package/lib/server/instructions/loop.js +107 -0
  70. package/lib/server/instructions/parallel.js +17 -10
  71. package/lib/server/instructions/query.js +1 -4
  72. package/lib/server/instructions/request.js +1 -1
  73. package/lib/server/instructions/update.js +1 -1
  74. package/package.json +13 -13
@@ -126,7 +126,7 @@ function TriggerExecution() {
126
126
  'x-component-props': {
127
127
  title: _react().default.createElement(_icons().InfoOutlined, null),
128
128
  shape: 'circle',
129
- className: 'workflow-node-job-button',
129
+ className: (0, _css().cx)(_style.nodeJobButtonClass, 'workflow-node-job-button'),
130
130
  type: 'primary'
131
131
  },
132
132
  properties: {
@@ -187,8 +187,10 @@ const TriggerConfig = () => {
187
187
  editingConfig = _useState4[0],
188
188
  setEditingConfig = _useState4[1];
189
189
  (0, _react().useEffect)(() => {
190
- var _workflow$title;
191
- setEditingTitle((_workflow$title = workflow.title) !== null && _workflow$title !== void 0 ? _workflow$title : typeTitle);
190
+ if (workflow) {
191
+ var _workflow$title;
192
+ setEditingTitle((_workflow$title = workflow.title) !== null && _workflow$title !== void 0 ? _workflow$title : typeTitle);
193
+ }
192
194
  }, [workflow]);
193
195
  if (!workflow || !workflow.type) {
194
196
  return null;
@@ -37,7 +37,9 @@ declare const _default: {
37
37
  ScheduleConfig: () => JSX.Element;
38
38
  FieldsSelect: import("react").MemoExoticComponent<import("react").FunctionComponent<Pick<any, string | number | symbol>>>;
39
39
  };
40
- getOptions(config: any, types: any): any[];
40
+ useVariables(config: any, { types }: {
41
+ types: any;
42
+ }): any[];
41
43
  useInitializers(config: any): SchemaInitializerItemOptions | null;
42
44
  initializers: {
43
45
  CollectionFieldInitializers: typeof CollectionFieldInitializers;
@@ -51,7 +51,9 @@ var _default = {
51
51
  ScheduleConfig: _ScheduleConfig.ScheduleConfig,
52
52
  FieldsSelect: _FieldsSelect.FieldsSelect
53
53
  },
54
- getOptions(config, types) {
54
+ useVariables(config, {
55
+ types
56
+ }) {
55
57
  const _useWorkflowTranslati = (0, _locale.useWorkflowTranslation)(),
56
58
  t = _useWorkflowTranslati.t;
57
59
  const options = [];
@@ -62,10 +64,10 @@ var _default = {
62
64
  label: t('Trigger time')
63
65
  });
64
66
  }
67
+ const fieldOptions = (0, _variable.useCollectionFieldOptions)({
68
+ collection: config.collection
69
+ });
65
70
  if (config.mode === _constants.SCHEDULE_MODE.COLLECTION_FIELD) {
66
- const fieldOptions = (0, _variable.useCollectionFieldOptions)({
67
- collection: config.collection
68
- });
69
71
  if (fieldOptions.length) {
70
72
  options.push({
71
73
  key: 'data',
@@ -5,6 +5,32 @@ export declare type VariableOption = {
5
5
  children?: VariableOptions;
6
6
  };
7
7
  export declare type VariableOptions = VariableOption[] | null;
8
+ export declare const nodesOptions: {
9
+ label: string;
10
+ value: string;
11
+ useOptions(options: any): VariableOption[];
12
+ };
13
+ export declare const triggerOptions: {
14
+ label: string;
15
+ value: string;
16
+ useOptions(options: any): VariableOption[];
17
+ };
18
+ export declare const scopeOptions: {
19
+ label: string;
20
+ value: string;
21
+ useOptions(options: any): VariableOption[];
22
+ };
23
+ export declare const systemOptions: {
24
+ label: string;
25
+ value: string;
26
+ useOptions({ types }: {
27
+ types: any;
28
+ }): {
29
+ key: string;
30
+ value: string;
31
+ label: string;
32
+ }[];
33
+ };
8
34
  export declare const BaseTypeSets: {
9
35
  boolean: Set<string>;
10
36
  number: Set<string>;
@@ -12,7 +38,7 @@ export declare const BaseTypeSets: {
12
38
  date: Set<string>;
13
39
  };
14
40
  export declare function filterTypedFields(fields: any, types: any, depth?: number): any;
15
- export declare function useWorkflowVariableOptions(types?: any): {
41
+ export declare function useWorkflowVariableOptions(options?: {}): {
16
42
  label: any;
17
43
  value: any;
18
44
  key: any;
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.BaseTypeSets = void 0;
7
7
  exports.filterTypedFields = filterTypedFields;
8
+ exports.triggerOptions = exports.systemOptions = exports.scopeOptions = exports.nodesOptions = void 0;
8
9
  exports.useCollectionFieldOptions = useCollectionFieldOptions;
9
10
  exports.useWorkflowVariableOptions = useWorkflowVariableOptions;
10
11
  function _client() {
@@ -23,20 +24,20 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
23
24
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
24
25
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
25
26
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
26
- const VariableTypes = [{
27
- title: `{{t("Node result", { ns: "${_locale.NAMESPACE}" })}}`,
27
+ const nodesOptions = {
28
+ label: `{{t("Node result", { ns: "${_locale.NAMESPACE}" })}}`,
28
29
  value: '$jobsMapByNodeId',
29
- options(types) {
30
+ useOptions(options) {
30
31
  const current = (0, _nodes.useNodeContext)();
31
32
  const upstreams = (0, _nodes.useAvailableUpstreams)(current);
32
- const options = [];
33
+ const result = [];
33
34
  upstreams.forEach(node => {
34
- var _instruction$getOptio;
35
+ var _instruction$useVaria;
35
36
  const instruction = _nodes.instructions.get(node.type);
36
- const subOptions = (_instruction$getOptio = instruction.getOptions) === null || _instruction$getOptio === void 0 ? void 0 : _instruction$getOptio.call(instruction, node.config, types);
37
+ const subOptions = (_instruction$useVaria = instruction.useVariables) === null || _instruction$useVaria === void 0 ? void 0 : _instruction$useVaria.call(instruction, node, options);
37
38
  if (subOptions) {
38
39
  var _node$title;
39
- options.push({
40
+ result.push({
40
41
  key: node.id.toString(),
41
42
  value: node.id.toString(),
42
43
  label: (_node$title = node.title) !== null && _node$title !== void 0 ? _node$title : `#${node.id}`,
@@ -44,29 +45,61 @@ const VariableTypes = [{
44
45
  });
45
46
  }
46
47
  });
47
- return options;
48
+ return result;
48
49
  }
49
- }, {
50
- title: `{{t("Trigger variables", { ns: "${_locale.NAMESPACE}" })}}`,
50
+ };
51
+ exports.nodesOptions = nodesOptions;
52
+ const triggerOptions = {
53
+ label: `{{t("Trigger variables", { ns: "${_locale.NAMESPACE}" })}}`,
51
54
  value: '$context',
52
- options(types) {
53
- var _trigger$getOptions, _trigger$getOptions2;
55
+ useOptions(options) {
56
+ var _trigger$useVariables, _trigger$useVariables2;
54
57
  const _useFlowContext = (0, _FlowContext.useFlowContext)(),
55
58
  workflow = _useFlowContext.workflow;
56
59
  const trigger = _triggers.triggers.get(workflow.type);
57
- return (_trigger$getOptions = trigger === null || trigger === void 0 ? void 0 : (_trigger$getOptions2 = trigger.getOptions) === null || _trigger$getOptions2 === void 0 ? void 0 : _trigger$getOptions2.call(trigger, workflow.config, types)) !== null && _trigger$getOptions !== void 0 ? _trigger$getOptions : null;
60
+ return (_trigger$useVariables = trigger === null || trigger === void 0 ? void 0 : (_trigger$useVariables2 = trigger.useVariables) === null || _trigger$useVariables2 === void 0 ? void 0 : _trigger$useVariables2.call(trigger, workflow.config, options)) !== null && _trigger$useVariables !== void 0 ? _trigger$useVariables : null;
61
+ }
62
+ };
63
+ exports.triggerOptions = triggerOptions;
64
+ const scopeOptions = {
65
+ label: `{{t("Scope variables", { ns: "${_locale.NAMESPACE}" })}}`,
66
+ value: '$scopes',
67
+ useOptions(options) {
68
+ const current = (0, _nodes.useNodeContext)();
69
+ const scopes = (0, _nodes.useUpstreamScopes)(current);
70
+ const result = [];
71
+ scopes.forEach(node => {
72
+ var _instruction$useScope;
73
+ const instruction = _nodes.instructions.get(node.type);
74
+ const subOptions = (_instruction$useScope = instruction.useScopeVariables) === null || _instruction$useScope === void 0 ? void 0 : _instruction$useScope.call(instruction, node, options);
75
+ if (subOptions) {
76
+ var _node$title2;
77
+ result.push({
78
+ key: node.id.toString(),
79
+ value: node.id.toString(),
80
+ label: (_node$title2 = node.title) !== null && _node$title2 !== void 0 ? _node$title2 : `#${node.id}`,
81
+ children: subOptions
82
+ });
83
+ }
84
+ });
85
+ return result;
58
86
  }
59
- }, {
60
- title: `{{t("System variables", { ns: "${_locale.NAMESPACE}" })}}`,
87
+ };
88
+ exports.scopeOptions = scopeOptions;
89
+ const systemOptions = {
90
+ label: `{{t("System variables", { ns: "${_locale.NAMESPACE}" })}}`,
61
91
  value: '$system',
62
- options(types) {
92
+ useOptions({
93
+ types
94
+ }) {
63
95
  return [...(!types || types.includes('date') ? [{
64
96
  key: 'now',
65
97
  value: 'now',
66
98
  label: `{{t("System time")}}`
67
99
  }] : [])];
68
100
  }
69
- }];
101
+ };
102
+ exports.systemOptions = systemOptions;
70
103
  const BaseTypeSets = {
71
104
  boolean: new Set(['checkbox']),
72
105
  number: new Set(['number', 'percent']),
@@ -77,7 +110,7 @@ const BaseTypeSets = {
77
110
  // { type: 'reference', options: { collection: 'attachments', multiple: false } }
78
111
  // { type: 'reference', options: { collection: 'myExpressions', entity: false } }
79
112
  exports.BaseTypeSets = BaseTypeSets;
80
- function matchFieldType(field, type) {
113
+ function matchFieldType(field, type, depth) {
81
114
  const inputType = typeof type;
82
115
  if (inputType === 'string') {
83
116
  var _BaseTypeSets$type;
@@ -95,7 +128,7 @@ function matchFieldType(field, type) {
95
128
  }
96
129
  }
97
130
  if (inputType === 'function') {
98
- return type(field);
131
+ return type(field, depth);
99
132
  }
100
133
  return false;
101
134
  }
@@ -110,32 +143,28 @@ function filterTypedFields(fields, types, depth = 1) {
110
143
  if (isAssociationField(field) && depth && filterTypedFields(useNormalizedFields(field.target), types, depth - 1).length) {
111
144
  return true;
112
145
  }
113
- return types.some(type => matchFieldType(field, type));
146
+ return types.some(type => matchFieldType(field, type, depth));
114
147
  });
115
148
  }
116
- function useWorkflowVariableOptions(types) {
149
+ function useWorkflowVariableOptions(options = {}) {
117
150
  const compile = (0, _client().useCompile)();
118
- const options = VariableTypes.map(item => {
119
- const opts = typeof item.options === 'function' ? item.options(types).filter(Boolean) : item.options;
151
+ const result = [scopeOptions, nodesOptions, triggerOptions, systemOptions].map(item => {
152
+ const opts = typeof item.useOptions === 'function' ? item.useOptions(options).filter(Boolean) : null;
120
153
  return {
121
- label: compile(item.title),
154
+ label: compile(item.label),
122
155
  value: item.value,
123
156
  key: item.value,
124
157
  children: compile(opts),
125
158
  disabled: opts && !opts.length
126
159
  };
127
160
  });
128
- return options;
161
+ return result;
129
162
  }
130
163
  function useNormalizedFields(collectionName) {
131
164
  const compile = (0, _client().useCompile)();
132
165
  const _useCollectionManager = (0, _client().useCollectionManager)(),
133
- getCollection = _useCollectionManager.getCollection;
134
- const collection = getCollection(collectionName);
135
- if (!collection) {
136
- return [];
137
- }
138
- const fields = collection.fields;
166
+ getCollectionFields = _useCollectionManager.getCollectionFields;
167
+ const fields = getCollectionFields(collectionName);
139
168
  const foreignKeyFields = [];
140
169
  const otherFields = [];
141
170
  fields.forEach(field => {
@@ -189,8 +218,9 @@ function useCollectionFieldOptions(options) {
189
218
  _options$depth = options.depth,
190
219
  depth = _options$depth === void 0 ? 1 : _options$depth;
191
220
  const compile = (0, _client().useCompile)();
192
- const normalizedFields = fields !== null && fields !== void 0 ? fields : useNormalizedFields(collection);
193
- const result = filterTypedFields(normalizedFields, types, depth).filter(field => !isAssociationField(field) || depth).map(field => {
221
+ const normalizedFields = useNormalizedFields(collection);
222
+ const computedFields = fields !== null && fields !== void 0 ? fields : normalizedFields;
223
+ const result = filterTypedFields(computedFields, types, depth).filter(field => !isAssociationField(field) || depth).map(field => {
194
224
  var _field$uiSchema5;
195
225
  const label = compile(((_field$uiSchema5 = field.uiSchema) === null || _field$uiSchema5 === void 0 ? void 0 : _field$uiSchema5.title) || field.name);
196
226
  return {
@@ -201,7 +231,8 @@ function useCollectionFieldOptions(options) {
201
231
  collection: field.target,
202
232
  types,
203
233
  depth: depth - 1
204
- }) : null
234
+ }) : null,
235
+ field
205
236
  };
206
237
  });
207
238
  return result;
@@ -169,25 +169,13 @@ class WorkflowPlugin extends _server().Plugin {
169
169
  transaction
170
170
  });
171
171
  // NOTE: not to trigger afterUpdate hook here
172
- yield workflow.update({
173
- executed
174
- }, {
175
- transaction,
176
- hooks: false
177
- });
178
- const allExecuted = yield execution.constructor.count({
179
- where: {
180
- key: workflow.key
181
- },
172
+ yield workflow.increment('executed', {
182
173
  transaction
183
174
  });
184
- yield workflow.constructor.update({
185
- allExecuted
186
- }, {
175
+ yield workflow.constructor.increment('allExecuted', {
187
176
  where: {
188
177
  key: workflow.key
189
178
  },
190
- individualHooks: true,
191
179
  transaction
192
180
  });
193
181
  execution.workflow = workflow;
@@ -38,13 +38,16 @@ export default class Processor {
38
38
  getBranches(node: FlowNodeModel): FlowNodeModel[];
39
39
  findBranchStartNode(node: FlowNodeModel, parent?: FlowNodeModel): FlowNodeModel | null;
40
40
  findBranchParentNode(node: FlowNodeModel): FlowNodeModel | null;
41
+ findBranchEndNode(node: FlowNodeModel): FlowNodeModel | null;
41
42
  findBranchParentJob(job: JobModel, node: FlowNodeModel): JobModel | null;
43
+ findBranchLastJob(node: FlowNodeModel): JobModel | null;
42
44
  getScope(node?: any): {
43
45
  $context: any;
44
46
  $jobsMapByNodeId: {
45
47
  [key: number]: any;
46
48
  };
47
49
  $system: {};
50
+ $scopes: {};
48
51
  };
49
52
  getParsedValue(value: any, node?: any): any;
50
53
  }
@@ -193,7 +193,7 @@ class Processor {
193
193
  });
194
194
  if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
195
195
  // run next node
196
- _this6.logger.debug(`run next node (${node.id})`);
196
+ _this6.logger.debug(`run next node (${node.downstreamId})`);
197
197
  return _this6.run(node.downstream, savedJob);
198
198
  }
199
199
  // all nodes in scope have been executed
@@ -215,7 +215,7 @@ class Processor {
215
215
  end(node, job) {
216
216
  var _this8 = this;
217
217
  return _asyncToGenerator(function* () {
218
- _this8.logger.debug(`branch ended at node (${node.id})})`);
218
+ _this8.logger.debug(`branch ended at node (${node.id})`);
219
219
  const parentNode = _this8.findBranchParentNode(node);
220
220
  // no parent, means on main flow
221
221
  if (parentNode) {
@@ -314,6 +314,14 @@ class Processor {
314
314
  }
315
315
  return null;
316
316
  }
317
+ findBranchEndNode(node) {
318
+ for (let n = node; n; n = n.downstream) {
319
+ if (!n.downstream) {
320
+ return n;
321
+ }
322
+ }
323
+ return null;
324
+ }
317
325
  findBranchParentJob(job, node) {
318
326
  for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
319
327
  if (j.nodeId === node.id) {
@@ -322,6 +330,15 @@ class Processor {
322
330
  }
323
331
  return null;
324
332
  }
333
+ findBranchLastJob(node) {
334
+ for (let n = this.findBranchEndNode(node); n && n !== node.upstream; n = n.upstream) {
335
+ const jobs = Array.from(this.jobsMap.values()).filter(item => item.nodeId === n.id).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
336
+ if (jobs.length) {
337
+ return jobs[jobs.length - 1];
338
+ }
339
+ }
340
+ return null;
341
+ }
325
342
  getScope(node) {
326
343
  const systemFns = {};
327
344
  const scope = {
@@ -342,10 +359,20 @@ class Processor {
342
359
  } finally {
343
360
  _iterator.f();
344
361
  }
362
+ const $scopes = {};
363
+ if (node) {
364
+ for (let n = this.findBranchParentNode(node); n; n = this.findBranchParentNode(n)) {
365
+ const instruction = this.options.plugin.instructions.get(n.type);
366
+ if (typeof instruction.getScope === 'function') {
367
+ $scopes[n.id] = instruction.getScope(n, this.jobsMapByNodeId[n.id], this);
368
+ }
369
+ }
370
+ }
345
371
  return {
346
372
  $context: this.execution.context,
347
373
  $jobsMapByNodeId: this.jobsMapByNodeId,
348
- $system: systemFns
374
+ $system: systemFns,
375
+ $scopes
349
376
  };
350
377
  }
351
378
  getParsedValue(value, node) {
@@ -132,12 +132,12 @@ function migrateConfig(config, oldToNew) {
132
132
  case 'array':
133
133
  return value.map(item => migrate(item));
134
134
  case 'string':
135
- return value.replace(/(\{\{\$jobsMapByNodeId\.)([\w-]+)/g, (_, jobVar, oldNodeId) => {
135
+ return value.replace(/({{\$jobsMapByNodeId|{{\$scopes)\.([\w-]+)/g, (_, jobVar, oldNodeId) => {
136
136
  const newNode = oldToNew.get(Number.parseInt(oldNodeId, 10));
137
137
  if (!newNode) {
138
138
  throw new Error('node configurated for result is not existed');
139
139
  }
140
- return `{{$jobsMapByNodeId.${newNode.id}`;
140
+ return `${jobVar}.${newNode.id}`;
141
141
  });
142
142
  default:
143
143
  return value;
@@ -64,7 +64,8 @@ function _default() {
64
64
  foreignKey: 'key',
65
65
  sourceKey: 'key',
66
66
  // NOTE: no constraints needed here because tricky self-referencing
67
- constraints: false
67
+ constraints: false,
68
+ onDelete: 'NO ACTION'
68
69
  }],
69
70
  // NOTE: use unique index for avoiding deadlock in mysql when setCurrent
70
71
  indexes: [{
@@ -0,0 +1,9 @@
1
+ import FlowNodeModel from '../models/FlowNode';
2
+ import Processor from '../Processor';
3
+ declare const _default: {
4
+ run(node: FlowNodeModel, input: any, processor: Processor): Promise<{
5
+ result: any;
6
+ status: number;
7
+ }>;
8
+ };
9
+ export default _default;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function _sequelize() {
8
+ const data = require("sequelize");
9
+ _sequelize = function _sequelize() {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ var _constants = require("../constants");
15
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
16
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
17
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
18
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
19
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
20
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
21
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
22
+ const aggregators = {
23
+ count: 'count',
24
+ sum: 'sum',
25
+ avg: 'avg',
26
+ min: 'min',
27
+ max: 'max'
28
+ };
29
+ var _default = {
30
+ run(node, input, processor) {
31
+ return _asyncToGenerator(function* () {
32
+ const _node$config = node.config,
33
+ aggregator = _node$config.aggregator,
34
+ associated = _node$config.associated,
35
+ collection = _node$config.collection,
36
+ _node$config$associat = _node$config.association,
37
+ association = _node$config$associat === void 0 ? {} : _node$config$associat,
38
+ _node$config$params = _node$config.params,
39
+ params = _node$config$params === void 0 ? {} : _node$config$params;
40
+ const options = processor.getParsedValue(params);
41
+ const database = node.constructor.database;
42
+ const repo = associated ? database.getRepository(`${association === null || association === void 0 ? void 0 : association.associatedCollection}.${association.name}`, processor.getParsedValue(association === null || association === void 0 ? void 0 : association.associatedKey)) : database.getRepository(collection);
43
+ if (!options.dataType && aggregator === 'avg') {
44
+ options.dataType = _sequelize().DataTypes.DOUBLE;
45
+ }
46
+ const result = yield repo.aggregate(_objectSpread(_objectSpread({}, options), {}, {
47
+ method: aggregators[aggregator],
48
+ transaction: processor.transaction
49
+ }));
50
+ return {
51
+ result: options.dataType === _sequelize().DataTypes.DOUBLE ? Number(result) : result,
52
+ status: _constants.JOB_STATUS.RESOLVED
53
+ };
54
+ })();
55
+ }
56
+ };
57
+ exports.default = _default;
@@ -32,7 +32,7 @@ var _default = {
32
32
  engine = _node$config$engine === void 0 ? 'math.js' : _node$config$engine,
33
33
  _node$config$expressi = _node$config.expression,
34
34
  expression = _node$config$expressi === void 0 ? '' : _node$config$expressi;
35
- let scope = processor.getScope();
35
+ let scope = processor.getScope(node);
36
36
  if (dynamic) {
37
37
  var _parse, _parse2, _node$config$scope;
38
38
  const parsed = (_parse = (0, _utils().parse)(dynamic)(scope)) !== null && _parse !== void 0 ? _parse : {};
@@ -108,7 +108,7 @@ var _default = {
108
108
  const evaluator = _evaluators().evaluators.get(engine);
109
109
  let result = true;
110
110
  try {
111
- result = evaluator ? evaluator(expression, processor.getScope()) : logicCalculate(processor.getParsedValue(calculation));
111
+ result = evaluator ? evaluator(expression, processor.getScope()) : logicCalculate(processor.getParsedValue(calculation, node));
112
112
  } catch (e) {
113
113
  return {
114
114
  result: e.toString(),
@@ -28,7 +28,7 @@ var _default = {
28
28
  const _node$constructor$dat = node.constructor.database.getCollection(collection),
29
29
  repository = _node$constructor$dat.repository,
30
30
  model = _node$constructor$dat.model;
31
- const options = processor.getParsedValue(params);
31
+ const options = processor.getParsedValue(params, node);
32
32
  const result = yield repository.create(_objectSpread(_objectSpread({}, options), {}, {
33
33
  context: {
34
34
  executionId: processor.execution.id
@@ -20,7 +20,7 @@ var _default = {
20
20
  _node$config$params = _node$config.params,
21
21
  params = _node$config$params === void 0 ? {} : _node$config$params;
22
22
  const repo = node.constructor.database.getRepository(collection);
23
- const options = processor.getParsedValue(params);
23
+ const options = processor.getParsedValue(params, node);
24
24
  const result = yield repo.destroy(_objectSpread(_objectSpread({}, options), {}, {
25
25
  context: {
26
26
  executionId: processor.execution.id
@@ -11,6 +11,7 @@ export declare type Runner = (node: FlowNodeModel, input: any, processor: Proces
11
11
  export interface Instruction {
12
12
  run: Runner;
13
13
  resume?: Runner;
14
+ getScope?: (node: FlowNodeModel, job: any, processor: Processor) => any;
14
15
  }
15
16
  declare type InstructionConstructor<T> = {
16
17
  new (p: Plugin): T;
@@ -32,7 +32,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
32
32
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
33
33
  function _default(plugin, more = {}) {
34
34
  const instructions = plugin.instructions;
35
- const natives = ['calculation', 'condition', 'parallel', 'delay', 'manual', 'query', 'create', 'update', 'destroy', 'request'].reduce((result, key) => Object.assign(result, {
35
+ const natives = ['calculation', 'condition', 'parallel', 'loop', 'delay', 'manual', 'query', 'create', 'update', 'destroy', 'aggregate', 'request'].reduce((result, key) => Object.assign(result, {
36
36
  [key]: (0, _utils().requireModule)(_path().default.isAbsolute(key) ? key : _path().default.join(__dirname, key))
37
37
  }), {});
38
38
  for (var _i = 0, _Object$entries = Object.entries(_objectSpread(_objectSpread({}, more), natives)); _i < _Object$entries.length; _i++) {
@@ -0,0 +1,16 @@
1
+ import FlowNodeModel from '../models/FlowNode';
2
+ import JobModel from '../models/Job';
3
+ import Processor from '../Processor';
4
+ declare const _default: {
5
+ run(node: FlowNodeModel, prevJob: JobModel, processor: Processor): Promise<{
6
+ status: number;
7
+ result: number;
8
+ }>;
9
+ resume(node: FlowNodeModel, branchJob: any, processor: Processor): Promise<JobModel>;
10
+ getScope(node: any, index: any, processor: any): {
11
+ item: any;
12
+ index: any;
13
+ length: number;
14
+ };
15
+ };
16
+ export default _default;