@marktoflow/core 2.0.2 → 2.0.4
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.
- package/README.md +69 -6
- package/dist/built-in-operations.d.ts +2 -136
- package/dist/built-in-operations.d.ts.map +1 -1
- package/dist/built-in-operations.js +7 -743
- package/dist/built-in-operations.js.map +1 -1
- package/dist/engine/conditions.d.ts +29 -0
- package/dist/engine/conditions.d.ts.map +1 -0
- package/dist/engine/conditions.js +109 -0
- package/dist/engine/conditions.js.map +1 -0
- package/dist/engine/control-flow.d.ts +35 -0
- package/dist/engine/control-flow.d.ts.map +1 -0
- package/dist/engine/control-flow.js +653 -0
- package/dist/engine/control-flow.js.map +1 -0
- package/dist/engine/index.d.ts +12 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +11 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/retry.d.ts +35 -0
- package/dist/engine/retry.d.ts.map +1 -0
- package/dist/engine/retry.js +86 -0
- package/dist/engine/retry.js.map +1 -0
- package/dist/engine/subworkflow.d.ts +31 -0
- package/dist/engine/subworkflow.d.ts.map +1 -0
- package/dist/engine/subworkflow.js +240 -0
- package/dist/engine/subworkflow.js.map +1 -0
- package/dist/engine/types.d.ts +55 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +5 -0
- package/dist/{secrets → engine}/types.js.map +1 -1
- package/dist/engine/variable-resolution.d.ts +29 -0
- package/dist/engine/variable-resolution.d.ts.map +1 -0
- package/dist/engine/variable-resolution.js +130 -0
- package/dist/engine/variable-resolution.js.map +1 -0
- package/dist/engine.d.ts +17 -211
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +84 -1351
- package/dist/engine.js.map +1 -1
- package/dist/file-operations.js +1 -1
- package/dist/file-operations.js.map +1 -1
- package/dist/filters/array.d.ts +9 -0
- package/dist/filters/array.d.ts.map +1 -0
- package/dist/filters/array.js +41 -0
- package/dist/filters/array.js.map +1 -0
- package/dist/filters/date.d.ts +9 -0
- package/dist/filters/date.d.ts.map +1 -0
- package/dist/filters/date.js +51 -0
- package/dist/filters/date.js.map +1 -0
- package/dist/filters/index.d.ts +13 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/index.js +13 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/json.d.ts +6 -0
- package/dist/filters/json.d.ts.map +1 -0
- package/dist/filters/json.js +15 -0
- package/dist/filters/json.js.map +1 -0
- package/dist/filters/logic.d.ts +8 -0
- package/dist/filters/logic.d.ts.map +1 -0
- package/dist/filters/logic.js +28 -0
- package/dist/filters/logic.js.map +1 -0
- package/dist/filters/math.d.ts +13 -0
- package/dist/filters/math.d.ts.map +1 -0
- package/dist/filters/math.js +39 -0
- package/dist/filters/math.js.map +1 -0
- package/dist/filters/object.d.ts +11 -0
- package/dist/filters/object.d.ts.map +1 -0
- package/dist/filters/object.js +64 -0
- package/dist/filters/object.js.map +1 -0
- package/dist/filters/regex.d.ts +7 -0
- package/dist/filters/regex.d.ts.map +1 -0
- package/dist/filters/regex.js +38 -0
- package/dist/filters/regex.js.map +1 -0
- package/dist/filters/string.d.ts +11 -0
- package/dist/filters/string.d.ts.map +1 -0
- package/dist/filters/string.js +35 -0
- package/dist/filters/string.js.map +1 -0
- package/dist/filters/type-checks.d.ts +10 -0
- package/dist/filters/type-checks.d.ts.map +1 -0
- package/dist/filters/type-checks.js +30 -0
- package/dist/filters/type-checks.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/nunjucks-filters.d.ts +2 -261
- package/dist/nunjucks-filters.d.ts.map +1 -1
- package/dist/nunjucks-filters.js +24 -582
- package/dist/nunjucks-filters.js.map +1 -1
- package/dist/operations/compress.d.ts +6 -0
- package/dist/operations/compress.d.ts.map +1 -0
- package/dist/operations/compress.js +36 -0
- package/dist/operations/compress.js.map +1 -0
- package/dist/operations/crypto.d.ts +5 -0
- package/dist/operations/crypto.d.ts.map +1 -0
- package/dist/operations/crypto.js +61 -0
- package/dist/operations/crypto.js.map +1 -0
- package/dist/operations/data-ops.d.ts +10 -0
- package/dist/operations/data-ops.d.ts.map +1 -0
- package/dist/operations/data-ops.js +124 -0
- package/dist/operations/data-ops.js.map +1 -0
- package/dist/operations/datetime.d.ts +5 -0
- package/dist/operations/datetime.d.ts.map +1 -0
- package/dist/operations/datetime.js +86 -0
- package/dist/operations/datetime.js.map +1 -0
- package/dist/operations/extract.d.ts +23 -0
- package/dist/operations/extract.d.ts.map +1 -0
- package/dist/operations/extract.js +31 -0
- package/dist/operations/extract.js.map +1 -0
- package/dist/operations/format.d.ts +14 -0
- package/dist/operations/format.d.ts.map +1 -0
- package/dist/operations/format.js +84 -0
- package/dist/operations/format.js.map +1 -0
- package/dist/operations/index.d.ts +13 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +13 -0
- package/dist/operations/index.js.map +1 -0
- package/dist/operations/parse.d.ts +5 -0
- package/dist/operations/parse.d.ts.map +1 -0
- package/dist/operations/parse.js +59 -0
- package/dist/operations/parse.js.map +1 -0
- package/dist/operations/set.d.ts +21 -0
- package/dist/operations/set.d.ts.map +1 -0
- package/dist/operations/set.js +25 -0
- package/dist/operations/set.js.map +1 -0
- package/dist/operations/transform.d.ts +15 -0
- package/dist/operations/transform.d.ts.map +1 -0
- package/dist/operations/transform.js +110 -0
- package/dist/operations/transform.js.map +1 -0
- package/dist/parallel.d.ts +114 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +325 -0
- package/dist/parallel.js.map +1 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +2 -0
- package/dist/parser.js.map +1 -1
- package/dist/routing.js +2 -2
- package/dist/routing.js.map +1 -1
- package/dist/sdk-registry.d.ts.map +1 -1
- package/dist/sdk-registry.js +9 -3
- package/dist/sdk-registry.js.map +1 -1
- package/dist/utils/duration.d.ts +23 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +41 -0
- package/dist/utils/duration.js.map +1 -0
- package/dist/utils/errors.d.ts +20 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +37 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/workflow-templates.d.ts +80 -0
- package/dist/workflow-templates.d.ts.map +1 -0
- package/dist/workflow-templates.js +248 -0
- package/dist/workflow-templates.js.map +1 -0
- package/package.json +30 -5
- package/dist/secrets/index.d.ts +0 -12
- package/dist/secrets/index.d.ts.map +0 -1
- package/dist/secrets/index.js +0 -11
- package/dist/secrets/index.js.map +0 -1
- package/dist/secrets/providers/aws.d.ts +0 -32
- package/dist/secrets/providers/aws.d.ts.map +0 -1
- package/dist/secrets/providers/aws.js +0 -118
- package/dist/secrets/providers/aws.js.map +0 -1
- package/dist/secrets/providers/azure.d.ts +0 -40
- package/dist/secrets/providers/azure.d.ts.map +0 -1
- package/dist/secrets/providers/azure.js +0 -170
- package/dist/secrets/providers/azure.js.map +0 -1
- package/dist/secrets/providers/env.d.ts +0 -26
- package/dist/secrets/providers/env.d.ts.map +0 -1
- package/dist/secrets/providers/env.js +0 -59
- package/dist/secrets/providers/env.js.map +0 -1
- package/dist/secrets/providers/vault.d.ts +0 -39
- package/dist/secrets/providers/vault.d.ts.map +0 -1
- package/dist/secrets/providers/vault.js +0 -180
- package/dist/secrets/providers/vault.js.map +0 -1
- package/dist/secrets/secret-manager.d.ts +0 -72
- package/dist/secrets/secret-manager.d.ts.map +0 -1
- package/dist/secrets/secret-manager.js +0 -226
- package/dist/secrets/secret-manager.js.map +0 -1
- package/dist/secrets/types.d.ts +0 -105
- package/dist/secrets/types.d.ts.map +0 -1
- package/dist/secrets/types.js +0 -8
|
@@ -1,387 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Built-in Operations for marktoflow
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - core.set: Simple variable assignment
|
|
6
|
-
* - core.transform: Map/filter/reduce transformations
|
|
7
|
-
* - core.extract: Nested path access
|
|
8
|
-
* - core.format: Date/number/string formatting
|
|
9
|
-
* - file.read: Read files with format conversion (docx, pdf, xlsx)
|
|
10
|
-
* - file.write: Write files (text or binary)
|
|
4
|
+
* Thin dispatcher — all implementations live in ./operations/.
|
|
11
5
|
*/
|
|
12
|
-
import { resolveTemplates, resolveVariablePath } from './engine.js';
|
|
13
6
|
import { executeFileOperation, isFileOperation } from './file-operations.js';
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* Set multiple variables at once with expression resolution.
|
|
19
|
-
*
|
|
20
|
-
* Example:
|
|
21
|
-
* ```yaml
|
|
22
|
-
* action: core.set
|
|
23
|
-
* inputs:
|
|
24
|
-
* owner: "{{ inputs.repo =~ /^([^\/]+)\// }}"
|
|
25
|
-
* repo_name: "{{ inputs.repo =~ /\/(.+)$/ }}"
|
|
26
|
-
* timestamp: "{{ now() }}"
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export function executeSet(inputs, context) {
|
|
30
|
-
const result = {};
|
|
31
|
-
for (const [key, value] of Object.entries(inputs)) {
|
|
32
|
-
const resolved = resolveTemplates(value, context);
|
|
33
|
-
result[key] = resolved;
|
|
34
|
-
}
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
37
|
-
// ============================================================================
|
|
38
|
-
// core.transform - Array Transformations
|
|
39
|
-
// ============================================================================
|
|
40
|
-
/**
|
|
41
|
-
* Transform arrays using common operations like map, filter, reduce.
|
|
42
|
-
*
|
|
43
|
-
* Examples:
|
|
44
|
-
*
|
|
45
|
-
* Map:
|
|
46
|
-
* ```yaml
|
|
47
|
-
* action: core.transform
|
|
48
|
-
* inputs:
|
|
49
|
-
* input: "{{ oncall_response.data.oncalls }}"
|
|
50
|
-
* operation: map
|
|
51
|
-
* expression: "@{{ item.user.name }}"
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* Filter:
|
|
55
|
-
* ```yaml
|
|
56
|
-
* action: core.transform
|
|
57
|
-
* inputs:
|
|
58
|
-
* input: "{{ issues }}"
|
|
59
|
-
* operation: filter
|
|
60
|
-
* condition: "item.priority == 'high'"
|
|
61
|
-
* ```
|
|
62
|
-
*
|
|
63
|
-
* Reduce:
|
|
64
|
-
* ```yaml
|
|
65
|
-
* action: core.transform
|
|
66
|
-
* inputs:
|
|
67
|
-
* input: "{{ numbers }}"
|
|
68
|
-
* operation: reduce
|
|
69
|
-
* expression: "{{ accumulator + item }}"
|
|
70
|
-
* initialValue: 0
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
export function executeTransform(rawInputs, resolvedInputs, context) {
|
|
74
|
-
// Use resolved input array
|
|
75
|
-
const input = resolvedInputs.input;
|
|
76
|
-
if (!Array.isArray(input)) {
|
|
77
|
-
throw new Error('Transform input must be an array');
|
|
78
|
-
}
|
|
79
|
-
// Use raw (unresolved) expression and condition to preserve templates
|
|
80
|
-
const operation = rawInputs.operation;
|
|
81
|
-
switch (operation) {
|
|
82
|
-
case 'map':
|
|
83
|
-
return transformMap(input, rawInputs.expression || '{{ item }}', context);
|
|
84
|
-
case 'filter':
|
|
85
|
-
return transformFilter(input, rawInputs.condition || 'item', context);
|
|
86
|
-
case 'reduce':
|
|
87
|
-
return transformReduce(input, rawInputs.expression || '{{ accumulator }}', resolvedInputs.initialValue, // Resolve initialValue upfront
|
|
88
|
-
context);
|
|
89
|
-
case 'find':
|
|
90
|
-
return transformFind(input, rawInputs.condition || 'item', context);
|
|
91
|
-
case 'group_by':
|
|
92
|
-
if (!rawInputs.key) {
|
|
93
|
-
throw new Error('group_by operation requires "key" parameter');
|
|
94
|
-
}
|
|
95
|
-
return transformGroupBy(input, rawInputs.key, context);
|
|
96
|
-
case 'unique':
|
|
97
|
-
return transformUnique(input, rawInputs.key, context);
|
|
98
|
-
case 'sort':
|
|
99
|
-
return transformSort(input, rawInputs.key, resolvedInputs.reverse || false, context);
|
|
100
|
-
default:
|
|
101
|
-
throw new Error(`Unknown transform operation: ${operation}`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Map transformation - transform each item in an array
|
|
106
|
-
*/
|
|
107
|
-
function transformMap(items, expression, context) {
|
|
108
|
-
return items.map((item) => {
|
|
109
|
-
const itemContext = { ...context, variables: { ...context.variables, item } };
|
|
110
|
-
return resolveTemplates(expression, itemContext);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Filter transformation - keep items that match a condition
|
|
115
|
-
*/
|
|
116
|
-
function transformFilter(items, condition, context) {
|
|
117
|
-
return items.filter((item) => {
|
|
118
|
-
const itemContext = { ...context, variables: { ...context.variables, item } };
|
|
119
|
-
const resolved = resolveTemplates(condition, itemContext);
|
|
120
|
-
return Boolean(resolved);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Reduce transformation - aggregate items to a single value
|
|
125
|
-
*/
|
|
126
|
-
function transformReduce(items, expression, initialValue, context) {
|
|
127
|
-
let accumulator = initialValue !== undefined ? initialValue : null;
|
|
128
|
-
for (const item of items) {
|
|
129
|
-
const reduceContext = {
|
|
130
|
-
...context,
|
|
131
|
-
variables: { ...context.variables, item, accumulator },
|
|
132
|
-
};
|
|
133
|
-
accumulator = resolveTemplates(expression, reduceContext);
|
|
134
|
-
}
|
|
135
|
-
return accumulator;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Find transformation - find first item that matches condition
|
|
139
|
-
*/
|
|
140
|
-
function transformFind(items, condition, context) {
|
|
141
|
-
for (const item of items) {
|
|
142
|
-
const itemContext = { ...context, variables: { ...context.variables, item } };
|
|
143
|
-
const resolved = resolveTemplates(condition, itemContext);
|
|
144
|
-
if (Boolean(resolved)) {
|
|
145
|
-
return item;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return undefined;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Group by transformation - group items by a key
|
|
152
|
-
*/
|
|
153
|
-
function transformGroupBy(items, key, context) {
|
|
154
|
-
const groups = {};
|
|
155
|
-
for (const item of items) {
|
|
156
|
-
const itemContext = { ...context, variables: { ...context.variables, item } };
|
|
157
|
-
const groupKey = String(resolveVariablePath(key, itemContext));
|
|
158
|
-
if (!groups[groupKey]) {
|
|
159
|
-
groups[groupKey] = [];
|
|
160
|
-
}
|
|
161
|
-
groups[groupKey].push(item);
|
|
162
|
-
}
|
|
163
|
-
return groups;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Unique transformation - remove duplicates
|
|
167
|
-
*/
|
|
168
|
-
function transformUnique(items, key, context) {
|
|
169
|
-
if (!key) {
|
|
170
|
-
// Simple unique for primitive values
|
|
171
|
-
return Array.from(new Set(items));
|
|
172
|
-
}
|
|
173
|
-
// Unique based on key
|
|
174
|
-
const seen = new Set();
|
|
175
|
-
const result = [];
|
|
176
|
-
for (const item of items) {
|
|
177
|
-
const itemContext = { ...context, variables: { ...context.variables, item } };
|
|
178
|
-
const keyValue = String(resolveVariablePath(key, itemContext));
|
|
179
|
-
if (!seen.has(keyValue)) {
|
|
180
|
-
seen.add(keyValue);
|
|
181
|
-
result.push(item);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return result;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Sort transformation - sort items by key or value
|
|
188
|
-
*/
|
|
189
|
-
function transformSort(items, key, reverse, context) {
|
|
190
|
-
const sorted = [...items];
|
|
191
|
-
sorted.sort((a, b) => {
|
|
192
|
-
let aVal = a;
|
|
193
|
-
let bVal = b;
|
|
194
|
-
if (key) {
|
|
195
|
-
const aContext = { ...context, variables: { ...context.variables, item: a } };
|
|
196
|
-
const bContext = { ...context, variables: { ...context.variables, item: b } };
|
|
197
|
-
aVal = resolveVariablePath(key, aContext);
|
|
198
|
-
bVal = resolveVariablePath(key, bContext);
|
|
199
|
-
}
|
|
200
|
-
// Handle different types
|
|
201
|
-
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
202
|
-
return aVal - bVal;
|
|
203
|
-
}
|
|
204
|
-
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
205
|
-
return aVal.localeCompare(bVal);
|
|
206
|
-
}
|
|
207
|
-
// Fall back to string comparison
|
|
208
|
-
return String(aVal).localeCompare(String(bVal));
|
|
209
|
-
});
|
|
210
|
-
return reverse ? sorted.reverse() : sorted;
|
|
211
|
-
}
|
|
212
|
-
// ============================================================================
|
|
213
|
-
// core.extract - Nested Path Access
|
|
214
|
-
// ============================================================================
|
|
215
|
-
/**
|
|
216
|
-
* Extract values from nested objects safely.
|
|
217
|
-
*
|
|
218
|
-
* Example:
|
|
219
|
-
* ```yaml
|
|
220
|
-
* action: core.extract
|
|
221
|
-
* inputs:
|
|
222
|
-
* input: "{{ api_response }}"
|
|
223
|
-
* path: "data.users[0].email"
|
|
224
|
-
* default: "unknown@example.com"
|
|
225
|
-
* ```
|
|
226
|
-
*/
|
|
227
|
-
export function executeExtract(inputs, context) {
|
|
228
|
-
const input = resolveTemplates(inputs.input, context);
|
|
229
|
-
const path = inputs.path;
|
|
230
|
-
const defaultValue = inputs.default;
|
|
231
|
-
// Create a temporary context with the input as a variable
|
|
232
|
-
const tempContext = {
|
|
233
|
-
...context,
|
|
234
|
-
variables: { ...context.variables, __extract_input: input },
|
|
235
|
-
};
|
|
236
|
-
const result = resolveVariablePath(`__extract_input.${path}`, tempContext);
|
|
237
|
-
if (result === undefined) {
|
|
238
|
-
return defaultValue !== undefined ? defaultValue : null;
|
|
239
|
-
}
|
|
240
|
-
return result;
|
|
241
|
-
}
|
|
242
|
-
// ============================================================================
|
|
243
|
-
// core.format - Value Formatting
|
|
244
|
-
// ============================================================================
|
|
245
|
-
/**
|
|
246
|
-
* Format values for display (dates, numbers, strings, currency).
|
|
247
|
-
*
|
|
248
|
-
* Examples:
|
|
249
|
-
*
|
|
250
|
-
* Date:
|
|
251
|
-
* ```yaml
|
|
252
|
-
* action: core.format
|
|
253
|
-
* inputs:
|
|
254
|
-
* value: "{{ now() }}"
|
|
255
|
-
* type: date
|
|
256
|
-
* format: "YYYY-MM-DD HH:mm:ss"
|
|
257
|
-
* ```
|
|
258
|
-
*
|
|
259
|
-
* Number:
|
|
260
|
-
* ```yaml
|
|
261
|
-
* action: core.format
|
|
262
|
-
* inputs:
|
|
263
|
-
* value: 1234.56
|
|
264
|
-
* type: number
|
|
265
|
-
* precision: 2
|
|
266
|
-
* ```
|
|
267
|
-
*
|
|
268
|
-
* Currency:
|
|
269
|
-
* ```yaml
|
|
270
|
-
* action: core.format
|
|
271
|
-
* inputs:
|
|
272
|
-
* value: 1234.56
|
|
273
|
-
* type: currency
|
|
274
|
-
* currency: USD
|
|
275
|
-
* locale: en-US
|
|
276
|
-
* ```
|
|
277
|
-
*/
|
|
278
|
-
export function executeFormat(inputs, context) {
|
|
279
|
-
const value = resolveTemplates(inputs.value, context);
|
|
280
|
-
switch (inputs.type) {
|
|
281
|
-
case 'date':
|
|
282
|
-
return formatDate(value, inputs.format);
|
|
283
|
-
case 'number':
|
|
284
|
-
return formatNumber(value, inputs.precision, inputs.locale);
|
|
285
|
-
case 'currency':
|
|
286
|
-
return formatCurrency(value, inputs.currency || 'USD', inputs.locale);
|
|
287
|
-
case 'string':
|
|
288
|
-
return formatString(value, inputs.format);
|
|
289
|
-
case 'json':
|
|
290
|
-
return JSON.stringify(value, null, 2);
|
|
291
|
-
default:
|
|
292
|
-
throw new Error(`Unknown format type: ${inputs.type}`);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Format a date value
|
|
297
|
-
* Supports simple format tokens: YYYY, MM, DD, HH, mm, ss
|
|
298
|
-
*/
|
|
299
|
-
function formatDate(value, format) {
|
|
300
|
-
let date;
|
|
301
|
-
if (value instanceof Date) {
|
|
302
|
-
date = value;
|
|
303
|
-
}
|
|
304
|
-
else if (typeof value === 'string' || typeof value === 'number') {
|
|
305
|
-
date = new Date(value);
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
date = new Date();
|
|
309
|
-
}
|
|
310
|
-
if (isNaN(date.getTime())) {
|
|
311
|
-
throw new Error('Invalid date value');
|
|
312
|
-
}
|
|
313
|
-
if (!format) {
|
|
314
|
-
return date.toISOString();
|
|
315
|
-
}
|
|
316
|
-
// Simple date formatting (basic implementation)
|
|
317
|
-
let formatted = format;
|
|
318
|
-
formatted = formatted.replace('YYYY', date.getFullYear().toString());
|
|
319
|
-
formatted = formatted.replace('MM', String(date.getMonth() + 1).padStart(2, '0'));
|
|
320
|
-
formatted = formatted.replace('DD', String(date.getDate()).padStart(2, '0'));
|
|
321
|
-
formatted = formatted.replace('HH', String(date.getHours()).padStart(2, '0'));
|
|
322
|
-
formatted = formatted.replace('mm', String(date.getMinutes()).padStart(2, '0'));
|
|
323
|
-
formatted = formatted.replace('ss', String(date.getSeconds()).padStart(2, '0'));
|
|
324
|
-
return formatted;
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Format a number value
|
|
328
|
-
*/
|
|
329
|
-
function formatNumber(value, precision, locale) {
|
|
330
|
-
const num = Number(value);
|
|
331
|
-
if (isNaN(num)) {
|
|
332
|
-
throw new Error('Invalid number value');
|
|
333
|
-
}
|
|
334
|
-
if (precision !== undefined) {
|
|
335
|
-
return num.toFixed(precision);
|
|
336
|
-
}
|
|
337
|
-
if (locale) {
|
|
338
|
-
return num.toLocaleString(locale);
|
|
339
|
-
}
|
|
340
|
-
return num.toString();
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Format a currency value
|
|
344
|
-
*/
|
|
345
|
-
function formatCurrency(value, currency, locale) {
|
|
346
|
-
const num = Number(value);
|
|
347
|
-
if (isNaN(num)) {
|
|
348
|
-
throw new Error('Invalid currency value');
|
|
349
|
-
}
|
|
350
|
-
return num.toLocaleString(locale || 'en-US', {
|
|
351
|
-
style: 'currency',
|
|
352
|
-
currency,
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Format a string value
|
|
357
|
-
* Supports: upper, lower, title, capitalize, trim
|
|
358
|
-
*/
|
|
359
|
-
function formatString(value, format) {
|
|
360
|
-
let str = String(value);
|
|
361
|
-
if (!format) {
|
|
362
|
-
return str;
|
|
363
|
-
}
|
|
364
|
-
switch (format.toLowerCase()) {
|
|
365
|
-
case 'upper':
|
|
366
|
-
case 'uppercase':
|
|
367
|
-
return str.toUpperCase();
|
|
368
|
-
case 'lower':
|
|
369
|
-
case 'lowercase':
|
|
370
|
-
return str.toLowerCase();
|
|
371
|
-
case 'title':
|
|
372
|
-
case 'titlecase':
|
|
373
|
-
return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase());
|
|
374
|
-
case 'capitalize':
|
|
375
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
376
|
-
case 'trim':
|
|
377
|
-
return str.trim();
|
|
378
|
-
default:
|
|
379
|
-
return str;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
// ============================================================================
|
|
383
|
-
// Helper Functions
|
|
384
|
-
// ============================================================================
|
|
7
|
+
import { isParallelOperation } from './parallel.js';
|
|
8
|
+
// Re-export all operations and types for backward compatibility
|
|
9
|
+
export { executeSet, executeTransform, executeExtract, executeFormat, executeAggregate, executeCompare, executeRenameKeys, executeLimit, executeSortOperation, executeCrypto, executeDatetime, executeParse, executeCompress, executeDecompress, } from './operations/index.js';
|
|
10
|
+
import { executeSet, executeTransform, executeExtract, executeFormat, executeAggregate, executeCompare, executeRenameKeys, executeLimit, executeSortOperation, executeCrypto, executeDatetime, executeParse, executeCompress, executeDecompress, } from './operations/index.js';
|
|
385
11
|
/**
|
|
386
12
|
* Execute a built-in operation based on action name
|
|
387
13
|
*/
|
|
@@ -390,7 +16,6 @@ export function executeBuiltInOperation(action, rawInputs, resolvedInputs, conte
|
|
|
390
16
|
case 'core.set':
|
|
391
17
|
return executeSet(resolvedInputs, context);
|
|
392
18
|
case 'core.transform':
|
|
393
|
-
// For transform operations, use raw inputs to preserve template expressions
|
|
394
19
|
return executeTransform(rawInputs, resolvedInputs, context);
|
|
395
20
|
case 'core.extract':
|
|
396
21
|
return executeExtract(resolvedInputs, context);
|
|
@@ -417,11 +42,10 @@ export function executeBuiltInOperation(action, rawInputs, resolvedInputs, conte
|
|
|
417
42
|
case 'core.decompress':
|
|
418
43
|
return executeDecompress(resolvedInputs);
|
|
419
44
|
default:
|
|
420
|
-
// Check if it's a file operation
|
|
421
45
|
if (isFileOperation(action)) {
|
|
422
46
|
return executeFileOperation(action, resolvedInputs, context);
|
|
423
47
|
}
|
|
424
|
-
return null;
|
|
48
|
+
return null;
|
|
425
49
|
}
|
|
426
50
|
}
|
|
427
51
|
/**
|
|
@@ -434,366 +58,6 @@ export function isBuiltInOperation(action) {
|
|
|
434
58
|
'core.sort', 'core.crypto', 'core.datetime', 'core.parse',
|
|
435
59
|
'core.compress', 'core.decompress',
|
|
436
60
|
];
|
|
437
|
-
return builtInActions.includes(action) || isFileOperation(action);
|
|
438
|
-
}
|
|
439
|
-
// ============================================================================
|
|
440
|
-
// core.aggregate - Common aggregation presets
|
|
441
|
-
// ============================================================================
|
|
442
|
-
export function executeAggregate(inputs, _context) {
|
|
443
|
-
const items = inputs.input;
|
|
444
|
-
const operation = inputs.operation;
|
|
445
|
-
const field = inputs.field;
|
|
446
|
-
if (!Array.isArray(items))
|
|
447
|
-
throw new Error('core.aggregate: input must be an array');
|
|
448
|
-
const values = field
|
|
449
|
-
? items.map((item) => {
|
|
450
|
-
if (item && typeof item === 'object')
|
|
451
|
-
return item[field];
|
|
452
|
-
return item;
|
|
453
|
-
})
|
|
454
|
-
: items;
|
|
455
|
-
const numValues = values.map(Number).filter((n) => !isNaN(n));
|
|
456
|
-
switch (operation) {
|
|
457
|
-
case 'sum':
|
|
458
|
-
return numValues.reduce((a, b) => a + b, 0);
|
|
459
|
-
case 'avg':
|
|
460
|
-
case 'average':
|
|
461
|
-
return numValues.length > 0 ? numValues.reduce((a, b) => a + b, 0) / numValues.length : 0;
|
|
462
|
-
case 'count':
|
|
463
|
-
return items.length;
|
|
464
|
-
case 'min':
|
|
465
|
-
return numValues.length > 0 ? Math.min(...numValues) : null;
|
|
466
|
-
case 'max':
|
|
467
|
-
return numValues.length > 0 ? Math.max(...numValues) : null;
|
|
468
|
-
case 'first':
|
|
469
|
-
return items[0] ?? null;
|
|
470
|
-
case 'last':
|
|
471
|
-
return items[items.length - 1] ?? null;
|
|
472
|
-
case 'concat':
|
|
473
|
-
return values.join(inputs.separator ?? ', ');
|
|
474
|
-
case 'unique_count':
|
|
475
|
-
return new Set(values).size;
|
|
476
|
-
default:
|
|
477
|
-
throw new Error(`core.aggregate: unknown operation "${operation}"`);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
// ============================================================================
|
|
481
|
-
// core.compare - Compare two datasets
|
|
482
|
-
// ============================================================================
|
|
483
|
-
export function executeCompare(inputs, _context) {
|
|
484
|
-
const source1 = inputs.source1;
|
|
485
|
-
const source2 = inputs.source2;
|
|
486
|
-
const field = inputs.field;
|
|
487
|
-
if (!Array.isArray(source1) || !Array.isArray(source2)) {
|
|
488
|
-
throw new Error('core.compare: source1 and source2 must be arrays');
|
|
489
|
-
}
|
|
490
|
-
if (!field)
|
|
491
|
-
throw new Error('core.compare: field is required');
|
|
492
|
-
const getVal = (item) => item && typeof item === 'object' ? item[field] : item;
|
|
493
|
-
const set1 = new Set(source1.map(getVal));
|
|
494
|
-
const set2 = new Set(source2.map(getVal));
|
|
495
|
-
return {
|
|
496
|
-
added: source2.filter((item) => !set1.has(getVal(item))),
|
|
497
|
-
removed: source1.filter((item) => !set2.has(getVal(item))),
|
|
498
|
-
unchanged: source1.filter((item) => set2.has(getVal(item))),
|
|
499
|
-
total_source1: source1.length,
|
|
500
|
-
total_source2: source2.length,
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
// ============================================================================
|
|
504
|
-
// core.rename_keys - Rename object keys
|
|
505
|
-
// ============================================================================
|
|
506
|
-
export function executeRenameKeys(inputs) {
|
|
507
|
-
const input = inputs.input;
|
|
508
|
-
const mapping = inputs.mapping;
|
|
509
|
-
if (!mapping || typeof mapping !== 'object') {
|
|
510
|
-
throw new Error('core.rename_keys: mapping is required');
|
|
511
|
-
}
|
|
512
|
-
const rename = (obj) => {
|
|
513
|
-
const result = {};
|
|
514
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
515
|
-
const newKey = mapping[key] ?? key;
|
|
516
|
-
result[newKey] = value;
|
|
517
|
-
}
|
|
518
|
-
return result;
|
|
519
|
-
};
|
|
520
|
-
if (Array.isArray(input)) {
|
|
521
|
-
return input.map((item) => item && typeof item === 'object' ? rename(item) : item);
|
|
522
|
-
}
|
|
523
|
-
if (input && typeof input === 'object') {
|
|
524
|
-
return rename(input);
|
|
525
|
-
}
|
|
526
|
-
return input;
|
|
527
|
-
}
|
|
528
|
-
// ============================================================================
|
|
529
|
-
// core.limit - Limit array items
|
|
530
|
-
// ============================================================================
|
|
531
|
-
export function executeLimit(inputs) {
|
|
532
|
-
const items = inputs.input;
|
|
533
|
-
const count = inputs.count;
|
|
534
|
-
const offset = inputs.offset ?? 0;
|
|
535
|
-
if (!Array.isArray(items))
|
|
536
|
-
throw new Error('core.limit: input must be an array');
|
|
537
|
-
if (typeof count !== 'number')
|
|
538
|
-
throw new Error('core.limit: count is required');
|
|
539
|
-
return items.slice(offset, offset + count);
|
|
540
|
-
}
|
|
541
|
-
// ============================================================================
|
|
542
|
-
// core.sort - Sort array
|
|
543
|
-
// ============================================================================
|
|
544
|
-
export function executeSortOperation(inputs) {
|
|
545
|
-
const items = inputs.input;
|
|
546
|
-
const field = inputs.field;
|
|
547
|
-
const direction = inputs.direction ?? 'asc';
|
|
548
|
-
if (!Array.isArray(items))
|
|
549
|
-
throw new Error('core.sort: input must be an array');
|
|
550
|
-
const sorted = [...items].sort((a, b) => {
|
|
551
|
-
const va = field && a && typeof a === 'object' ? a[field] : a;
|
|
552
|
-
const vb = field && b && typeof b === 'object' ? b[field] : b;
|
|
553
|
-
if (typeof va === 'number' && typeof vb === 'number')
|
|
554
|
-
return va - vb;
|
|
555
|
-
return String(va ?? '').localeCompare(String(vb ?? ''));
|
|
556
|
-
});
|
|
557
|
-
return direction === 'desc' ? sorted.reverse() : sorted;
|
|
558
|
-
}
|
|
559
|
-
// ============================================================================
|
|
560
|
-
// core.crypto - Cryptographic operations
|
|
561
|
-
// ============================================================================
|
|
562
|
-
export function executeCrypto(inputs) {
|
|
563
|
-
const { createHash, createHmac, randomBytes, createCipheriv, createDecipheriv } = require('node:crypto');
|
|
564
|
-
const operation = inputs.operation;
|
|
565
|
-
const data = inputs.data;
|
|
566
|
-
switch (operation) {
|
|
567
|
-
case 'hash': {
|
|
568
|
-
const algorithm = inputs.algorithm ?? 'sha256';
|
|
569
|
-
const encoding = inputs.encoding ?? 'hex';
|
|
570
|
-
return createHash(algorithm).update(data).digest(encoding);
|
|
571
|
-
}
|
|
572
|
-
case 'hmac': {
|
|
573
|
-
const algorithm = inputs.algorithm ?? 'sha256';
|
|
574
|
-
const key = inputs.key;
|
|
575
|
-
const encoding = inputs.encoding ?? 'hex';
|
|
576
|
-
if (!key)
|
|
577
|
-
throw new Error('core.crypto: key required for hmac');
|
|
578
|
-
return createHmac(algorithm, key).update(data).digest(encoding);
|
|
579
|
-
}
|
|
580
|
-
case 'random': {
|
|
581
|
-
const size = inputs.size ?? 32;
|
|
582
|
-
const encoding = inputs.encoding ?? 'hex';
|
|
583
|
-
return randomBytes(size).toString(encoding);
|
|
584
|
-
}
|
|
585
|
-
case 'encrypt': {
|
|
586
|
-
const key = inputs.key;
|
|
587
|
-
const algorithm = inputs.algorithm ?? 'aes-256-gcm';
|
|
588
|
-
if (!key)
|
|
589
|
-
throw new Error('core.crypto: key required for encrypt');
|
|
590
|
-
const keyBuf = Buffer.from(key, 'hex');
|
|
591
|
-
const iv = randomBytes(16);
|
|
592
|
-
const cipher = createCipheriv(algorithm, keyBuf, iv);
|
|
593
|
-
let encrypted = cipher.update(data, 'utf8', 'hex');
|
|
594
|
-
encrypted += cipher.final('hex');
|
|
595
|
-
const authTag = algorithm.includes('gcm') ? cipher.getAuthTag().toString('hex') : '';
|
|
596
|
-
return { encrypted, iv: iv.toString('hex'), authTag };
|
|
597
|
-
}
|
|
598
|
-
case 'decrypt': {
|
|
599
|
-
const key = inputs.key;
|
|
600
|
-
const algorithm = inputs.algorithm ?? 'aes-256-gcm';
|
|
601
|
-
const encrypted = inputs.encrypted;
|
|
602
|
-
const iv = inputs.iv;
|
|
603
|
-
const authTag = inputs.authTag;
|
|
604
|
-
if (!key || !encrypted || !iv)
|
|
605
|
-
throw new Error('core.crypto: key, encrypted, iv required for decrypt');
|
|
606
|
-
const keyBuf = Buffer.from(key, 'hex');
|
|
607
|
-
const decipher = createDecipheriv(algorithm, keyBuf, Buffer.from(iv, 'hex'));
|
|
608
|
-
if (algorithm.includes('gcm') && authTag) {
|
|
609
|
-
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
|
|
610
|
-
}
|
|
611
|
-
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
612
|
-
decrypted += decipher.final('utf8');
|
|
613
|
-
return decrypted;
|
|
614
|
-
}
|
|
615
|
-
default:
|
|
616
|
-
throw new Error(`core.crypto: unknown operation "${operation}"`);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
// ============================================================================
|
|
620
|
-
// core.datetime - Date/time operations
|
|
621
|
-
// ============================================================================
|
|
622
|
-
export function executeDatetime(inputs) {
|
|
623
|
-
const operation = inputs.operation;
|
|
624
|
-
const date = inputs.date ? new Date(inputs.date) : new Date();
|
|
625
|
-
switch (operation) {
|
|
626
|
-
case 'now':
|
|
627
|
-
return new Date().toISOString();
|
|
628
|
-
case 'parse':
|
|
629
|
-
return date.toISOString();
|
|
630
|
-
case 'format': {
|
|
631
|
-
const fmt = inputs.format ?? 'iso';
|
|
632
|
-
if (fmt === 'iso')
|
|
633
|
-
return date.toISOString();
|
|
634
|
-
if (fmt === 'date')
|
|
635
|
-
return date.toISOString().split('T')[0];
|
|
636
|
-
if (fmt === 'time')
|
|
637
|
-
return date.toISOString().split('T')[1]?.replace('Z', '');
|
|
638
|
-
if (fmt === 'unix')
|
|
639
|
-
return Math.floor(date.getTime() / 1000);
|
|
640
|
-
if (fmt === 'unix_ms')
|
|
641
|
-
return date.getTime();
|
|
642
|
-
return date.toISOString();
|
|
643
|
-
}
|
|
644
|
-
case 'add': {
|
|
645
|
-
const amount = inputs.amount;
|
|
646
|
-
const unit = inputs.unit ?? 'days';
|
|
647
|
-
const ms = { ms: 1, seconds: 1000, minutes: 60000, hours: 3600000, days: 86400000, weeks: 604800000 };
|
|
648
|
-
const mult = ms[unit] ?? ms.days;
|
|
649
|
-
return new Date(date.getTime() + amount * mult).toISOString();
|
|
650
|
-
}
|
|
651
|
-
case 'subtract': {
|
|
652
|
-
const amount = inputs.amount;
|
|
653
|
-
const unit = inputs.unit ?? 'days';
|
|
654
|
-
const ms = { ms: 1, seconds: 1000, minutes: 60000, hours: 3600000, days: 86400000, weeks: 604800000 };
|
|
655
|
-
const mult = ms[unit] ?? ms.days;
|
|
656
|
-
return new Date(date.getTime() - amount * mult).toISOString();
|
|
657
|
-
}
|
|
658
|
-
case 'diff': {
|
|
659
|
-
const date2 = new Date(inputs.date2);
|
|
660
|
-
const unit = inputs.unit ?? 'days';
|
|
661
|
-
const diffMs = date.getTime() - date2.getTime();
|
|
662
|
-
const divisors = { ms: 1, seconds: 1000, minutes: 60000, hours: 3600000, days: 86400000 };
|
|
663
|
-
return diffMs / (divisors[unit] ?? divisors.days);
|
|
664
|
-
}
|
|
665
|
-
case 'start_of': {
|
|
666
|
-
const unit = inputs.unit ?? 'day';
|
|
667
|
-
const d = new Date(date);
|
|
668
|
-
if (unit === 'day') {
|
|
669
|
-
d.setHours(0, 0, 0, 0);
|
|
670
|
-
}
|
|
671
|
-
else if (unit === 'month') {
|
|
672
|
-
d.setDate(1);
|
|
673
|
-
d.setHours(0, 0, 0, 0);
|
|
674
|
-
}
|
|
675
|
-
else if (unit === 'year') {
|
|
676
|
-
d.setMonth(0, 1);
|
|
677
|
-
d.setHours(0, 0, 0, 0);
|
|
678
|
-
}
|
|
679
|
-
else if (unit === 'hour') {
|
|
680
|
-
d.setMinutes(0, 0, 0);
|
|
681
|
-
}
|
|
682
|
-
return d.toISOString();
|
|
683
|
-
}
|
|
684
|
-
case 'end_of': {
|
|
685
|
-
const unit = inputs.unit ?? 'day';
|
|
686
|
-
const d = new Date(date);
|
|
687
|
-
if (unit === 'day') {
|
|
688
|
-
d.setHours(23, 59, 59, 999);
|
|
689
|
-
}
|
|
690
|
-
else if (unit === 'month') {
|
|
691
|
-
d.setMonth(d.getMonth() + 1, 0);
|
|
692
|
-
d.setHours(23, 59, 59, 999);
|
|
693
|
-
}
|
|
694
|
-
else if (unit === 'year') {
|
|
695
|
-
d.setMonth(11, 31);
|
|
696
|
-
d.setHours(23, 59, 59, 999);
|
|
697
|
-
}
|
|
698
|
-
return d.toISOString();
|
|
699
|
-
}
|
|
700
|
-
default:
|
|
701
|
-
throw new Error(`core.datetime: unknown operation "${operation}"`);
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
// ============================================================================
|
|
705
|
-
// core.parse - Parse structured data formats
|
|
706
|
-
// ============================================================================
|
|
707
|
-
export function executeParse(inputs) {
|
|
708
|
-
const data = inputs.data;
|
|
709
|
-
const format = inputs.format;
|
|
710
|
-
if (!data || typeof data !== 'string')
|
|
711
|
-
throw new Error('core.parse: data must be a string');
|
|
712
|
-
if (!format)
|
|
713
|
-
throw new Error('core.parse: format is required');
|
|
714
|
-
switch (format) {
|
|
715
|
-
case 'json':
|
|
716
|
-
return JSON.parse(data);
|
|
717
|
-
case 'csv': {
|
|
718
|
-
const delimiter = inputs.delimiter ?? ',';
|
|
719
|
-
const hasHeader = inputs.header ?? true;
|
|
720
|
-
const lines = data.split('\n').filter((l) => l.trim());
|
|
721
|
-
if (lines.length === 0)
|
|
722
|
-
return [];
|
|
723
|
-
if (hasHeader) {
|
|
724
|
-
const headers = lines[0].split(delimiter).map((h) => h.trim());
|
|
725
|
-
return lines.slice(1).map((line) => {
|
|
726
|
-
const values = line.split(delimiter);
|
|
727
|
-
const obj = {};
|
|
728
|
-
headers.forEach((h, i) => { obj[h] = (values[i] ?? '').trim(); });
|
|
729
|
-
return obj;
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
return lines.map((line) => line.split(delimiter).map((v) => v.trim()));
|
|
733
|
-
}
|
|
734
|
-
case 'xml': {
|
|
735
|
-
// Simple XML to object parser (handles basic cases)
|
|
736
|
-
const result = {};
|
|
737
|
-
const tagRegex = /<(\w+)(?:\s[^>]*)?>([^<]*)<\/\1>/g;
|
|
738
|
-
let match;
|
|
739
|
-
while ((match = tagRegex.exec(data)) !== null) {
|
|
740
|
-
result[match[1]] = match[2].trim();
|
|
741
|
-
}
|
|
742
|
-
return result;
|
|
743
|
-
}
|
|
744
|
-
case 'yaml': {
|
|
745
|
-
// Use the yaml package if available, otherwise basic parsing
|
|
746
|
-
try {
|
|
747
|
-
const yaml = require('yaml');
|
|
748
|
-
return yaml.parse(data);
|
|
749
|
-
}
|
|
750
|
-
catch {
|
|
751
|
-
throw new Error('core.parse: yaml format requires the "yaml" package');
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
case 'url_params': {
|
|
755
|
-
const params = new URLSearchParams(data);
|
|
756
|
-
const result = {};
|
|
757
|
-
params.forEach((value, key) => { result[key] = value; });
|
|
758
|
-
return result;
|
|
759
|
-
}
|
|
760
|
-
default:
|
|
761
|
-
throw new Error(`core.parse: unknown format "${format}"`);
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
// ============================================================================
|
|
765
|
-
// core.compress / core.decompress - Compression operations
|
|
766
|
-
// ============================================================================
|
|
767
|
-
export function executeCompress(inputs) {
|
|
768
|
-
const { gzipSync, deflateSync } = require('node:zlib');
|
|
769
|
-
const data = inputs.data;
|
|
770
|
-
const algorithm = inputs.algorithm ?? 'gzip';
|
|
771
|
-
if (!data)
|
|
772
|
-
throw new Error('core.compress: data is required');
|
|
773
|
-
const buf = Buffer.from(data, 'utf8');
|
|
774
|
-
switch (algorithm) {
|
|
775
|
-
case 'gzip':
|
|
776
|
-
return gzipSync(buf).toString('base64');
|
|
777
|
-
case 'deflate':
|
|
778
|
-
return deflateSync(buf).toString('base64');
|
|
779
|
-
default:
|
|
780
|
-
throw new Error(`core.compress: unknown algorithm "${algorithm}"`);
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
export function executeDecompress(inputs) {
|
|
784
|
-
const { gunzipSync, inflateSync } = require('node:zlib');
|
|
785
|
-
const data = inputs.data;
|
|
786
|
-
const algorithm = inputs.algorithm ?? 'gzip';
|
|
787
|
-
if (!data)
|
|
788
|
-
throw new Error('core.decompress: data is required');
|
|
789
|
-
const buf = Buffer.from(data, 'base64');
|
|
790
|
-
switch (algorithm) {
|
|
791
|
-
case 'gzip':
|
|
792
|
-
return gunzipSync(buf).toString('utf8');
|
|
793
|
-
case 'deflate':
|
|
794
|
-
return inflateSync(buf).toString('utf8');
|
|
795
|
-
default:
|
|
796
|
-
throw new Error(`core.decompress: unknown algorithm "${algorithm}"`);
|
|
797
|
-
}
|
|
61
|
+
return builtInActions.includes(action) || isFileOperation(action) || isParallelOperation(action);
|
|
798
62
|
}
|
|
799
63
|
//# sourceMappingURL=built-in-operations.js.map
|