@adminide-stack/form-builder-core 5.1.4-alpha.49 → 5.1.4-alpha.58

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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [5.1.4-alpha.58](https://github.com/CDEBase/forms-stack/compare/v5.1.4-alpha.57...v5.1.4-alpha.58) (2025-10-06)
7
+
8
+ **Note:** Version bump only for package @adminide-stack/form-builder-core
9
+
10
+ ## [5.1.4-alpha.57](https://github.com/CDEBase/forms-stack/compare/v5.1.4-alpha.56...v5.1.4-alpha.57) (2025-10-03)
11
+
12
+ **Note:** Version bump only for package @adminide-stack/form-builder-core
13
+
6
14
  ## [5.1.4-alpha.49](https://github.com/CDEBase/forms-stack/compare/v5.1.4-alpha.48...v5.1.4-alpha.49) (2025-09-24)
7
15
 
8
16
  **Note:** Version bump only for package @adminide-stack/form-builder-core
@@ -54,8 +54,8 @@ ${indent(body, 4)}
54
54
  // New: return only the handler body that backend executes and editor displays
55
55
  function generateHandlerBody(def) {
56
56
  const stepBlocks = def.steps.map((step, index) => generateStepBlock(step, index + 1)).join('\n');
57
- const footer = `return {\n functionId: '${def.id}',\n steps: ${def.steps.length},\n timestamp: new Date().toISOString()\n};`;
58
- return `${stepBlocks}\n${footer}`;
57
+ // Footer removed: callers should append their own consolidated return as needed
58
+ return `${stepBlocks}`;
59
59
  }
60
60
  // Generate Inngest function from database-extracted functions
61
61
  function generateStepFunctionsFromDB(functionId, events, extractedFunctions) {
@@ -1 +1 @@
1
- {"version":3,"file":"stepGenerator.d.ts","sourceRoot":"","sources":["../../src/inngest/stepGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGzE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;GAGG;AAGH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAGD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4FrF;AAGD,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,WAAW,GAAG,iBAAiB,EACrC,KAAK,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAYnC;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0C/D;AAGD,wBAAgB,yBAAyB,CACrC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC/C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAClB,MAAM,CAsER;AAGD,wBAAgB,gCAAgC,CAC5C,aAAa,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACvF,MAAM,CAgCR;AAGD,wBAAgB,8BAA8B,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAoB9F"}
1
+ {"version":3,"file":"stepGenerator.d.ts","sourceRoot":"","sources":["../../src/inngest/stepGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGzE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;GAGG;AAGH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAGD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4FrF;AAGD,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,WAAW,GAAG,iBAAiB,EACrC,KAAK,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAYnC;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0E/D;AAED,wBAAgB,yBAAyB,CACrC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC/C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAClB,MAAM,CAsER;AAGD,wBAAgB,gCAAgC,CAC5C,aAAa,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACvF,MAAM,CAgCR;AAGD,wBAAgB,8BAA8B,CAAC,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,MAAM,CA6B9F"}
@@ -11,105 +11,6 @@ function extractStepVarName(code) {
11
11
  const match = code.match(/const\s+(\w+)\s*=/);
12
12
  return match ? match[1] : null;
13
13
  }
14
- // Generate default step function for different step types
15
- function generateDefaultStepFunction(stepVar, stepType) {
16
- switch (stepType) {
17
- case 'sleep':
18
- return `const ${stepVar} = async (event, step) => {
19
- // Sleep for specified duration
20
- const sleepResult = await step.sleep('${stepVar}', '5s');
21
-
22
- console.log('Sleep completed:', sleepResult);
23
-
24
- return { success: true, duration: '5s', result: sleepResult };
25
- };`;
26
- case 'sendEvent':
27
- return `const ${stepVar} = async (event, step) => {
28
- // Send an event to trigger other functions
29
- const eventResult = await step.sendEvent('${stepVar}', {
30
- name: 'my.custom.event',
31
- data: {
32
- source: '${stepVar}',
33
- timestamp: new Date().toISOString(),
34
- payload: event.data
35
- }
36
- });
37
-
38
- console.log('Event sent:', eventResult);
39
-
40
- return { success: true, eventSent: true, result: eventResult };
41
- };`;
42
- case 'waitForEvent':
43
- return `const ${stepVar} = async (event, step) => {
44
- // Wait for a specific event before continuing
45
- const waitResult = await step.waitForEvent('${stepVar}', {
46
- event: 'my.waited.event',
47
- timeout: '60s'
48
- });
49
-
50
- console.log('Event received:', waitResult);
51
-
52
- return { success: true, eventReceived: true, result: waitResult };
53
- };`;
54
- case 'retrieveData':
55
- return `const ${stepVar} = async (event, step) => {
56
- // Data retrieval implementation
57
- const formData = event.data.formData || {};
58
-
59
- // Process and retrieve data
60
- const retrievedData = {
61
- ...formData,
62
- processedAt: new Date().toISOString()
63
- };
64
-
65
- return { success: true, data: retrievedData };
66
- };`;
67
- case 'validateForm':
68
- return `const ${stepVar} = async (event, step) => {
69
- // Validate form data
70
- const formData = event.data.formData || {};
71
- const errors = [];
72
-
73
- // Add validation logic here
74
- if (!formData.email) {
75
- errors.push('Email is required');
76
- }
77
-
78
- return {
79
- success: errors.length === 0,
80
- errors,
81
- validated: errors.length === 0
82
- };
83
- };`;
84
- case 'parallel':
85
- return `const ${stepVar} = async (event, step) => {
86
- // Execute parallel operations
87
- const results = await Promise.all([
88
- // Add parallel operations here
89
- Promise.resolve({ task: 'task1', result: 'completed' }),
90
- Promise.resolve({ task: 'task2', result: 'completed' })
91
- ]);
92
-
93
- return { success: true, results };
94
- };`;
95
- default:
96
- return `const ${stepVar} = async (event, step) => {
97
- // Default step implementation
98
- return { success: true };
99
- };`;
100
- }
101
- }
102
- // Generate a step function in editor format (const step_xxx = async (event, step) => {...})
103
- function generateStepFunction(step, index) {
104
- // Extract or generate step variable name
105
- const varName = extractStepVarName(step.code || '') || step.originalStepName || step.id || `step_${index}`;
106
- // If step has code, use it; otherwise generate default
107
- const code = step.code || generateDefaultStepFunction(varName, step.type || 'run');
108
- return {
109
- code: cleanStepCode(code),
110
- varName
111
- };
112
- }
113
14
  // Extract function body from step function code
114
15
  function extractFunctionBody(code) {
115
16
  // Find the opening brace after the arrow or function keyword
@@ -129,15 +30,40 @@ function extractFunctionBody(code) {
129
30
  startIndex = openBraceIndex + 1;
130
31
  }
131
32
  }
132
- if (startIndex === -1) return null;
33
+ if (startIndex === -1) {
34
+ // FALLBACK: If we can't find function wrapper, return the whole code
35
+ console.warn('Could not extract function body, returning full code');
36
+ return code;
37
+ }
133
38
  // Find the matching closing brace by counting braces
134
39
  let braceCount = 1;
135
40
  let endIndex = startIndex;
41
+ let inString = false;
42
+ let stringChar = '';
43
+ let inTemplate = false;
136
44
  while (endIndex < code.length && braceCount > 0) {
137
- if (code[endIndex] === '{') {
138
- braceCount++;
139
- } else if (code[endIndex] === '}') {
140
- braceCount--;
45
+ const char = code[endIndex];
46
+ const prevChar = endIndex > 0 ? code[endIndex - 1] : '';
47
+ // Handle string literals
48
+ if ((char === '"' || char === "'") && prevChar !== '\\') {
49
+ if (!inString) {
50
+ inString = true;
51
+ stringChar = char;
52
+ } else if (char === stringChar) {
53
+ inString = false;
54
+ }
55
+ }
56
+ // Handle template literals
57
+ if (char === '`' && prevChar !== '\\') {
58
+ inTemplate = !inTemplate;
59
+ }
60
+ // Only count braces outside of strings
61
+ if (!inString && !inTemplate) {
62
+ if (char === '{') {
63
+ braceCount++;
64
+ } else if (char === '}') {
65
+ braceCount--;
66
+ }
141
67
  }
142
68
  if (braceCount > 0) {
143
69
  endIndex++;
@@ -146,107 +72,34 @@ function extractFunctionBody(code) {
146
72
  if (braceCount === 0) {
147
73
  return code.substring(startIndex, endIndex).trim();
148
74
  }
149
- return null;
75
+ // FALLBACK: Return full code if brace matching fails
76
+ console.warn('Brace matching failed, returning full code');
77
+ return code;
150
78
  }
151
- // Transform a step function for execution inside Inngest wrapper
152
- function transformStepForExecution(stepFunction, stepType, stepLabel) {
153
- const functionBody = extractFunctionBody(stepFunction.code);
154
- if (!functionBody) {
155
- return `// ${stepLabel}\nconst ${stepFunction.varName}_result = { success: false, error: 'Invalid function format' };`;
79
+ // Convert ExtractedFunction array to step functions and generate Inngest function
80
+ function generateFromExtractedFunctions(extractedFunctions) {
81
+ if (extractedFunctions.length === 0) {
82
+ return 'return { success: false, error: "No functions to execute" };';
156
83
  }
157
- const cleanedBody = cleanStepCode(functionBody);
158
- // For these step types, execute the body directly (they contain step.* calls)
159
- if (stepType === 'sleep' || stepType === 'sendEvent' || stepType === 'waitForEvent') {
160
- // Transform the body to ensure result is captured
161
- let transformedBody = cleanedBody;
162
- // Replace step method calls to ensure result variable is created
163
- transformedBody = transformedBody.replace(/(const\s+\w+\s*=\s*)?await\s+step\.(sleep|sendEvent|waitForEvent)/g, (match, constPart, method) => {
164
- if (constPart) {
165
- // Already has assignment, replace variable name
166
- return `const ${stepFunction.varName}_result = await step.${method}`;
167
- }
168
- // No assignment, add one
169
- return `const ${stepFunction.varName}_result = await step.${method}`;
170
- });
171
- // Find the original variable name from the step assignment
172
- const originalVarMatch = transformedBody.match(/const\s+(\w+)\s*=\s*await\s+step\./);
173
- let originalVarName = null;
174
- // Also try to find variable from the original code before transformation
175
- if (!originalVarMatch) {
176
- const [, codeVarName] = cleanedBody.match(/const\s+(\w+)\s*=\s*await\s+step\./) || [];
177
- if (codeVarName) {
178
- originalVarName = codeVarName;
179
- }
180
- }
181
- // Replace variable references (like eventResult, sleepResult, waitResult)
182
- // Common patterns: eventResult, sleepResult, waitResult, or any variable used in console.log/return
183
- if (originalVarName) {
184
- // Replace all references to the original variable with the new result variable
185
- const varPattern = new RegExp(`\\b${originalVarName}\\b`, 'g');
186
- transformedBody = transformedBody.replace(varPattern, `${stepFunction.varName}_result`);
84
+ // For functions that are complete workflow steps (like step_416),
85
+ // just return the code body directly without extraction
86
+ const func = extractedFunctions[0];
87
+ // Check if this is a complete function (has async function signature)
88
+ if (func.code && func.code.includes('async function')) {
89
+ // Extract just the body, preserving all helper functions and logic
90
+ const bodyMatch = func.code.match(/async function[^{]*\{([\s\S]*)\}[\s]*$/);
91
+ if (bodyMatch) {
92
+ return bodyMatch[1].trim();
187
93
  }
188
- // Also replace common result variable names that might not have been caught
189
- transformedBody = transformedBody.replace(/\beventResult\b/g, `${stepFunction.varName}_result`).replace(/\bsleepResult\b/g, `${stepFunction.varName}_result`).replace(/\bwaitResult\b/g, `${stepFunction.varName}_result`);
190
- // Remove return statements (since we'll add our own unified return)
191
- transformedBody = transformedBody.split('\n').filter(line => {
192
- const trimmed = line.trim();
193
- // Remove lines that start with 'return'
194
- return !trimmed.match(/^return\s/);
195
- }).join('\n');
196
- return `// ${stepLabel}\n ${transformedBody}`;
197
94
  }
198
- // For other step types, wrap in step.run()
199
- return `// ${stepLabel}
200
- const ${stepFunction.varName}_result = await step.run('${stepFunction.varName}', async (event, step) => {
201
- ${cleanedBody}
202
- });`;
203
- }
204
- // Generate complete Inngest function from step functions
205
- function generateInngestFunctionFromSteps(stepFunctions) {
206
- // Transform each step for execution
207
- const stepBlocks = [];
208
- const resultVars = [];
209
- stepFunctions.forEach((stepFunc, index) => {
210
- const stepType = stepFunc.type || 'run';
211
- const stepLabel = stepFunc.label || `Step ${index + 1}`;
212
- const executionCode = transformStepForExecution(stepFunc, stepType, stepLabel);
213
- stepBlocks.push(executionCode);
214
- // Determine result variable name
215
- if (executionCode.includes(`${stepFunc.varName}_result`)) {
216
- resultVars.push(`${stepFunc.varName}_result`);
217
- } else {
218
- // For direct execution without result assignment
219
- resultVars.push(stepFunc.varName);
95
+ // Check if code has arrow function format: const x = async (event, step) => { ... }
96
+ if (func.code && func.code.includes('async') && func.code.includes('=>')) {
97
+ const arrowBodyMatch = func.code.match(/=>\s*\{([\s\S]*)\}[\s]*;?[\s]*$/);
98
+ if (arrowBodyMatch) {
99
+ return arrowBodyMatch[1].trim();
220
100
  }
221
- });
222
- // Generate function body without async wrapper
223
- const code = `${stepBlocks.join('\n\n')}
224
-
225
- return {
226
- steps: ${stepFunctions.length},
227
- results: {
228
- ${resultVars.map((v, i) => ` ${stepFunctions[i].varName}: ${v}`).join(',\n')}
229
- }
230
- };`;
231
- return code;
232
- }
233
- // Convert ExtractedFunction array to step functions and generate Inngest function
234
- function generateFromExtractedFunctions(extractedFunctions) {
235
- // Convert extracted functions to step function format
236
- const stepFunctions = extractedFunctions.map((func, index) => {
237
- const {
238
- code,
239
- varName
240
- } = generateStepFunction(func, index + 1);
241
- // Detect step type from the code
242
- let type = 'run';
243
- if (code.includes('step.sleep(')) type = 'sleep';else if (code.includes('step.sendEvent(')) type = 'sendEvent';else if (code.includes('step.waitForEvent(')) type = 'waitForEvent';
244
- return {
245
- code,
246
- varName,
247
- type,
248
- label: func.name || `Step ${index + 1}`
249
- };
250
- });
251
- return generateInngestFunctionFromSteps(stepFunctions);
252
- }export{cleanStepCode,extractFunctionBody,extractStepVarName,generateDefaultStepFunction,generateFromExtractedFunctions,generateInngestFunctionFromSteps,generateStepFunction,transformStepForExecution};//# sourceMappingURL=stepGenerator.js.map
101
+ }
102
+ // Fallback: return the code as-is if we can't parse it
103
+ console.warn('Could not parse function format, returning code as-is');
104
+ return func.code || 'return { success: false, error: "No code available" };';
105
+ }export{cleanStepCode,extractFunctionBody,extractStepVarName,generateFromExtractedFunctions};//# sourceMappingURL=stepGenerator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stepGenerator.js","sources":["../../src/inngest/stepGenerator.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AAGA;AAEA;;;AAGG,SAAA,aAAA,CAAA,IAAA,EAAA;AAGH,EAAA,OAAA,IAAA;AAKA;AAMA;AA+FA,SAAA,kBAAgB,CAAA,IAAA,EAAA;QAGP,QAAQ,IAAC,CAAA,KAAA,CAAA,mBAAA,CAAA;SAAC,aAAe,CAAA,CAAA,CAAA,GAAA,IAAA;;AAelC;AA6CA,SAAA,2BAAgB,CAAA,OACZ,EAAA,QAAA,EAAY;UAAU,QAAO;IAAC,KAAA;MAC9B,OAAU,CAAA,MAAM,UACP;AA0Eb;wCACwC,EAAA,OAAA,CAAA;;;;;AAoCxC,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"stepGenerator.js","sources":["../../src/inngest/stepGenerator.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AAGA;AAEA;;;AAGG,SAAA,aAAA,CAAA,IAAA,EAAA;AAGH,EAAA,OAAA,IAAA;AAKA;AAMA;AA+FA,SAAA,kBAAgB,CAAA,IAAA,EAAA;QAGP,QAAQ,IAAC,CAAA,KAAA,CAAA,mBAAA,CAAA;SAAC,aAAe,CAAA,CAAA,CAAA,GAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminide-stack/form-builder-core",
3
- "version": "5.1.4-alpha.49",
3
+ "version": "5.1.4-alpha.58",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -24,5 +24,5 @@
24
24
  "publishConfig": {
25
25
  "access": "public"
26
26
  },
27
- "gitHead": "4fc9dbe45e8754f40077dc927b64be811d2e1562"
27
+ "gitHead": "4ddce5652e314ce3408435942885de210e49a6af"
28
28
  }
@@ -89,8 +89,8 @@ ${indent(body, 4)}
89
89
  // New: return only the handler body that backend executes and editor displays
90
90
  export function generateHandlerBody(def: InngestFunctionDef): string {
91
91
  const stepBlocks = def.steps.map((step, index) => generateStepBlock(step, index + 1)).join('\n');
92
- const footer = `return {\n functionId: '${def.id}',\n steps: ${def.steps.length},\n timestamp: new Date().toISOString()\n};`;
93
- return `${stepBlocks}\n${footer}`;
92
+ // Footer removed: callers should append their own consolidated return as needed
93
+ return `${stepBlocks}`;
94
94
  }
95
95
 
96
96
  // Generate Inngest function from database-extracted functions
@@ -154,17 +154,47 @@ export function extractFunctionBody(code: string): string | null {
154
154
  }
155
155
  }
156
156
 
157
- if (startIndex === -1) return null;
157
+ if (startIndex === -1) {
158
+ // FALLBACK: If we can't find function wrapper, return the whole code
159
+ console.warn('Could not extract function body, returning full code');
160
+ return code;
161
+ }
158
162
 
159
163
  // Find the matching closing brace by counting braces
160
164
  let braceCount = 1;
161
165
  let endIndex = startIndex;
166
+ let inString = false;
167
+ let stringChar = '';
168
+ let inTemplate = false;
169
+
162
170
  while (endIndex < code.length && braceCount > 0) {
163
- if (code[endIndex] === '{') {
164
- braceCount++;
165
- } else if (code[endIndex] === '}') {
166
- braceCount--;
171
+ const char = code[endIndex];
172
+ const prevChar = endIndex > 0 ? code[endIndex - 1] : '';
173
+
174
+ // Handle string literals
175
+ if ((char === '"' || char === "'") && prevChar !== '\\') {
176
+ if (!inString) {
177
+ inString = true;
178
+ stringChar = char;
179
+ } else if (char === stringChar) {
180
+ inString = false;
181
+ }
182
+ }
183
+
184
+ // Handle template literals
185
+ if (char === '`' && prevChar !== '\\') {
186
+ inTemplate = !inTemplate;
167
187
  }
188
+
189
+ // Only count braces outside of strings
190
+ if (!inString && !inTemplate) {
191
+ if (char === '{') {
192
+ braceCount++;
193
+ } else if (char === '}') {
194
+ braceCount--;
195
+ }
196
+ }
197
+
168
198
  if (braceCount > 0) {
169
199
  endIndex++;
170
200
  }
@@ -174,9 +204,10 @@ export function extractFunctionBody(code: string): string | null {
174
204
  return code.substring(startIndex, endIndex).trim();
175
205
  }
176
206
 
177
- return null;
207
+ // FALLBACK: Return full code if brace matching fails
208
+ console.warn('Brace matching failed, returning full code');
209
+ return code;
178
210
  }
179
-
180
211
  // Transform a step function for execution inside Inngest wrapper
181
212
  export function transformStepForExecution(
182
213
  stepFunction: { code: string; varName: string },
@@ -293,23 +324,32 @@ ${resultVars.map((v, i) => ` ${stepFunctions[i].varName}: ${v}`).
293
324
 
294
325
  // Convert ExtractedFunction array to step functions and generate Inngest function
295
326
  export function generateFromExtractedFunctions(extractedFunctions: ExtractedFunction[]): string {
296
- // Convert extracted functions to step function format
297
- const stepFunctions = extractedFunctions.map((func, index) => {
298
- const { code, varName } = generateStepFunction(func, index + 1);
327
+ if (extractedFunctions.length === 0) {
328
+ return 'return { success: false, error: "No functions to execute" };';
329
+ }
299
330
 
300
- // Detect step type from the code
301
- let type = 'run';
302
- if (code.includes('step.sleep(')) type = 'sleep';
303
- else if (code.includes('step.sendEvent(')) type = 'sendEvent';
304
- else if (code.includes('step.waitForEvent(')) type = 'waitForEvent';
331
+ // For functions that are complete workflow steps (like step_416),
332
+ // just return the code body directly without extraction
333
+ const func = extractedFunctions[0];
305
334
 
306
- return {
307
- code,
308
- varName,
309
- type,
310
- label: func.name || `Step ${index + 1}`,
311
- };
312
- });
335
+ // Check if this is a complete function (has async function signature)
336
+ if (func.code && func.code.includes('async function')) {
337
+ // Extract just the body, preserving all helper functions and logic
338
+ const bodyMatch = func.code.match(/async function[^{]*\{([\s\S]*)\}[\s]*$/);
339
+ if (bodyMatch) {
340
+ return bodyMatch[1].trim();
341
+ }
342
+ }
343
+
344
+ // Check if code has arrow function format: const x = async (event, step) => { ... }
345
+ if (func.code && func.code.includes('async') && func.code.includes('=>')) {
346
+ const arrowBodyMatch = func.code.match(/=>\s*\{([\s\S]*)\}[\s]*;?[\s]*$/);
347
+ if (arrowBodyMatch) {
348
+ return arrowBodyMatch[1].trim();
349
+ }
350
+ }
313
351
 
314
- return generateInngestFunctionFromSteps(stepFunctions);
352
+ // Fallback: return the code as-is if we can't parse it
353
+ console.warn('Could not parse function format, returning code as-is');
354
+ return func.code || 'return { success: false, error: "No code available" };';
315
355
  }