@nocobase/plugin-workflow 0.9.2-alpha.4 → 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 (78) 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/FieldsSelect.js +2 -1
  7. package/lib/client/components/NodeDescription.d.ts +2 -0
  8. package/lib/client/components/NodeDescription.js +59 -0
  9. package/lib/client/components/ValueBlock.d.ts +5 -0
  10. package/lib/client/components/ValueBlock.js +110 -0
  11. package/lib/client/index.d.ts +1 -0
  12. package/lib/client/index.js +12 -0
  13. package/lib/client/locale/es-ES.d.ts +130 -0
  14. package/lib/client/locale/es-ES.js +136 -0
  15. package/lib/client/locale/zh-CN.d.ts +35 -6
  16. package/lib/client/locale/zh-CN.js +35 -6
  17. package/lib/client/nodes/aggregate.d.ts +186 -0
  18. package/lib/client/nodes/aggregate.js +349 -0
  19. package/lib/client/nodes/calculation.d.ts +2 -1
  20. package/lib/client/nodes/calculation.js +35 -60
  21. package/lib/client/nodes/condition.d.ts +2 -6
  22. package/lib/client/nodes/condition.js +4 -3
  23. package/lib/client/nodes/create.d.ts +6 -3
  24. package/lib/client/nodes/create.js +16 -7
  25. package/lib/client/nodes/delay.d.ts +1 -0
  26. package/lib/client/nodes/delay.js +1 -0
  27. package/lib/client/nodes/destroy.d.ts +3 -2
  28. package/lib/client/nodes/destroy.js +1 -0
  29. package/lib/client/nodes/index.d.ts +5 -2
  30. package/lib/client/nodes/index.js +96 -105
  31. package/lib/client/nodes/loop.d.ts +29 -0
  32. package/lib/client/nodes/loop.js +165 -0
  33. package/lib/client/nodes/manual/AssigneesSelect.js +8 -6
  34. package/lib/client/nodes/manual/WorkflowTodo.js +1 -8
  35. package/lib/client/nodes/manual/index.d.ts +6 -1
  36. package/lib/client/nodes/manual/index.js +6 -1
  37. package/lib/client/nodes/parallel.d.ts +1 -0
  38. package/lib/client/nodes/parallel.js +2 -1
  39. package/lib/client/nodes/query.d.ts +13 -3
  40. package/lib/client/nodes/query.js +24 -17
  41. package/lib/client/nodes/request.d.ts +1 -0
  42. package/lib/client/nodes/request.js +1 -0
  43. package/lib/client/nodes/update.d.ts +3 -2
  44. package/lib/client/nodes/update.js +1 -0
  45. package/lib/client/schemas/collection.d.ts +2 -2
  46. package/lib/client/schemas/collection.js +5 -5
  47. package/lib/client/style.d.ts +1 -0
  48. package/lib/client/style.js +40 -26
  49. package/lib/client/triggers/collection.d.ts +4 -11
  50. package/lib/client/triggers/collection.js +7 -7
  51. package/lib/client/triggers/index.d.ts +1 -1
  52. package/lib/client/triggers/index.js +5 -3
  53. package/lib/client/triggers/schedule/index.d.ts +3 -1
  54. package/lib/client/triggers/schedule/index.js +6 -4
  55. package/lib/client/variable.d.ts +27 -1
  56. package/lib/client/variable.js +66 -35
  57. package/lib/server/Plugin.d.ts +5 -2
  58. package/lib/server/Plugin.js +2 -14
  59. package/lib/server/Processor.d.ts +3 -0
  60. package/lib/server/Processor.js +34 -8
  61. package/lib/server/actions/workflows.js +2 -2
  62. package/lib/server/collections/workflows.js +2 -1
  63. package/lib/server/functions/index.d.ts +7 -1
  64. package/lib/server/instructions/aggregate.d.ts +9 -0
  65. package/lib/server/instructions/aggregate.js +57 -0
  66. package/lib/server/instructions/calculation.js +6 -7
  67. package/lib/server/instructions/condition.js +1 -1
  68. package/lib/server/instructions/create.js +1 -1
  69. package/lib/server/instructions/destroy.js +1 -1
  70. package/lib/server/instructions/index.d.ts +1 -0
  71. package/lib/server/instructions/index.js +1 -1
  72. package/lib/server/instructions/loop.d.ts +16 -0
  73. package/lib/server/instructions/loop.js +107 -0
  74. package/lib/server/instructions/parallel.js +17 -10
  75. package/lib/server/instructions/query.js +1 -4
  76. package/lib/server/instructions/request.js +1 -1
  77. package/lib/server/instructions/update.js +1 -1
  78. package/package.json +13 -14
@@ -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,11 +110,11 @@ 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;
84
- return Boolean((_BaseTypeSets$type = BaseTypeSets[type]) === null || _BaseTypeSets$type === void 0 ? void 0 : _BaseTypeSets$type.has(field.interface));
117
+ return (_BaseTypeSets$type = BaseTypeSets[type]) === null || _BaseTypeSets$type === void 0 ? void 0 : _BaseTypeSets$type.has(field.interface);
85
118
  }
86
119
  if (inputType === 'object' && type.type === 'reference') {
87
120
  if (isAssociationField(field)) {
@@ -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;
@@ -5,12 +5,13 @@ import ExecutionModel from './models/Execution';
5
5
  import WorkflowModel from './models/Workflow';
6
6
  import Processor from './Processor';
7
7
  import { Trigger } from './triggers';
8
+ import { CustomFunction } from './functions';
8
9
  import { Logger } from '@nocobase/logger';
9
10
  declare type ID = number | string;
10
11
  export default class WorkflowPlugin extends Plugin {
11
12
  instructions: Registry<Instruction>;
12
13
  triggers: Registry<Trigger>;
13
- functions: Registry<Function>;
14
+ functions: Registry<CustomFunction>;
14
15
  private executing;
15
16
  private pending;
16
17
  private events;
@@ -19,7 +20,9 @@ export default class WorkflowPlugin extends Plugin {
19
20
  onBeforeSave: (instance: WorkflowModel, options: any) => Promise<void>;
20
21
  load(): Promise<void>;
21
22
  toggle(workflow: WorkflowModel, enable?: boolean): void;
22
- trigger(workflow: WorkflowModel, context: Object, options?: {
23
+ trigger(workflow: WorkflowModel, context: {
24
+ [key: string]: any;
25
+ }, options?: {
23
26
  context?: any;
24
27
  }): void;
25
28
  private prepare;
@@ -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
  }
@@ -18,15 +18,14 @@ function _evaluators() {
18
18
  };
19
19
  return data;
20
20
  }
21
- function _jsonTemplates() {
22
- const data = _interopRequireDefault(require("json-templates"));
23
- _jsonTemplates = function _jsonTemplates() {
21
+ function _utils() {
22
+ const data = require("@nocobase/utils");
23
+ _utils = function _utils() {
24
24
  return data;
25
25
  };
26
26
  return data;
27
27
  }
28
28
  var _constants = require("./constants");
29
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30
29
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
31
30
  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; }
32
31
  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; }
@@ -194,7 +193,7 @@ class Processor {
194
193
  });
195
194
  if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
196
195
  // run next node
197
- _this6.logger.debug(`run next node (${node.id})`);
196
+ _this6.logger.debug(`run next node (${node.downstreamId})`);
198
197
  return _this6.run(node.downstream, savedJob);
199
198
  }
200
199
  // all nodes in scope have been executed
@@ -216,7 +215,7 @@ class Processor {
216
215
  end(node, job) {
217
216
  var _this8 = this;
218
217
  return _asyncToGenerator(function* () {
219
- _this8.logger.debug(`branch ended at node (${node.id})})`);
218
+ _this8.logger.debug(`branch ended at node (${node.id})`);
220
219
  const parentNode = _this8.findBranchParentNode(node);
221
220
  // no parent, means on main flow
222
221
  if (parentNode) {
@@ -315,6 +314,14 @@ class Processor {
315
314
  }
316
315
  return null;
317
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
+ }
318
325
  findBranchParentJob(job, node) {
319
326
  for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
320
327
  if (j.nodeId === node.id) {
@@ -323,6 +330,15 @@ class Processor {
323
330
  }
324
331
  return null;
325
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
+ }
326
342
  getScope(node) {
327
343
  const systemFns = {};
328
344
  const scope = {
@@ -343,14 +359,24 @@ class Processor {
343
359
  } finally {
344
360
  _iterator.f();
345
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
+ }
346
371
  return {
347
372
  $context: this.execution.context,
348
373
  $jobsMapByNodeId: this.jobsMapByNodeId,
349
- $system: systemFns
374
+ $system: systemFns,
375
+ $scopes
350
376
  };
351
377
  }
352
378
  getParsedValue(value, node) {
353
- const template = (0, _jsonTemplates().default)(value);
379
+ const template = (0, _utils().parse)(value);
354
380
  const scope = this.getScope(node);
355
381
  template.parameters.forEach(({
356
382
  key
@@ -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: [{
@@ -1,4 +1,10 @@
1
1
  import Plugin from '..';
2
+ import ExecutionModel from '../models/Execution';
3
+ import FlowNodeModel from '../models/FlowNode';
4
+ export declare type CustomFunction = (this: {
5
+ execution: ExecutionModel;
6
+ node?: FlowNodeModel;
7
+ }) => any;
2
8
  export default function ({ functions }: Plugin, more?: {
3
- [key: string]: Function;
9
+ [key: string]: CustomFunction;
4
10
  }): void;
@@ -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;
@@ -11,15 +11,14 @@ function _evaluators() {
11
11
  };
12
12
  return data;
13
13
  }
14
- function _jsonTemplates() {
15
- const data = _interopRequireDefault(require("json-templates"));
16
- _jsonTemplates = function _jsonTemplates() {
14
+ function _utils() {
15
+ const data = require("@nocobase/utils");
16
+ _utils = function _utils() {
17
17
  return data;
18
18
  };
19
19
  return data;
20
20
  }
21
21
  var _constants = require("../constants");
22
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
22
  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); } }
24
23
  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); }); }; }
25
24
  var _default = {
@@ -33,13 +32,13 @@ var _default = {
33
32
  engine = _node$config$engine === void 0 ? 'math.js' : _node$config$engine,
34
33
  _node$config$expressi = _node$config.expression,
35
34
  expression = _node$config$expressi === void 0 ? '' : _node$config$expressi;
36
- let scope = processor.getScope();
35
+ let scope = processor.getScope(node);
37
36
  if (dynamic) {
38
37
  var _parse, _parse2, _node$config$scope;
39
- const parsed = (_parse = (0, _jsonTemplates().default)(dynamic)(scope)) !== null && _parse !== void 0 ? _parse : {};
38
+ const parsed = (_parse = (0, _utils().parse)(dynamic)(scope)) !== null && _parse !== void 0 ? _parse : {};
40
39
  engine = parsed.engine;
41
40
  expression = parsed.expression;
42
- scope = (_parse2 = (0, _jsonTemplates().default)((_node$config$scope = node.config.scope) !== null && _node$config$scope !== void 0 ? _node$config$scope : '')(scope)) !== null && _parse2 !== void 0 ? _parse2 : {};
41
+ scope = (_parse2 = (0, _utils().parse)((_node$config$scope = node.config.scope) !== null && _node$config$scope !== void 0 ? _node$config$scope : '')(scope)) !== null && _parse2 !== void 0 ? _parse2 : {};
43
42
  }
44
43
  const evaluator = _evaluators().evaluators.get(engine);
45
44
  try {
@@ -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;