@memberjunction/core-actions 2.54.0 → 2.55.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 (118) hide show
  1. package/dist/custom/ai/execute-ai-prompt.action.d.ts +94 -0
  2. package/dist/custom/ai/execute-ai-prompt.action.d.ts.map +1 -0
  3. package/dist/custom/ai/execute-ai-prompt.action.js +274 -0
  4. package/dist/custom/ai/execute-ai-prompt.action.js.map +1 -0
  5. package/dist/custom/communication/slack-webhook.action.d.ts +101 -0
  6. package/dist/custom/communication/slack-webhook.action.d.ts.map +1 -0
  7. package/dist/custom/communication/slack-webhook.action.js +269 -0
  8. package/dist/custom/communication/slack-webhook.action.js.map +1 -0
  9. package/dist/custom/communication/teams-webhook.action.d.ts +96 -0
  10. package/dist/custom/communication/teams-webhook.action.d.ts.map +1 -0
  11. package/dist/custom/communication/teams-webhook.action.js +275 -0
  12. package/dist/custom/communication/teams-webhook.action.js.map +1 -0
  13. package/dist/custom/data/aggregate-data.action.d.ts +91 -0
  14. package/dist/custom/data/aggregate-data.action.d.ts.map +1 -0
  15. package/dist/custom/data/aggregate-data.action.js +333 -0
  16. package/dist/custom/data/aggregate-data.action.js.map +1 -0
  17. package/dist/custom/data/csv-parser.action.d.ts +68 -0
  18. package/dist/custom/data/csv-parser.action.d.ts.map +1 -0
  19. package/dist/custom/data/csv-parser.action.js +184 -0
  20. package/dist/custom/data/csv-parser.action.js.map +1 -0
  21. package/dist/custom/data/data-mapper.action.d.ts +89 -0
  22. package/dist/custom/data/data-mapper.action.d.ts.map +1 -0
  23. package/dist/custom/data/data-mapper.action.js +325 -0
  24. package/dist/custom/data/data-mapper.action.js.map +1 -0
  25. package/dist/custom/data/json-transform.action.d.ts +57 -0
  26. package/dist/custom/data/json-transform.action.d.ts.map +1 -0
  27. package/dist/custom/data/json-transform.action.js +205 -0
  28. package/dist/custom/data/json-transform.action.js.map +1 -0
  29. package/dist/custom/data/xml-parser.action.d.ts +85 -0
  30. package/dist/custom/data/xml-parser.action.d.ts.map +1 -0
  31. package/dist/custom/data/xml-parser.action.js +326 -0
  32. package/dist/custom/data/xml-parser.action.js.map +1 -0
  33. package/dist/custom/files/excel-reader.action.d.ts +86 -0
  34. package/dist/custom/files/excel-reader.action.d.ts.map +1 -0
  35. package/dist/custom/files/excel-reader.action.js +348 -0
  36. package/dist/custom/files/excel-reader.action.js.map +1 -0
  37. package/dist/custom/files/excel-writer.action.d.ts +79 -0
  38. package/dist/custom/files/excel-writer.action.d.ts.map +1 -0
  39. package/dist/custom/files/excel-writer.action.js +325 -0
  40. package/dist/custom/files/excel-writer.action.js.map +1 -0
  41. package/dist/custom/files/file-compress.action.d.ts +90 -0
  42. package/dist/custom/files/file-compress.action.d.ts.map +1 -0
  43. package/dist/custom/files/file-compress.action.js +346 -0
  44. package/dist/custom/files/file-compress.action.js.map +1 -0
  45. package/dist/custom/files/pdf-extractor.action.d.ts +86 -0
  46. package/dist/custom/files/pdf-extractor.action.d.ts.map +1 -0
  47. package/dist/custom/files/pdf-extractor.action.js +247 -0
  48. package/dist/custom/files/pdf-extractor.action.js.map +1 -0
  49. package/dist/custom/files/pdf-generator.action.d.ts +70 -0
  50. package/dist/custom/files/pdf-generator.action.d.ts.map +1 -0
  51. package/dist/custom/files/pdf-generator.action.js +286 -0
  52. package/dist/custom/files/pdf-generator.action.js.map +1 -0
  53. package/dist/custom/integration/api-rate-limiter.action.d.ts +88 -0
  54. package/dist/custom/integration/api-rate-limiter.action.d.ts.map +1 -0
  55. package/dist/custom/integration/api-rate-limiter.action.js +363 -0
  56. package/dist/custom/integration/api-rate-limiter.action.js.map +1 -0
  57. package/dist/custom/integration/graphql-query.action.d.ts +92 -0
  58. package/dist/custom/integration/graphql-query.action.d.ts.map +1 -0
  59. package/dist/custom/integration/graphql-query.action.js +251 -0
  60. package/dist/custom/integration/graphql-query.action.js.map +1 -0
  61. package/dist/custom/integration/http-request.action.d.ts +96 -0
  62. package/dist/custom/integration/http-request.action.d.ts.map +1 -0
  63. package/dist/custom/integration/http-request.action.js +316 -0
  64. package/dist/custom/integration/http-request.action.js.map +1 -0
  65. package/dist/custom/integration/oauth-flow.action.d.ts +130 -0
  66. package/dist/custom/integration/oauth-flow.action.d.ts.map +1 -0
  67. package/dist/custom/integration/oauth-flow.action.js +624 -0
  68. package/dist/custom/integration/oauth-flow.action.js.map +1 -0
  69. package/dist/custom/security/password-strength.action.d.ts +129 -0
  70. package/dist/custom/security/password-strength.action.d.ts.map +1 -0
  71. package/dist/custom/security/password-strength.action.js +463 -0
  72. package/dist/custom/security/password-strength.action.js.map +1 -0
  73. package/dist/custom/utilities/base-file-handler.d.ts +54 -0
  74. package/dist/custom/utilities/base-file-handler.d.ts.map +1 -0
  75. package/dist/custom/utilities/base-file-handler.js +167 -0
  76. package/dist/custom/utilities/base-file-handler.js.map +1 -0
  77. package/dist/custom/utilities/index.d.ts +3 -0
  78. package/dist/custom/utilities/index.d.ts.map +1 -0
  79. package/dist/custom/utilities/index.js +19 -0
  80. package/dist/custom/utilities/index.js.map +1 -0
  81. package/dist/custom/utilities/json-param-helper.d.ts +33 -0
  82. package/dist/custom/utilities/json-param-helper.d.ts.map +1 -0
  83. package/dist/custom/utilities/json-param-helper.js +66 -0
  84. package/dist/custom/utilities/json-param-helper.js.map +1 -0
  85. package/dist/custom/web/duckduckgo-rate-limiter.d.ts +72 -0
  86. package/dist/custom/web/duckduckgo-rate-limiter.d.ts.map +1 -0
  87. package/dist/custom/web/duckduckgo-rate-limiter.js +175 -0
  88. package/dist/custom/web/duckduckgo-rate-limiter.js.map +1 -0
  89. package/dist/custom/web/web-search.action.d.ts +1 -0
  90. package/dist/custom/web/web-search.action.d.ts.map +1 -1
  91. package/dist/custom/web/web-search.action.js +48 -20
  92. package/dist/custom/web/web-search.action.js.map +1 -1
  93. package/dist/custom/workflow/conditional.action.d.ts +94 -0
  94. package/dist/custom/workflow/conditional.action.d.ts.map +1 -0
  95. package/dist/custom/workflow/conditional.action.js +274 -0
  96. package/dist/custom/workflow/conditional.action.js.map +1 -0
  97. package/dist/custom/workflow/delay.action.d.ts +76 -0
  98. package/dist/custom/workflow/delay.action.d.ts.map +1 -0
  99. package/dist/custom/workflow/delay.action.js +187 -0
  100. package/dist/custom/workflow/delay.action.js.map +1 -0
  101. package/dist/custom/workflow/loop.action.d.ts +112 -0
  102. package/dist/custom/workflow/loop.action.d.ts.map +1 -0
  103. package/dist/custom/workflow/loop.action.js +380 -0
  104. package/dist/custom/workflow/loop.action.js.map +1 -0
  105. package/dist/custom/workflow/parallel-execute.action.d.ts +105 -0
  106. package/dist/custom/workflow/parallel-execute.action.d.ts.map +1 -0
  107. package/dist/custom/workflow/parallel-execute.action.js +457 -0
  108. package/dist/custom/workflow/parallel-execute.action.js.map +1 -0
  109. package/dist/custom/workflow/retry.action.d.ts +90 -0
  110. package/dist/custom/workflow/retry.action.d.ts.map +1 -0
  111. package/dist/custom/workflow/retry.action.js +378 -0
  112. package/dist/custom/workflow/retry.action.js.map +1 -0
  113. package/dist/index.d.ts +23 -0
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +75 -0
  116. package/dist/index.js.map +1 -1
  117. package/package.json +25 -10
  118. package/readme.md +11270 -101
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LoadDelayAction = exports.DelayAction = void 0;
10
+ const global_1 = require("@memberjunction/global");
11
+ const actions_1 = require("@memberjunction/actions");
12
+ /**
13
+ * Action that adds delays to workflows
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Fixed delay
18
+ * await runAction({
19
+ * ActionName: 'Delay',
20
+ * Params: [{
21
+ * Name: 'DelayMs',
22
+ * Value: 5000
23
+ * }]
24
+ * });
25
+ *
26
+ * // Random delay between min and max
27
+ * await runAction({
28
+ * ActionName: 'Delay',
29
+ * Params: [{
30
+ * Name: 'DelayType',
31
+ * Value: 'random'
32
+ * }, {
33
+ * Name: 'MinDelayMs',
34
+ * Value: 1000
35
+ * }, {
36
+ * Name: 'MaxDelayMs',
37
+ * Value: 5000
38
+ * }]
39
+ * });
40
+ *
41
+ * // Delay with message
42
+ * await runAction({
43
+ * ActionName: 'Delay',
44
+ * Params: [{
45
+ * Name: 'DelayMs',
46
+ * Value: 3000
47
+ * }, {
48
+ * Name: 'Message',
49
+ * Value: 'Waiting for external system to process...'
50
+ * }]
51
+ * });
52
+ * ```
53
+ */
54
+ let DelayAction = class DelayAction extends actions_1.BaseAction {
55
+ /**
56
+ * Adds a delay to the workflow
57
+ *
58
+ * @param params - The action parameters containing:
59
+ * - DelayMs: Delay in milliseconds (required for fixed delay)
60
+ * - DelayType: "fixed" | "random" (default: "fixed")
61
+ * - MinDelayMs: Minimum delay for random delays (required for random)
62
+ * - MaxDelayMs: Maximum delay for random delays (required for random)
63
+ * - Message: Optional message to include in result
64
+ *
65
+ * @returns Success with actual delay applied
66
+ */
67
+ async InternalRunAction(params) {
68
+ try {
69
+ const delayType = (this.getParamValue(params, 'delaytype') || 'fixed').toLowerCase();
70
+ const message = this.getParamValue(params, 'message');
71
+ let actualDelay;
72
+ if (delayType === 'random') {
73
+ // Random delay
74
+ const minDelay = this.getNumericParam(params, 'mindelayms', 0);
75
+ const maxDelay = this.getNumericParam(params, 'maxdelayms', 0);
76
+ if (minDelay < 0 || maxDelay < 0) {
77
+ return {
78
+ Success: false,
79
+ Message: "Delay values must be non-negative",
80
+ ResultCode: "INVALID_DELAY"
81
+ };
82
+ }
83
+ if (minDelay > maxDelay) {
84
+ return {
85
+ Success: false,
86
+ Message: "MinDelayMs must be less than or equal to MaxDelayMs",
87
+ ResultCode: "INVALID_DELAY_RANGE"
88
+ };
89
+ }
90
+ // Calculate random delay
91
+ actualDelay = Math.floor(minDelay + Math.random() * (maxDelay - minDelay + 1));
92
+ }
93
+ else {
94
+ // Fixed delay
95
+ actualDelay = this.getNumericParam(params, 'delayms', 0);
96
+ if (actualDelay < 0) {
97
+ return {
98
+ Success: false,
99
+ Message: "DelayMs must be non-negative",
100
+ ResultCode: "INVALID_DELAY"
101
+ };
102
+ }
103
+ }
104
+ // Record start time
105
+ const startTime = Date.now();
106
+ // Perform the delay
107
+ await this.delay(actualDelay);
108
+ // Calculate actual elapsed time
109
+ const elapsedTime = Date.now() - startTime;
110
+ // Add output parameters
111
+ params.Params.push({
112
+ Name: 'ActualDelayMs',
113
+ Type: 'Output',
114
+ Value: actualDelay
115
+ });
116
+ params.Params.push({
117
+ Name: 'ElapsedTimeMs',
118
+ Type: 'Output',
119
+ Value: elapsedTime
120
+ });
121
+ params.Params.push({
122
+ Name: 'DelayType',
123
+ Type: 'Output',
124
+ Value: delayType
125
+ });
126
+ // Build result message
127
+ const resultData = {
128
+ message: message || `Delay completed`,
129
+ delayType: delayType,
130
+ requestedDelayMs: actualDelay,
131
+ actualElapsedMs: elapsedTime,
132
+ timeDifference: elapsedTime - actualDelay
133
+ };
134
+ if (delayType === 'random') {
135
+ resultData.minDelayMs = this.getNumericParam(params, 'mindelayms', 0);
136
+ resultData.maxDelayMs = this.getNumericParam(params, 'maxdelayms', 0);
137
+ }
138
+ return {
139
+ Success: true,
140
+ ResultCode: "DELAY_COMPLETED",
141
+ Message: JSON.stringify(resultData, null, 2)
142
+ };
143
+ }
144
+ catch (error) {
145
+ return {
146
+ Success: false,
147
+ Message: `Delay action failed: ${error instanceof Error ? error.message : String(error)}`,
148
+ ResultCode: "DELAY_FAILED"
149
+ };
150
+ }
151
+ }
152
+ /**
153
+ * Perform the actual delay
154
+ */
155
+ delay(ms) {
156
+ return new Promise(resolve => setTimeout(resolve, ms));
157
+ }
158
+ /**
159
+ * Get numeric parameter with default
160
+ */
161
+ getNumericParam(params, name, defaultValue) {
162
+ const value = this.getParamValue(params, name);
163
+ if (value === undefined || value === null)
164
+ return defaultValue;
165
+ const num = Number(value);
166
+ return isNaN(num) ? defaultValue : num;
167
+ }
168
+ /**
169
+ * Get parameter value by name (case-insensitive)
170
+ */
171
+ getParamValue(params, name) {
172
+ const param = params.Params.find(p => p.Name.toLowerCase() === name.toLowerCase());
173
+ return param?.Value;
174
+ }
175
+ };
176
+ exports.DelayAction = DelayAction;
177
+ exports.DelayAction = DelayAction = __decorate([
178
+ (0, global_1.RegisterClass)(actions_1.BaseAction, "Delay")
179
+ ], DelayAction);
180
+ /**
181
+ * Loader function to ensure the DelayAction class is included in the bundle
182
+ */
183
+ function LoadDelayAction() {
184
+ // Stub function to prevent tree shaking
185
+ }
186
+ exports.LoadDelayAction = LoadDelayAction;
187
+ //# sourceMappingURL=delay.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delay.action.js","sourceRoot":"","sources":["../../../src/custom/workflow/delay.action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { ActionResultSimple, RunActionParams } from "@memberjunction/actions-base";
2
+ import { BaseAction } from "@memberjunction/actions";
3
+ /**
4
+ * Action that iterates over collections executing actions for each item
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // Process array of items
9
+ * await runAction({
10
+ * ActionName: 'Loop',
11
+ * Params: [{
12
+ * Name: 'Items',
13
+ * Value: [
14
+ * { name: 'John', email: 'john@example.com' },
15
+ * { name: 'Jane', email: 'jane@example.com' }
16
+ * ]
17
+ * }, {
18
+ * Name: 'ItemVariableName',
19
+ * Value: 'user'
20
+ * }, {
21
+ * Name: 'Action',
22
+ * Value: {
23
+ * ActionName: 'Send Single Message',
24
+ * Params: {
25
+ * To: '{{user.email}}',
26
+ * Subject: 'Welcome {{user.name}}'
27
+ * }
28
+ * }
29
+ * }]
30
+ * });
31
+ *
32
+ * // Parallel processing with limit
33
+ * await runAction({
34
+ * ActionName: 'Loop',
35
+ * Params: [{
36
+ * Name: 'Items',
37
+ * Value: fileUrls
38
+ * }, {
39
+ * Name: 'Parallel',
40
+ * Value: true
41
+ * }, {
42
+ * Name: 'MaxConcurrent',
43
+ * Value: 5
44
+ * }, {
45
+ * Name: 'Action',
46
+ * Value: {
47
+ * ActionName: 'Web Page Content',
48
+ * Params: { URL: '{{item}}' }
49
+ * }
50
+ * }]
51
+ * });
52
+ * ```
53
+ */
54
+ export declare class LoopAction extends BaseAction {
55
+ /**
56
+ * Iterates over collections executing actions
57
+ *
58
+ * @param params - The action parameters containing:
59
+ * - Items: Array to iterate over (required)
60
+ * - ItemVariableName: Variable name for current item (default: 'item')
61
+ * - IndexVariableName: Variable name for current index (default: 'index')
62
+ * - Action: Action configuration to execute per item (required)
63
+ * - Parallel: Boolean - run iterations in parallel (default: false)
64
+ * - MaxConcurrent: Max parallel executions (default: 10)
65
+ * - ContinueOnError: Boolean - continue if an iteration fails (default: false)
66
+ * - IncludeContext: Additional context to pass to each action (optional)
67
+ *
68
+ * @returns Array of results from each iteration
69
+ */
70
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
71
+ /**
72
+ * Execute a single iteration
73
+ */
74
+ private executeIteration;
75
+ /**
76
+ * Prepare action configuration with template replacement
77
+ */
78
+ private prepareActionConfig;
79
+ /**
80
+ * Replace template variables in object recursively
81
+ */
82
+ private replaceTemplates;
83
+ /**
84
+ * Replace template variables in a string
85
+ */
86
+ private replaceTemplateString;
87
+ /**
88
+ * Get value from object by dot-notation path
89
+ */
90
+ private getValueByPath;
91
+ /**
92
+ * Chunk array into smaller arrays
93
+ */
94
+ private chunkArray;
95
+ /**
96
+ * Get numeric parameter with default
97
+ */
98
+ private getNumericParam;
99
+ /**
100
+ * Get boolean parameter with default
101
+ */
102
+ private getBooleanParam;
103
+ /**
104
+ * Get parameter value by name (case-insensitive)
105
+ */
106
+ private getParamValue;
107
+ }
108
+ /**
109
+ * Loader function to ensure the LoopAction class is included in the bundle
110
+ */
111
+ export declare function LoadLoopAction(): void;
112
+ //# sourceMappingURL=loop.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.action.d.ts","sourceRoot":"","sources":["../../../src/custom/workflow/loop.action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBACa,UAAW,SAAQ,UAAU;IAEtC;;;;;;;;;;;;;;OAcG;cACa,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8LvF;;OAEG;YACW,gBAAgB;IAgC9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAIxB;AAED;;GAEG;AACH,wBAAgB,cAAc,SAE7B"}
@@ -0,0 +1,380 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LoadLoopAction = exports.LoopAction = void 0;
10
+ const global_1 = require("@memberjunction/global");
11
+ const actions_1 = require("@memberjunction/actions");
12
+ const actions_2 = require("@memberjunction/actions");
13
+ const json_param_helper_1 = require("../utilities/json-param-helper");
14
+ /**
15
+ * Action that iterates over collections executing actions for each item
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Process array of items
20
+ * await runAction({
21
+ * ActionName: 'Loop',
22
+ * Params: [{
23
+ * Name: 'Items',
24
+ * Value: [
25
+ * { name: 'John', email: 'john@example.com' },
26
+ * { name: 'Jane', email: 'jane@example.com' }
27
+ * ]
28
+ * }, {
29
+ * Name: 'ItemVariableName',
30
+ * Value: 'user'
31
+ * }, {
32
+ * Name: 'Action',
33
+ * Value: {
34
+ * ActionName: 'Send Single Message',
35
+ * Params: {
36
+ * To: '{{user.email}}',
37
+ * Subject: 'Welcome {{user.name}}'
38
+ * }
39
+ * }
40
+ * }]
41
+ * });
42
+ *
43
+ * // Parallel processing with limit
44
+ * await runAction({
45
+ * ActionName: 'Loop',
46
+ * Params: [{
47
+ * Name: 'Items',
48
+ * Value: fileUrls
49
+ * }, {
50
+ * Name: 'Parallel',
51
+ * Value: true
52
+ * }, {
53
+ * Name: 'MaxConcurrent',
54
+ * Value: 5
55
+ * }, {
56
+ * Name: 'Action',
57
+ * Value: {
58
+ * ActionName: 'Web Page Content',
59
+ * Params: { URL: '{{item}}' }
60
+ * }
61
+ * }]
62
+ * });
63
+ * ```
64
+ */
65
+ let LoopAction = class LoopAction extends actions_1.BaseAction {
66
+ /**
67
+ * Iterates over collections executing actions
68
+ *
69
+ * @param params - The action parameters containing:
70
+ * - Items: Array to iterate over (required)
71
+ * - ItemVariableName: Variable name for current item (default: 'item')
72
+ * - IndexVariableName: Variable name for current index (default: 'index')
73
+ * - Action: Action configuration to execute per item (required)
74
+ * - Parallel: Boolean - run iterations in parallel (default: false)
75
+ * - MaxConcurrent: Max parallel executions (default: 10)
76
+ * - ContinueOnError: Boolean - continue if an iteration fails (default: false)
77
+ * - IncludeContext: Additional context to pass to each action (optional)
78
+ *
79
+ * @returns Array of results from each iteration
80
+ */
81
+ async InternalRunAction(params) {
82
+ try {
83
+ const items = json_param_helper_1.JSONParamHelper.getJSONParam(params, 'items');
84
+ const itemVariableName = this.getParamValue(params, 'itemvariablename') || 'item';
85
+ const indexVariableName = this.getParamValue(params, 'indexvariablename') || 'index';
86
+ const actionConfig = json_param_helper_1.JSONParamHelper.getJSONParam(params, 'action');
87
+ const parallel = this.getBooleanParam(params, 'parallel', false);
88
+ const maxConcurrent = this.getNumericParam(params, 'maxconcurrent', 10);
89
+ const continueOnError = this.getBooleanParam(params, 'continueonerror', false);
90
+ const includeContext = json_param_helper_1.JSONParamHelper.getJSONParam(params, 'includecontext') || {};
91
+ // Validate required parameters
92
+ if (!items) {
93
+ return {
94
+ Success: false,
95
+ Message: "Items parameter is required",
96
+ ResultCode: "MISSING_ITEMS"
97
+ };
98
+ }
99
+ if (!Array.isArray(items)) {
100
+ return {
101
+ Success: false,
102
+ Message: "Items must be an array",
103
+ ResultCode: "INVALID_ITEMS"
104
+ };
105
+ }
106
+ if (!actionConfig) {
107
+ return {
108
+ Success: false,
109
+ Message: "Action parameter is required",
110
+ ResultCode: "MISSING_ACTION"
111
+ };
112
+ }
113
+ if (!actionConfig.ActionName) {
114
+ return {
115
+ Success: false,
116
+ Message: "Action configuration must include ActionName",
117
+ ResultCode: "INVALID_ACTION"
118
+ };
119
+ }
120
+ // Track results
121
+ const results = [];
122
+ const errors = [];
123
+ let successCount = 0;
124
+ let errorCount = 0;
125
+ // Execute iterations
126
+ if (parallel) {
127
+ // Parallel execution with concurrency limit
128
+ const chunks = this.chunkArray(items, maxConcurrent);
129
+ for (const chunk of chunks) {
130
+ const chunkPromises = chunk.map((item, chunkIndex) => {
131
+ const globalIndex = chunks.indexOf(chunk) * maxConcurrent + chunkIndex;
132
+ return this.executeIteration(item, globalIndex, itemVariableName, indexVariableName, actionConfig, includeContext, params.ContextUser);
133
+ });
134
+ const chunkResults = await Promise.allSettled(chunkPromises);
135
+ for (let i = 0; i < chunkResults.length; i++) {
136
+ const result = chunkResults[i];
137
+ const globalIndex = chunks.indexOf(chunk) * maxConcurrent + i;
138
+ if (result.status === 'fulfilled') {
139
+ results[globalIndex] = result.value;
140
+ if (result.value.Success) {
141
+ successCount++;
142
+ }
143
+ else {
144
+ errorCount++;
145
+ errors.push({ index: globalIndex, error: result.value.Message });
146
+ if (!continueOnError)
147
+ break;
148
+ }
149
+ }
150
+ else {
151
+ errorCount++;
152
+ const errorResult = {
153
+ Success: false,
154
+ Message: result.reason?.message || String(result.reason),
155
+ ResultCode: "ITERATION_ERROR"
156
+ };
157
+ results[globalIndex] = errorResult;
158
+ errors.push({ index: globalIndex, error: result.reason });
159
+ if (!continueOnError)
160
+ break;
161
+ }
162
+ }
163
+ if (!continueOnError && errorCount > 0)
164
+ break;
165
+ }
166
+ }
167
+ else {
168
+ // Sequential execution
169
+ for (let i = 0; i < items.length; i++) {
170
+ try {
171
+ const result = await this.executeIteration(items[i], i, itemVariableName, indexVariableName, actionConfig, includeContext, params.ContextUser);
172
+ results.push(result);
173
+ if (result.Success) {
174
+ successCount++;
175
+ }
176
+ else {
177
+ errorCount++;
178
+ errors.push({ index: i, error: result.Message });
179
+ if (!continueOnError)
180
+ break;
181
+ }
182
+ }
183
+ catch (error) {
184
+ errorCount++;
185
+ const errorResult = {
186
+ Success: false,
187
+ Message: error instanceof Error ? error.message : String(error),
188
+ ResultCode: "ITERATION_ERROR"
189
+ };
190
+ results.push(errorResult);
191
+ errors.push({ index: i, error: error });
192
+ if (!continueOnError)
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ // Add output parameters
198
+ params.Params.push({
199
+ Name: 'Results',
200
+ Type: 'Output',
201
+ Value: results
202
+ });
203
+ params.Params.push({
204
+ Name: 'SuccessCount',
205
+ Type: 'Output',
206
+ Value: successCount
207
+ });
208
+ params.Params.push({
209
+ Name: 'ErrorCount',
210
+ Type: 'Output',
211
+ Value: errorCount
212
+ });
213
+ if (errors.length > 0) {
214
+ params.Params.push({
215
+ Name: 'Errors',
216
+ Type: 'Output',
217
+ Value: errors
218
+ });
219
+ }
220
+ // Determine overall success
221
+ const allSuccessful = errorCount === 0;
222
+ const someSuccessful = successCount > 0;
223
+ return {
224
+ Success: continueOnError ? someSuccessful : allSuccessful,
225
+ ResultCode: allSuccessful ? "ALL_SUCCESS" : (someSuccessful ? "PARTIAL_SUCCESS" : "ALL_FAILED"),
226
+ Message: JSON.stringify({
227
+ message: `Loop completed: ${successCount} successful, ${errorCount} failed`,
228
+ totalItems: items.length,
229
+ successCount: successCount,
230
+ errorCount: errorCount,
231
+ parallel: parallel,
232
+ continueOnError: continueOnError,
233
+ errors: errors.length > 0 ? errors : undefined
234
+ }, null, 2)
235
+ };
236
+ }
237
+ catch (error) {
238
+ return {
239
+ Success: false,
240
+ Message: `Loop action failed: ${error instanceof Error ? error.message : String(error)}`,
241
+ ResultCode: "LOOP_FAILED"
242
+ };
243
+ }
244
+ }
245
+ /**
246
+ * Execute a single iteration
247
+ */
248
+ async executeIteration(item, index, itemVariableName, indexVariableName, actionConfig, includeContext, contextUser) {
249
+ // Build context for this iteration
250
+ const iterationContext = {
251
+ ...includeContext,
252
+ [itemVariableName]: item,
253
+ [indexVariableName]: index
254
+ };
255
+ // Prepare action configuration with context
256
+ const preparedConfig = this.prepareActionConfig(actionConfig, iterationContext);
257
+ // Execute the action
258
+ const engine = new actions_2.ActionEngineServer();
259
+ const result = await engine.RunAction(preparedConfig);
260
+ // Convert ActionResult to ActionResultSimple
261
+ return {
262
+ Success: result.Success,
263
+ ResultCode: result.Result?.ResultCode || (result.Success ? "SUCCESS" : "FAILED"),
264
+ Message: result.Message,
265
+ Params: result.Params
266
+ };
267
+ }
268
+ /**
269
+ * Prepare action configuration with template replacement
270
+ */
271
+ prepareActionConfig(actionConfig, context) {
272
+ // Deep clone the config
273
+ const preparedConfig = JSON.parse(JSON.stringify(actionConfig));
274
+ // Replace templates in the configuration
275
+ this.replaceTemplates(preparedConfig, context);
276
+ return preparedConfig;
277
+ }
278
+ /**
279
+ * Replace template variables in object recursively
280
+ */
281
+ replaceTemplates(obj, context) {
282
+ if (typeof obj === 'string') {
283
+ // Can't modify string in place, would need parent reference
284
+ return;
285
+ }
286
+ for (const key in obj) {
287
+ if (obj.hasOwnProperty(key)) {
288
+ const value = obj[key];
289
+ if (typeof value === 'string') {
290
+ // Replace template variables
291
+ obj[key] = this.replaceTemplateString(value, context);
292
+ }
293
+ else if (typeof value === 'object' && value !== null) {
294
+ // Recurse into objects and arrays
295
+ this.replaceTemplates(value, context);
296
+ }
297
+ }
298
+ }
299
+ }
300
+ /**
301
+ * Replace template variables in a string
302
+ */
303
+ replaceTemplateString(template, context) {
304
+ // Simple template replacement for {{variable}} and {{object.property}}
305
+ return template.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
306
+ const trimmedPath = path.trim();
307
+ const value = this.getValueByPath(context, trimmedPath);
308
+ return value !== undefined ? String(value) : match;
309
+ });
310
+ }
311
+ /**
312
+ * Get value from object by dot-notation path
313
+ */
314
+ getValueByPath(obj, path) {
315
+ const parts = path.split('.');
316
+ let current = obj;
317
+ for (const part of parts) {
318
+ if (current && typeof current === 'object' && part in current) {
319
+ current = current[part];
320
+ }
321
+ else {
322
+ return undefined;
323
+ }
324
+ }
325
+ return current;
326
+ }
327
+ /**
328
+ * Chunk array into smaller arrays
329
+ */
330
+ chunkArray(array, size) {
331
+ const chunks = [];
332
+ for (let i = 0; i < array.length; i += size) {
333
+ chunks.push(array.slice(i, i + size));
334
+ }
335
+ return chunks;
336
+ }
337
+ /**
338
+ * Get numeric parameter with default
339
+ */
340
+ getNumericParam(params, name, defaultValue) {
341
+ const value = this.getParamValue(params, name);
342
+ if (value === undefined || value === null)
343
+ return defaultValue;
344
+ const num = Number(value);
345
+ return isNaN(num) ? defaultValue : num;
346
+ }
347
+ /**
348
+ * Get boolean parameter with default
349
+ */
350
+ getBooleanParam(params, name, defaultValue) {
351
+ const value = this.getParamValue(params, name);
352
+ if (value === undefined || value === null)
353
+ return defaultValue;
354
+ if (typeof value === 'boolean')
355
+ return value;
356
+ if (typeof value === 'string') {
357
+ return value.toLowerCase() === 'true';
358
+ }
359
+ return defaultValue;
360
+ }
361
+ /**
362
+ * Get parameter value by name (case-insensitive)
363
+ */
364
+ getParamValue(params, name) {
365
+ const param = params.Params.find(p => p.Name.toLowerCase() === name.toLowerCase());
366
+ return param?.Value;
367
+ }
368
+ };
369
+ exports.LoopAction = LoopAction;
370
+ exports.LoopAction = LoopAction = __decorate([
371
+ (0, global_1.RegisterClass)(actions_1.BaseAction, "Loop")
372
+ ], LoopAction);
373
+ /**
374
+ * Loader function to ensure the LoopAction class is included in the bundle
375
+ */
376
+ function LoadLoopAction() {
377
+ // Stub function to prevent tree shaking
378
+ }
379
+ exports.LoadLoopAction = LoadLoopAction;
380
+ //# sourceMappingURL=loop.action.js.map