@abyss-project/console 1.0.28 → 1.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/api/workflow.api.d.ts +2 -1
  2. package/dist/api/workflow.api.js +6 -1
  3. package/dist/expressions/functions/array.d.ts +2 -0
  4. package/dist/expressions/functions/array.js +252 -0
  5. package/dist/expressions/functions/crypto.d.ts +2 -0
  6. package/dist/expressions/functions/crypto.js +101 -0
  7. package/dist/expressions/functions/datetime.d.ts +2 -0
  8. package/dist/expressions/functions/datetime.js +256 -0
  9. package/dist/expressions/functions/index.d.ts +7 -0
  10. package/dist/expressions/functions/index.js +46 -0
  11. package/dist/expressions/functions/math.d.ts +2 -0
  12. package/dist/expressions/functions/math.js +174 -0
  13. package/dist/expressions/functions/string.d.ts +2 -0
  14. package/dist/expressions/functions/string.js +301 -0
  15. package/dist/expressions/functions/utility.d.ts +2 -0
  16. package/dist/expressions/functions/utility.js +230 -0
  17. package/dist/expressions/helpers.d.ts +26 -0
  18. package/dist/expressions/helpers.js +132 -0
  19. package/dist/expressions/index.d.ts +5 -0
  20. package/dist/expressions/index.js +16 -0
  21. package/dist/expressions/mapper.d.ts +9 -0
  22. package/dist/expressions/mapper.js +88 -0
  23. package/dist/expressions/parser.d.ts +3 -0
  24. package/dist/expressions/parser.js +97 -0
  25. package/dist/expressions/pipes/array-pipes.d.ts +2 -0
  26. package/dist/expressions/pipes/array-pipes.js +248 -0
  27. package/dist/expressions/pipes/index.d.ts +8 -0
  28. package/dist/expressions/pipes/index.js +40 -0
  29. package/dist/expressions/pipes/object-pipes.d.ts +2 -0
  30. package/dist/expressions/pipes/object-pipes.js +243 -0
  31. package/dist/expressions/pipes/string-pipes.d.ts +9 -0
  32. package/dist/expressions/pipes/string-pipes.js +178 -0
  33. package/dist/expressions/resolver.d.ts +12 -0
  34. package/dist/expressions/resolver.js +88 -0
  35. package/dist/expressions/types.d.ts +36 -0
  36. package/dist/expressions/types.js +2 -0
  37. package/dist/index.d.ts +5 -0
  38. package/dist/index.js +6 -1
  39. package/dist/types/interface/api/requests/workflow.request.d.ts +10 -0
  40. package/dist/types/interface/api/responses/workflow.response.d.ts +4 -0
  41. package/dist/utils/webhook-trigger.utils.js +10 -6
  42. package/dist/workflow-expressions/functions/array.d.ts +2 -0
  43. package/dist/workflow-expressions/functions/array.js +252 -0
  44. package/dist/workflow-expressions/functions/crypto.d.ts +2 -0
  45. package/dist/workflow-expressions/functions/crypto.js +101 -0
  46. package/dist/workflow-expressions/functions/datetime.d.ts +2 -0
  47. package/dist/workflow-expressions/functions/datetime.js +256 -0
  48. package/dist/workflow-expressions/functions/index.d.ts +7 -0
  49. package/dist/workflow-expressions/functions/index.js +46 -0
  50. package/dist/workflow-expressions/functions/math.d.ts +2 -0
  51. package/dist/workflow-expressions/functions/math.js +174 -0
  52. package/dist/workflow-expressions/functions/string.d.ts +2 -0
  53. package/dist/workflow-expressions/functions/string.js +301 -0
  54. package/dist/workflow-expressions/functions/utility.d.ts +2 -0
  55. package/dist/workflow-expressions/functions/utility.js +230 -0
  56. package/dist/workflow-expressions/helpers.d.ts +26 -0
  57. package/dist/workflow-expressions/helpers.js +130 -0
  58. package/dist/workflow-expressions/index.d.ts +15 -0
  59. package/dist/workflow-expressions/index.js +61 -0
  60. package/dist/workflow-expressions/parser.d.ts +8 -0
  61. package/dist/workflow-expressions/parser.js +456 -0
  62. package/dist/workflow-expressions/pipes/array-pipes.d.ts +2 -0
  63. package/dist/workflow-expressions/pipes/array-pipes.js +248 -0
  64. package/dist/workflow-expressions/pipes/index.d.ts +8 -0
  65. package/dist/workflow-expressions/pipes/index.js +40 -0
  66. package/dist/workflow-expressions/pipes/object-pipes.d.ts +2 -0
  67. package/dist/workflow-expressions/pipes/object-pipes.js +243 -0
  68. package/dist/workflow-expressions/pipes/string-pipes.d.ts +9 -0
  69. package/dist/workflow-expressions/pipes/string-pipes.js +178 -0
  70. package/dist/workflow-expressions/resolver.d.ts +8 -0
  71. package/dist/workflow-expressions/resolver.js +260 -0
  72. package/dist/workflow-expressions/types.d.ts +141 -0
  73. package/dist/workflow-expressions/types.js +33 -0
  74. package/package.json +2 -1
@@ -0,0 +1,15 @@
1
+ export { DataSourceType, OPERATOR_PRECEDENCE } from './types';
2
+ export type { ParsedExpression, PathExpression, FunctionExpression, BinaryExpression, UnaryExpression, TernaryExpression, LiteralExpression, GroupExpression, BuiltInFunction, FunctionCategory, FunctionArg, PipeOperation, OperationCategory, WorkflowContext, StepExecution, WorkflowStep, ValidationResult, ValidationError, ValidationWarning, ExpressionToken, WorkflowResourceMapping, } from './types';
3
+ export { parseExpression, detectDataSource, parsePathSegments, tokenizeTemplate } from './parser';
4
+ export { buildResolverContext, resolvePathValue, evaluateExpression, interpolateString, resolveExpression, } from './resolver';
5
+ export { BUILT_IN_FUNCTIONS, executeFunction, getFunctionsByCategory, getFunctionNames, hasFunction, getFunction, } from './functions';
6
+ export { PIPE_OPERATIONS, executePipeOperation, getPipesByCategory, getPipeNames, hasPipe, getPipe, } from './pipes';
7
+ export type { PipeDefinition } from './pipes/string-pipes';
8
+ import type { WorkflowContext } from './types';
9
+ export { buildExpressionString, buildReferenceString, hasExpressions, hasReferences, isInsideExpression, extractPaths, parseOperations, getCurrentExpressionContext, getValueType, } from './helpers';
10
+ export declare function evaluate(expression: string, workflowContext: WorkflowContext, secretsMap?: Map<string, string>): unknown;
11
+ export declare function interpolate(template: string, workflowContext: WorkflowContext, secretsMap?: Map<string, string>, options?: {
12
+ maskSecrets?: boolean;
13
+ }): string;
14
+ export declare function hasDynamicContent(str: string): boolean;
15
+ export declare function extractReferences(str: string): string[];
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractReferences = exports.hasDynamicContent = exports.interpolate = exports.evaluate = exports.getValueType = exports.getCurrentExpressionContext = exports.parseOperations = exports.extractPaths = exports.isInsideExpression = exports.hasReferences = exports.hasExpressions = exports.buildReferenceString = exports.buildExpressionString = exports.getPipe = exports.hasPipe = exports.getPipeNames = exports.getPipesByCategory = exports.executePipeOperation = exports.PIPE_OPERATIONS = exports.getFunction = exports.hasFunction = exports.getFunctionNames = exports.getFunctionsByCategory = exports.executeFunction = exports.BUILT_IN_FUNCTIONS = exports.resolveExpression = exports.interpolateString = exports.evaluateExpression = exports.resolvePathValue = exports.buildResolverContext = exports.tokenizeTemplate = exports.parsePathSegments = exports.detectDataSource = exports.parseExpression = exports.OPERATOR_PRECEDENCE = exports.DataSourceType = void 0;
4
+ var types_1 = require("./types");
5
+ Object.defineProperty(exports, "DataSourceType", { enumerable: true, get: function () { return types_1.DataSourceType; } });
6
+ Object.defineProperty(exports, "OPERATOR_PRECEDENCE", { enumerable: true, get: function () { return types_1.OPERATOR_PRECEDENCE; } });
7
+ var parser_1 = require("./parser");
8
+ Object.defineProperty(exports, "parseExpression", { enumerable: true, get: function () { return parser_1.parseExpression; } });
9
+ Object.defineProperty(exports, "detectDataSource", { enumerable: true, get: function () { return parser_1.detectDataSource; } });
10
+ Object.defineProperty(exports, "parsePathSegments", { enumerable: true, get: function () { return parser_1.parsePathSegments; } });
11
+ Object.defineProperty(exports, "tokenizeTemplate", { enumerable: true, get: function () { return parser_1.tokenizeTemplate; } });
12
+ var resolver_1 = require("./resolver");
13
+ Object.defineProperty(exports, "buildResolverContext", { enumerable: true, get: function () { return resolver_1.buildResolverContext; } });
14
+ Object.defineProperty(exports, "resolvePathValue", { enumerable: true, get: function () { return resolver_1.resolvePathValue; } });
15
+ Object.defineProperty(exports, "evaluateExpression", { enumerable: true, get: function () { return resolver_1.evaluateExpression; } });
16
+ Object.defineProperty(exports, "interpolateString", { enumerable: true, get: function () { return resolver_1.interpolateString; } });
17
+ Object.defineProperty(exports, "resolveExpression", { enumerable: true, get: function () { return resolver_1.resolveExpression; } });
18
+ var functions_1 = require("./functions");
19
+ Object.defineProperty(exports, "BUILT_IN_FUNCTIONS", { enumerable: true, get: function () { return functions_1.BUILT_IN_FUNCTIONS; } });
20
+ Object.defineProperty(exports, "executeFunction", { enumerable: true, get: function () { return functions_1.executeFunction; } });
21
+ Object.defineProperty(exports, "getFunctionsByCategory", { enumerable: true, get: function () { return functions_1.getFunctionsByCategory; } });
22
+ Object.defineProperty(exports, "getFunctionNames", { enumerable: true, get: function () { return functions_1.getFunctionNames; } });
23
+ Object.defineProperty(exports, "hasFunction", { enumerable: true, get: function () { return functions_1.hasFunction; } });
24
+ Object.defineProperty(exports, "getFunction", { enumerable: true, get: function () { return functions_1.getFunction; } });
25
+ var pipes_1 = require("./pipes");
26
+ Object.defineProperty(exports, "PIPE_OPERATIONS", { enumerable: true, get: function () { return pipes_1.PIPE_OPERATIONS; } });
27
+ Object.defineProperty(exports, "executePipeOperation", { enumerable: true, get: function () { return pipes_1.executePipeOperation; } });
28
+ Object.defineProperty(exports, "getPipesByCategory", { enumerable: true, get: function () { return pipes_1.getPipesByCategory; } });
29
+ Object.defineProperty(exports, "getPipeNames", { enumerable: true, get: function () { return pipes_1.getPipeNames; } });
30
+ Object.defineProperty(exports, "hasPipe", { enumerable: true, get: function () { return pipes_1.hasPipe; } });
31
+ Object.defineProperty(exports, "getPipe", { enumerable: true, get: function () { return pipes_1.getPipe; } });
32
+ const resolver_2 = require("./resolver");
33
+ var helpers_1 = require("./helpers");
34
+ Object.defineProperty(exports, "buildExpressionString", { enumerable: true, get: function () { return helpers_1.buildExpressionString; } });
35
+ Object.defineProperty(exports, "buildReferenceString", { enumerable: true, get: function () { return helpers_1.buildReferenceString; } });
36
+ Object.defineProperty(exports, "hasExpressions", { enumerable: true, get: function () { return helpers_1.hasExpressions; } });
37
+ Object.defineProperty(exports, "hasReferences", { enumerable: true, get: function () { return helpers_1.hasReferences; } });
38
+ Object.defineProperty(exports, "isInsideExpression", { enumerable: true, get: function () { return helpers_1.isInsideExpression; } });
39
+ Object.defineProperty(exports, "extractPaths", { enumerable: true, get: function () { return helpers_1.extractPaths; } });
40
+ Object.defineProperty(exports, "parseOperations", { enumerable: true, get: function () { return helpers_1.parseOperations; } });
41
+ Object.defineProperty(exports, "getCurrentExpressionContext", { enumerable: true, get: function () { return helpers_1.getCurrentExpressionContext; } });
42
+ Object.defineProperty(exports, "getValueType", { enumerable: true, get: function () { return helpers_1.getValueType; } });
43
+ function evaluate(expression, workflowContext, secretsMap) {
44
+ const context = (0, resolver_2.buildResolverContext)(workflowContext);
45
+ return (0, resolver_2.resolveExpression)(expression, context, secretsMap);
46
+ }
47
+ exports.evaluate = evaluate;
48
+ function interpolate(template, workflowContext, secretsMap, options) {
49
+ const context = (0, resolver_2.buildResolverContext)(workflowContext);
50
+ return (0, resolver_2.interpolateString)(template, context, secretsMap, options);
51
+ }
52
+ exports.interpolate = interpolate;
53
+ function hasDynamicContent(str) {
54
+ return /\{\{.+?\}\}/.test(str);
55
+ }
56
+ exports.hasDynamicContent = hasDynamicContent;
57
+ function extractReferences(str) {
58
+ const matches = str.matchAll(/\{\{(.+?)\}\}/g);
59
+ return Array.from(matches, (m) => m[1].trim());
60
+ }
61
+ exports.extractReferences = extractReferences;
@@ -0,0 +1,8 @@
1
+ import type { ParsedExpression, DataSourceType } from './types';
2
+ export declare function detectDataSource(path: string): DataSourceType | null;
3
+ export declare function parsePathSegments(path: string): string[];
4
+ export declare function parseExpression(expression: string): ParsedExpression;
5
+ export declare function tokenizeTemplate(template: string): Array<{
6
+ type: 'text' | 'expression';
7
+ value: string;
8
+ }>;
@@ -0,0 +1,456 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tokenizeTemplate = exports.parseExpression = exports.parsePathSegments = exports.detectDataSource = void 0;
4
+ const EXPRESSION_PATTERN = /\{\{(.+?)\}\}/g;
5
+ const FUNCTION_PATTERN = /^(?:fn\.)?(\w+)\((.*)\)$/s;
6
+ const PIPE_PATTERN = /\s*\|\s*(\w+)(?:\(([^)]*)\))?/g;
7
+ const DATA_SOURCE_PREFIXES = {
8
+ trigger: 'trigger',
9
+ triggerData: 'trigger',
10
+ steps: 'steps',
11
+ variables: 'variables',
12
+ secret: 'secret',
13
+ ipAddress: 'ipAddress',
14
+ domain: 'domain',
15
+ abyss: 'abyss',
16
+ app: 'app',
17
+ project: 'project',
18
+ env: 'env',
19
+ fn: 'fn',
20
+ };
21
+ function detectDataSource(path) {
22
+ const firstDot = path.indexOf('.');
23
+ const firstBracket = path.indexOf('[');
24
+ let prefix;
25
+ if (firstDot === -1 && firstBracket === -1) {
26
+ prefix = path;
27
+ }
28
+ else if (firstDot === -1) {
29
+ prefix = path.substring(0, firstBracket);
30
+ }
31
+ else if (firstBracket === -1) {
32
+ prefix = path.substring(0, firstDot);
33
+ }
34
+ else {
35
+ prefix = path.substring(0, Math.min(firstDot, firstBracket));
36
+ }
37
+ return DATA_SOURCE_PREFIXES[prefix] || null;
38
+ }
39
+ exports.detectDataSource = detectDataSource;
40
+ function parsePathSegments(path) {
41
+ const segments = [];
42
+ let current = '';
43
+ let inBracket = false;
44
+ let bracketContent = '';
45
+ for (let i = 0; i < path.length; i++) {
46
+ const char = path[i];
47
+ if (char === '[') {
48
+ if (current) {
49
+ segments.push(current);
50
+ current = '';
51
+ }
52
+ inBracket = true;
53
+ bracketContent = '';
54
+ }
55
+ else if (char === ']' && inBracket) {
56
+ const cleaned = bracketContent.replace(/^["']|["']$/g, '');
57
+ segments.push(cleaned);
58
+ inBracket = false;
59
+ bracketContent = '';
60
+ }
61
+ else if (inBracket) {
62
+ bracketContent += char;
63
+ }
64
+ else if (char === '.') {
65
+ if (current) {
66
+ segments.push(current);
67
+ current = '';
68
+ }
69
+ }
70
+ else {
71
+ current += char;
72
+ }
73
+ }
74
+ if (current) {
75
+ segments.push(current);
76
+ }
77
+ return segments;
78
+ }
79
+ exports.parsePathSegments = parsePathSegments;
80
+ function parseExpression(expression) {
81
+ const trimmed = expression.trim();
82
+ if (!trimmed) {
83
+ return {
84
+ type: 'literal',
85
+ literalType: 'string',
86
+ literalValue: '',
87
+ isValid: false,
88
+ error: 'Empty expression',
89
+ };
90
+ }
91
+ try {
92
+ return parseExpressionAST(trimmed);
93
+ }
94
+ catch (error) {
95
+ return {
96
+ type: 'literal',
97
+ literalType: 'string',
98
+ literalValue: '',
99
+ isValid: false,
100
+ error: error instanceof Error ? error.message : 'Parse error',
101
+ };
102
+ }
103
+ }
104
+ exports.parseExpression = parseExpression;
105
+ function parseExpressionAST(expr) {
106
+ const trimmed = expr.trim();
107
+ const ternary = findTernaryOperator(trimmed);
108
+ if (ternary) {
109
+ return {
110
+ type: 'ternary',
111
+ condition: parseExpressionAST(ternary.condition),
112
+ consequent: parseExpressionAST(ternary.consequent),
113
+ alternate: parseExpressionAST(ternary.alternate),
114
+ isValid: true,
115
+ };
116
+ }
117
+ const binary = findBinaryOperator(trimmed);
118
+ if (binary) {
119
+ return {
120
+ type: 'binary',
121
+ operator: binary.operator,
122
+ left: parseExpressionAST(binary.left),
123
+ right: parseExpressionAST(binary.right),
124
+ isValid: true,
125
+ };
126
+ }
127
+ return parsePrimary(trimmed);
128
+ }
129
+ function parsePrimary(expr) {
130
+ const trimmed = expr.trim();
131
+ if (trimmed.startsWith('!') && !trimmed.startsWith('!=')) {
132
+ return {
133
+ type: 'unary',
134
+ operator: '!',
135
+ operand: parsePrimary(trimmed.substring(1)),
136
+ isValid: true,
137
+ };
138
+ }
139
+ if (trimmed.startsWith('(') && trimmed.endsWith(')')) {
140
+ const inner = trimmed.substring(1, trimmed.length - 1);
141
+ return {
142
+ type: 'group',
143
+ expression: parseExpressionAST(inner),
144
+ isValid: true,
145
+ };
146
+ }
147
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
148
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
149
+ return {
150
+ type: 'literal',
151
+ literalType: 'string',
152
+ literalValue: trimmed.slice(1, -1),
153
+ isValid: true,
154
+ };
155
+ }
156
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
157
+ return {
158
+ type: 'literal',
159
+ literalType: 'number',
160
+ literalValue: parseFloat(trimmed),
161
+ isValid: true,
162
+ };
163
+ }
164
+ if (trimmed === 'true' || trimmed === 'false') {
165
+ return {
166
+ type: 'literal',
167
+ literalType: 'boolean',
168
+ literalValue: trimmed === 'true',
169
+ isValid: true,
170
+ };
171
+ }
172
+ if (trimmed === 'null') {
173
+ return {
174
+ type: 'literal',
175
+ literalType: 'null',
176
+ literalValue: null,
177
+ isValid: true,
178
+ };
179
+ }
180
+ const funcMatch = trimmed.match(FUNCTION_PATTERN);
181
+ if (funcMatch) {
182
+ const [, funcName, argsStr] = funcMatch;
183
+ return {
184
+ type: 'function',
185
+ isFunction: true,
186
+ functionName: funcName,
187
+ functionArgs: parseArgs(argsStr),
188
+ isValid: true,
189
+ };
190
+ }
191
+ const pipeIndex = findFirstPipeIndex(trimmed);
192
+ if (pipeIndex !== -1) {
193
+ const pathPart = trimmed.substring(0, pipeIndex).trim();
194
+ const pipesPart = trimmed.substring(pipeIndex);
195
+ const operations = parsePipeOperations(pipesPart);
196
+ const source = detectDataSource(pathPart);
197
+ return {
198
+ type: 'path',
199
+ path: pathPart,
200
+ source,
201
+ operations,
202
+ isValid: true,
203
+ };
204
+ }
205
+ const source = detectDataSource(trimmed);
206
+ return {
207
+ type: 'path',
208
+ path: trimmed,
209
+ source,
210
+ isValid: true,
211
+ };
212
+ }
213
+ const OPERATOR_PRECEDENCE_MAP = {
214
+ '||': 1,
215
+ '&&': 2,
216
+ '==': 3,
217
+ '!=': 3,
218
+ '<': 4,
219
+ '>': 4,
220
+ '<=': 4,
221
+ '>=': 4,
222
+ '+': 5,
223
+ '-': 5,
224
+ '*': 6,
225
+ '/': 6,
226
+ '%': 6,
227
+ '**': 7,
228
+ };
229
+ function findTernaryOperator(expr) {
230
+ let depth = 0;
231
+ let questionIdx = -1;
232
+ let colonIdx = -1;
233
+ for (let i = 0; i < expr.length; i++) {
234
+ const char = expr[i];
235
+ if (char === '(' || char === '[' || char === '{') {
236
+ depth++;
237
+ }
238
+ if (char === ')' || char === ']' || char === '}') {
239
+ depth--;
240
+ }
241
+ if (depth === 0) {
242
+ if (char === '?' && questionIdx === -1) {
243
+ questionIdx = i;
244
+ }
245
+ else if (char === ':' && questionIdx !== -1 && colonIdx === -1) {
246
+ colonIdx = i;
247
+ }
248
+ }
249
+ }
250
+ if (questionIdx !== -1 && colonIdx !== -1) {
251
+ return {
252
+ condition: expr.substring(0, questionIdx).trim(),
253
+ consequent: expr.substring(questionIdx + 1, colonIdx).trim(),
254
+ alternate: expr.substring(colonIdx + 1).trim(),
255
+ };
256
+ }
257
+ return null;
258
+ }
259
+ function findBinaryOperator(expr) {
260
+ const operators = [
261
+ '||',
262
+ '&&',
263
+ '===',
264
+ '!==',
265
+ '==',
266
+ '!=',
267
+ '>=',
268
+ '<=',
269
+ '>',
270
+ '<',
271
+ '**',
272
+ '+',
273
+ '-',
274
+ '*',
275
+ '/',
276
+ '%',
277
+ ];
278
+ let depth = 0;
279
+ let inString = false;
280
+ let stringChar = '';
281
+ let bestOp = null;
282
+ for (let i = 0; i < expr.length; i++) {
283
+ const char = expr[i];
284
+ if ((char === '"' || char === "'") && (i === 0 || expr[i - 1] !== '\\')) {
285
+ if (!inString) {
286
+ inString = true;
287
+ stringChar = char;
288
+ }
289
+ else if (char === stringChar) {
290
+ inString = false;
291
+ }
292
+ continue;
293
+ }
294
+ if (inString) {
295
+ continue;
296
+ }
297
+ if (char === '(' || char === '[' || char === '{')
298
+ depth++;
299
+ if (char === ')' || char === ']' || char === '}')
300
+ depth--;
301
+ if (depth !== 0)
302
+ continue;
303
+ for (const op of operators) {
304
+ if (expr.substring(i, i + op.length) === op) {
305
+ if (i === 0)
306
+ continue;
307
+ const precedence = OPERATOR_PRECEDENCE_MAP[op] || 0;
308
+ if (!bestOp ||
309
+ precedence < bestOp.precedence ||
310
+ (precedence === bestOp.precedence && i > bestOp.index)) {
311
+ bestOp = { operator: op, index: i, precedence };
312
+ }
313
+ break;
314
+ }
315
+ }
316
+ }
317
+ if (bestOp && bestOp.index > 0) {
318
+ return {
319
+ operator: bestOp.operator,
320
+ left: expr.substring(0, bestOp.index).trim(),
321
+ right: expr.substring(bestOp.index + bestOp.operator.length).trim(),
322
+ };
323
+ }
324
+ return null;
325
+ }
326
+ function findFirstPipeIndex(str) {
327
+ let depth = 0;
328
+ let inString = false;
329
+ let stringChar = '';
330
+ for (let i = 0; i < str.length; i++) {
331
+ const char = str[i];
332
+ const prevChar = i > 0 ? str[i - 1] : '';
333
+ if ((char === '"' || char === "'") && prevChar !== '\\') {
334
+ if (!inString) {
335
+ inString = true;
336
+ stringChar = char;
337
+ }
338
+ else if (char === stringChar) {
339
+ inString = false;
340
+ }
341
+ continue;
342
+ }
343
+ if (inString)
344
+ continue;
345
+ if (char === '(' || char === '[' || char === '{')
346
+ depth++;
347
+ if (char === ')' || char === ']' || char === '}')
348
+ depth--;
349
+ if (char === '|' && depth === 0 && str[i + 1] !== '|') {
350
+ return i;
351
+ }
352
+ }
353
+ return -1;
354
+ }
355
+ function parseArgs(argsString) {
356
+ if (!argsString.trim()) {
357
+ return [];
358
+ }
359
+ const args = [];
360
+ let current = '';
361
+ let depth = 0;
362
+ let inString = false;
363
+ let stringChar = '';
364
+ for (let i = 0; i < argsString.length; i++) {
365
+ const char = argsString[i];
366
+ const prevChar = i > 0 ? argsString[i - 1] : '';
367
+ if ((char === '"' || char === "'") && prevChar !== '\\') {
368
+ if (!inString) {
369
+ inString = true;
370
+ stringChar = char;
371
+ }
372
+ else if (char === stringChar) {
373
+ inString = false;
374
+ }
375
+ current += char;
376
+ continue;
377
+ }
378
+ if (inString) {
379
+ current += char;
380
+ continue;
381
+ }
382
+ if (char === '(' || char === '[' || char === '{') {
383
+ depth++;
384
+ current += char;
385
+ continue;
386
+ }
387
+ if (char === ')' || char === ']' || char === '}') {
388
+ depth--;
389
+ current += char;
390
+ continue;
391
+ }
392
+ if (char === ',' && depth === 0) {
393
+ args.push(parseArgValue(current.trim()));
394
+ current = '';
395
+ continue;
396
+ }
397
+ current += char;
398
+ }
399
+ if (current.trim()) {
400
+ args.push(parseArgValue(current.trim()));
401
+ }
402
+ return args;
403
+ }
404
+ function parseArgValue(value) {
405
+ if ((value.startsWith('"') && value.endsWith('"')) ||
406
+ (value.startsWith("'") && value.endsWith("'"))) {
407
+ return value.slice(1, -1);
408
+ }
409
+ if (value === 'true')
410
+ return true;
411
+ if (value === 'false')
412
+ return false;
413
+ if (value === 'null')
414
+ return null;
415
+ if (/^-?\d+(\.\d+)?$/.test(value))
416
+ return parseFloat(value);
417
+ return value;
418
+ }
419
+ function parsePipeOperations(pipesStr) {
420
+ const operations = [];
421
+ const pipePattern = /\s*\|\s*(\w+)(?:\(([^)]*)\))?/g;
422
+ let match;
423
+ while ((match = pipePattern.exec(pipesStr)) !== null) {
424
+ const [, name, argsStr] = match;
425
+ const args = argsStr ? parseArgs(argsStr) : [];
426
+ operations.push({ name, args });
427
+ }
428
+ return operations;
429
+ }
430
+ function tokenizeTemplate(template) {
431
+ const tokens = [];
432
+ let lastIndex = 0;
433
+ const regex = new RegExp(EXPRESSION_PATTERN);
434
+ let match;
435
+ while ((match = regex.exec(template)) !== null) {
436
+ if (match.index > lastIndex) {
437
+ tokens.push({
438
+ type: 'text',
439
+ value: template.substring(lastIndex, match.index),
440
+ });
441
+ }
442
+ tokens.push({
443
+ type: 'expression',
444
+ value: match[1],
445
+ });
446
+ lastIndex = match.index + match[0].length;
447
+ }
448
+ if (lastIndex < template.length) {
449
+ tokens.push({
450
+ type: 'text',
451
+ value: template.substring(lastIndex),
452
+ });
453
+ }
454
+ return tokens;
455
+ }
456
+ exports.tokenizeTemplate = tokenizeTemplate;
@@ -0,0 +1,2 @@
1
+ import type { PipeDefinition } from './string-pipes';
2
+ export declare const arrayPipes: Record<string, PipeDefinition>;