@adminide-stack/form-builder-core 5.1.4-alpha.81 → 6.0.1-alpha.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.
- package/LICENSE +30 -21
- package/lib/index.js +1 -1
- package/lib/inngest/generateFunctionCode.d.ts +1 -0
- package/lib/inngest/generateFunctionCode.d.ts.map +1 -1
- package/lib/inngest/generateFunctionCode.js +72 -3
- package/lib/inngest/generateFunctionCode.js.map +1 -1
- package/package.json +2 -2
- package/CHANGELOG.md +0 -56
- package/rollup.config.mjs +0 -33
- package/src/index.ts +0 -5
- package/src/inngest/MONACO_INTEGRATION_EXAMPLE.md +0 -406
- package/src/inngest/README_AUTOCOMPLETE.md +0 -380
- package/src/inngest/generateFunctionCode.ts +0 -151
- package/src/inngest/interfaces/index.ts +0 -1
- package/src/inngest/interfaces/types.ts +0 -63
- package/src/inngest/monacoAutocompleteIntegration.ts +0 -432
- package/src/inngest/stepGenerator.ts +0 -538
- package/src/utils/json.ts +0 -50
- package/tsconfig.json +0 -14
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
# JavaScript Autocomplete Integration for Inngest Steps
|
|
2
|
-
|
|
3
|
-
Complete integration of intelligent JavaScript autocompletion in step function editors.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
This integration connects Monaco Editor with the `js-autocomplete-extension` to provide:
|
|
8
|
-
|
|
9
|
-
- Context-aware JavaScript completions using Tern.js
|
|
10
|
-
- Type information on hover
|
|
11
|
-
- Step-specific completions for Inngest workflows
|
|
12
|
-
- Library support (lodash, moment, etc.)
|
|
13
|
-
- Dynamic completions based on execution context
|
|
14
|
-
|
|
15
|
-
## Architecture
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
┌─────────────────────────────────────────────────┐
|
|
19
|
-
│ CodeEditor Component │
|
|
20
|
-
│ (Monaco Editor Instance) │
|
|
21
|
-
└──────────────────┬──────────────────────────────┘
|
|
22
|
-
│
|
|
23
|
-
│ User types code
|
|
24
|
-
│
|
|
25
|
-
┌──────────────────▼──────────────────────────────┐
|
|
26
|
-
│ monacoAutocompleteIntegration.ts │
|
|
27
|
-
│ - setupMonacoAutocomplete() │
|
|
28
|
-
│ - setupStepAutocomplete() │
|
|
29
|
-
└──────────────────┬──────────────────────────────┘
|
|
30
|
-
│
|
|
31
|
-
│ services.commands.executeCommand()
|
|
32
|
-
│
|
|
33
|
-
┌──────────────────▼──────────────────────────────┐
|
|
34
|
-
│ js-autocomplete-extension │
|
|
35
|
-
│ - jsAutocomplete.getCompletions │
|
|
36
|
-
│ - jsAutocomplete.getTypeInfo │
|
|
37
|
-
│ - jsAutocomplete.installLibrary │
|
|
38
|
-
└──────────────────┬──────────────────────────────┘
|
|
39
|
-
│
|
|
40
|
-
│ code.javascript.* API
|
|
41
|
-
│
|
|
42
|
-
┌──────────────────▼──────────────────────────────┐
|
|
43
|
-
│ JavaScript Worker (Tern.js) │
|
|
44
|
-
│ - Type inference │
|
|
45
|
-
│ - Library definitions │
|
|
46
|
-
│ - Scope analysis │
|
|
47
|
-
└──────────────────────────────────────────────────┘
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Files Created
|
|
51
|
-
|
|
52
|
-
### 1. `stepGenerator.ts` (Updated)
|
|
53
|
-
|
|
54
|
-
Added completion support functions:
|
|
55
|
-
|
|
56
|
-
- `getStepCompletionScope()` - Returns available scope variables
|
|
57
|
-
- `getStepTypeDefinitions()` - Returns TypeScript definitions for Inngest API
|
|
58
|
-
- `getStepTypeCompletions()` - Returns step-type-specific completions
|
|
59
|
-
- `extractVariablesFromCode()` - Extracts variables from code for context
|
|
60
|
-
- `getStepCompletionContext()` - Gets complete completion context for a step
|
|
61
|
-
|
|
62
|
-
### 2. `monacoAutocompleteIntegration.ts` (New)
|
|
63
|
-
|
|
64
|
-
Monaco Editor integration layer:
|
|
65
|
-
|
|
66
|
-
- `setupMonacoAutocomplete()` - Setup general JS/TS autocomplete
|
|
67
|
-
- `setupStepAutocomplete()` - Setup step-specific autocomplete
|
|
68
|
-
- `installLibraryForAutocomplete()` - Install library definitions
|
|
69
|
-
- `updateAutocompleteConfig()` - Update autocomplete settings
|
|
70
|
-
- `getAvailableDefinitions()` - Get loaded type definitions
|
|
71
|
-
|
|
72
|
-
Uses your command execution pattern:
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
await services.commands.executeCommand({
|
|
76
|
-
command: 'jsAutocomplete.getCompletions',
|
|
77
|
-
arguments: [text, position, scope],
|
|
78
|
-
});
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Usage in CodeEditor
|
|
82
|
-
|
|
83
|
-
### Basic Integration
|
|
84
|
-
|
|
85
|
-
```tsx
|
|
86
|
-
import { setupMonacoAutocomplete } from '@form-builder/core/inngest/monacoAutocompleteIntegration';
|
|
87
|
-
|
|
88
|
-
const CodeEditor: React.FC<CodeEditorProps> = ({ value, onChange, services }) => {
|
|
89
|
-
const handleEditorWillMount = async (monaco: any) => {
|
|
90
|
-
// Setup autocomplete
|
|
91
|
-
if (services?.commands) {
|
|
92
|
-
await setupMonacoAutocomplete(
|
|
93
|
-
monaco,
|
|
94
|
-
{
|
|
95
|
-
enableInngestContext: true,
|
|
96
|
-
customScope: ['step', 'event'],
|
|
97
|
-
enableHoverInfo: true,
|
|
98
|
-
commandService: services.commands,
|
|
99
|
-
},
|
|
100
|
-
services.commands,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Rest of your setup...
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
return <Editor beforeMount={handleEditorWillMount} />;
|
|
108
|
-
};
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Step-Specific Integration
|
|
112
|
-
|
|
113
|
-
```tsx
|
|
114
|
-
import { setupStepAutocomplete } from '@form-builder/core/inngest/monacoAutocompleteIntegration';
|
|
115
|
-
|
|
116
|
-
const handleEditorWillMount = async (monaco: any) => {
|
|
117
|
-
if (services?.commands && currentStep) {
|
|
118
|
-
// Provides step-type-specific completions
|
|
119
|
-
await setupStepAutocomplete(monaco, currentStep, code, services.commands);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Extension Commands
|
|
125
|
-
|
|
126
|
-
All extension commands follow your command execution pattern:
|
|
127
|
-
|
|
128
|
-
### Get Completions
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
const result = await services.commands.executeCommand({
|
|
132
|
-
command: 'jsAutocomplete.getCompletions',
|
|
133
|
-
arguments: [
|
|
134
|
-
text, // Full source code
|
|
135
|
-
position, // Cursor offset
|
|
136
|
-
['step', 'event', 'myVar'], // Optional scope
|
|
137
|
-
],
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Returns:
|
|
141
|
-
// {
|
|
142
|
-
// completions: [
|
|
143
|
-
// { name: 'run', type: 'fn(id: string, fn: function): Promise', doc: '...' },
|
|
144
|
-
// { name: 'sleep', type: 'fn(id: string, duration: string): Promise', doc: '...' }
|
|
145
|
-
// ],
|
|
146
|
-
// isIncomplete: false
|
|
147
|
-
// }
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Get Type Info
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
const typeInfo = await services.commands.executeCommand({
|
|
154
|
-
command: 'jsAutocomplete.getTypeInfo',
|
|
155
|
-
arguments: ['step', ['event', 'step']],
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Returns:
|
|
159
|
-
// {
|
|
160
|
-
// type: 'object with methods run, sleep, sendEvent, waitForEvent',
|
|
161
|
-
// doc: 'Inngest step API for workflow orchestration',
|
|
162
|
-
// url: 'https://docs.inngest.com'
|
|
163
|
-
// }
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Install Library
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
await services.commands.executeCommand({
|
|
170
|
-
command: 'jsAutocomplete.installLibrary',
|
|
171
|
-
arguments: ['https://cdn.jsdelivr.net/npm/@types/lodash/index.d.ts', ['_', 'lodash']],
|
|
172
|
-
});
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Update Configuration
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
await services.commands.executeCommand({
|
|
179
|
-
command: 'jsAutocomplete.updateConfig',
|
|
180
|
-
arguments: [
|
|
181
|
-
{
|
|
182
|
-
includeDefaults: true,
|
|
183
|
-
includeLibraries: true,
|
|
184
|
-
enableDynamicLibraries: true,
|
|
185
|
-
customDefinitions: ['lodash', 'moment'],
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Step-Specific Completions
|
|
192
|
-
|
|
193
|
-
The integration provides context-aware completions based on step type:
|
|
194
|
-
|
|
195
|
-
### Sleep Step
|
|
196
|
-
|
|
197
|
-
```javascript
|
|
198
|
-
step.sleep('step-id', '5s'); // Completions show duration formats: "5s", "1m", "1h"
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Send Event Step
|
|
202
|
-
|
|
203
|
-
```javascript
|
|
204
|
-
step.sendEvent('step-id', {
|
|
205
|
-
name: 'my.event', // Completions suggest event patterns
|
|
206
|
-
data: {}, // Type-aware data completions
|
|
207
|
-
});
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Wait For Event Step
|
|
211
|
-
|
|
212
|
-
```javascript
|
|
213
|
-
step.waitForEvent('step-id', {
|
|
214
|
-
event: '', // Event name completions
|
|
215
|
-
timeout: '', // Duration completions
|
|
216
|
-
});
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Run Step
|
|
220
|
-
|
|
221
|
-
```javascript
|
|
222
|
-
step.run('step-id', async (event, step) => {
|
|
223
|
-
event. // Completions for event properties
|
|
224
|
-
step. // Completions for step methods
|
|
225
|
-
})
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## Type Definitions
|
|
229
|
-
|
|
230
|
-
The integration includes comprehensive type definitions:
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
declare const step: {
|
|
234
|
-
run<T>(id: string, fn: (event: any, step: any) => Promise<T> | T): Promise<T>;
|
|
235
|
-
sendEvent(id: string, input: { name: string; data?: any }): Promise<void>;
|
|
236
|
-
waitForEvent<T = any>(id: string, opts: { event: string; timeout?: string | number }): Promise<T>;
|
|
237
|
-
sleep(id: string, ms: string | number): Promise<void>;
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
declare const event: {
|
|
241
|
-
data: any;
|
|
242
|
-
id: string;
|
|
243
|
-
name: string;
|
|
244
|
-
ts: number;
|
|
245
|
-
};
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Features
|
|
249
|
-
|
|
250
|
-
### 1. Context-Aware Completions
|
|
251
|
-
|
|
252
|
-
- Knows about `step`, `event`, and local variables
|
|
253
|
-
- Provides method completions based on type inference
|
|
254
|
-
- Suggests relevant APIs for current step type
|
|
255
|
-
|
|
256
|
-
### 2. Hover Type Information
|
|
257
|
-
|
|
258
|
-
- Hover over any symbol to see its type
|
|
259
|
-
- View documentation inline
|
|
260
|
-
- Links to external documentation
|
|
261
|
-
|
|
262
|
-
### 3. Library Support
|
|
263
|
-
|
|
264
|
-
- Automatically includes installed libraries
|
|
265
|
-
- Dynamic library detection from execution context
|
|
266
|
-
- Custom library definitions
|
|
267
|
-
|
|
268
|
-
### 4. Scope Analysis
|
|
269
|
-
|
|
270
|
-
- Extracts variables from code
|
|
271
|
-
- Maintains scope context across edits
|
|
272
|
-
- Provides completions for local variables
|
|
273
|
-
|
|
274
|
-
### 5. Snippets Integration
|
|
275
|
-
|
|
276
|
-
- Works alongside your existing Monaco snippets
|
|
277
|
-
- Doesn't conflict with manual completions
|
|
278
|
-
- Combines template snippets with intelligent completions
|
|
279
|
-
|
|
280
|
-
## Configuration
|
|
281
|
-
|
|
282
|
-
Users can configure autocomplete behavior:
|
|
283
|
-
|
|
284
|
-
```typescript
|
|
285
|
-
{
|
|
286
|
-
"jsAutocomplete.includeDefaults": true, // ECMAScript definitions
|
|
287
|
-
"jsAutocomplete.includeLibraries": true, // Installed libraries
|
|
288
|
-
"jsAutocomplete.enableDynamicLibraries": true, // Runtime detection
|
|
289
|
-
"jsAutocomplete.customDefinitions": [] // Custom type defs
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Testing
|
|
294
|
-
|
|
295
|
-
### Test Extension Availability
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
React.useEffect(() => {
|
|
299
|
-
if (services?.commands) {
|
|
300
|
-
services.commands
|
|
301
|
-
.executeCommand({
|
|
302
|
-
command: 'jsAutocomplete.getAvailableDefinitions',
|
|
303
|
-
arguments: [],
|
|
304
|
-
})
|
|
305
|
-
.then((defs) => {
|
|
306
|
-
console.log('Extension loaded, definitions:', defs);
|
|
307
|
-
})
|
|
308
|
-
.catch((err) => {
|
|
309
|
-
console.error('Extension not available:', err);
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}, [services]);
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Test Completions
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
const testCompletions = async () => {
|
|
319
|
-
const result = await services.commands.executeCommand({
|
|
320
|
-
command: 'jsAutocomplete.getCompletions',
|
|
321
|
-
arguments: ['step.', 5, ['step', 'event']],
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
console.log('Completions:', result.completions);
|
|
325
|
-
// Should show: run, sleep, sendEvent, waitForEvent
|
|
326
|
-
};
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## Troubleshooting
|
|
330
|
-
|
|
331
|
-
### No Completions Showing
|
|
332
|
-
|
|
333
|
-
1. ✅ Check extension is activated in console
|
|
334
|
-
2. ✅ Verify `services.commands` is available
|
|
335
|
-
3. ✅ Test command execution manually
|
|
336
|
-
4. ✅ Check Monaco provider was registered
|
|
337
|
-
|
|
338
|
-
### Wrong Completions
|
|
339
|
-
|
|
340
|
-
1. ✅ Verify scope context is correct
|
|
341
|
-
2. ✅ Check step type is properly set
|
|
342
|
-
3. ✅ Try resetting context: `jsAutocomplete.resetContext`
|
|
343
|
-
|
|
344
|
-
### Type Info Not Showing
|
|
345
|
-
|
|
346
|
-
1. ✅ Ensure `enableHoverInfo: true`
|
|
347
|
-
2. ✅ Check hover provider is registered
|
|
348
|
-
3. ✅ Test `getTypeInfo` command manually
|
|
349
|
-
|
|
350
|
-
## Performance
|
|
351
|
-
|
|
352
|
-
- **Lazy Loading**: Type definitions loaded on-demand
|
|
353
|
-
- **Caching**: Tern.js caches type information
|
|
354
|
-
- **Incremental**: Updates as code changes
|
|
355
|
-
- **Worker-Based**: Runs in separate thread
|
|
356
|
-
|
|
357
|
-
## Future Enhancements
|
|
358
|
-
|
|
359
|
-
- [ ] Signature help for function parameters
|
|
360
|
-
- [ ] Definition provider (Go to Definition)
|
|
361
|
-
- [ ] References provider (Find All References)
|
|
362
|
-
- [ ] Rename provider
|
|
363
|
-
- [ ] Code actions (quick fixes)
|
|
364
|
-
- [ ] Import statement generation
|
|
365
|
-
- [ ] JSDoc parsing and display
|
|
366
|
-
- [ ] Multi-step context awareness
|
|
367
|
-
|
|
368
|
-
## Benefits
|
|
369
|
-
|
|
370
|
-
✅ **Intelligent Completions** - Context-aware suggestions using Tern.js
|
|
371
|
-
✅ **Type Information** - Hover to see types and documentation
|
|
372
|
-
✅ **Library Support** - Completions for installed libraries
|
|
373
|
-
✅ **Step-Specific** - Tailored completions for each step type
|
|
374
|
-
✅ **Works with Existing Code** - Integrates with your snippets
|
|
375
|
-
✅ **Command Pattern** - Uses your existing command execution
|
|
376
|
-
✅ **Performance** - Worker-based, doesn't block UI
|
|
377
|
-
|
|
378
|
-
## License
|
|
379
|
-
|
|
380
|
-
MIT
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-use-before-define */
|
|
2
|
-
import type {
|
|
3
|
-
InngestFunctionDef,
|
|
4
|
-
InngestStep,
|
|
5
|
-
ExtractedFunction,
|
|
6
|
-
StepFunction,
|
|
7
|
-
GeneratedFunctionResult,
|
|
8
|
-
} from './interfaces/types';
|
|
9
|
-
import {
|
|
10
|
-
cleanStepCode,
|
|
11
|
-
extractStepVarName,
|
|
12
|
-
generateFromExtractedFunctions,
|
|
13
|
-
extractFunctionBody,
|
|
14
|
-
} from './stepGenerator';
|
|
15
|
-
|
|
16
|
-
// Re-export utilities for backward compatibility
|
|
17
|
-
export { cleanStepCode, extractStepVarName } from './stepGenerator';
|
|
18
|
-
|
|
19
|
-
// Check if code contains direct step operations (sleep, sendEvent, etc)
|
|
20
|
-
function hasDirectStepOperations(code: string): boolean {
|
|
21
|
-
return /step\.(sleep|sendEvent|waitForEvent|run)\s*\(/.test(code);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function getDefaultDirectBody(type: string, id: string, label?: string): string {
|
|
25
|
-
switch (type) {
|
|
26
|
-
case 'sleep':
|
|
27
|
-
return `const ${id}_result = await step.sleep('${id}', '5s');`;
|
|
28
|
-
case 'sendEvent':
|
|
29
|
-
return `const ${id}_result = await step.sendEvent('${id}', { name: 'my.custom.event', data: { source: '${
|
|
30
|
-
label || id
|
|
31
|
-
}', ts: new Date().toISOString() } });`;
|
|
32
|
-
case 'waitForEvent':
|
|
33
|
-
return `const ${id}_result = await step.waitForEvent('${id}', { event: 'my.waited.event', timeout: '60s' });`;
|
|
34
|
-
default:
|
|
35
|
-
return `// not supported`;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function indent(s: string, spaces: number): string {
|
|
40
|
-
const pad = ' '.repeat(spaces);
|
|
41
|
-
return s
|
|
42
|
-
.split('\n')
|
|
43
|
-
.map((l) => (l ? pad + l : l))
|
|
44
|
-
.join('\n');
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Simple code formatter
|
|
48
|
-
function formatCode(code: string): string {
|
|
49
|
-
// Basic formatting - in production, you'd use a proper formatter
|
|
50
|
-
return code
|
|
51
|
-
.split('\n')
|
|
52
|
-
.map((line) => line.trimEnd())
|
|
53
|
-
.join('\n')
|
|
54
|
-
.replace(/\n{3,}/g, '\n\n'); // Remove excessive blank lines
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function generateStepBlock(step: InngestStep, position: number): string {
|
|
58
|
-
const stepVar = (step.code || '').match(/const\s+(\w+)\s*=/)?.[1] || `step_${position}`;
|
|
59
|
-
|
|
60
|
-
// If caller supplied code, embed it inside step.run wrapper by default for consistency
|
|
61
|
-
if (step.type === 'sleep' || step.type === 'sendEvent' || step.type === 'waitForEvent') {
|
|
62
|
-
// Execute directly (these typically call step.* helpers)
|
|
63
|
-
const body = extractFunctionBody(step.code || '') || getDefaultDirectBody(step.type, stepVar, step.name);
|
|
64
|
-
return `// ${step.description || step.name || `Step ${position}`}
|
|
65
|
-
${body}`;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const inner = extractFunctionBody(step.code || '') || 'return { success: true };';
|
|
69
|
-
return `// ${step.description || step.name || `Step ${position}`}
|
|
70
|
-
const ${stepVar}_result = await step.run('${stepVar}', async (event, step) => {
|
|
71
|
-
${indent(inner, 2)}
|
|
72
|
-
});`;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Minimal shared generator. Replace internals by moving editor logic here incrementally.
|
|
76
|
-
export function generateFunctionCode(def: InngestFunctionDef): string {
|
|
77
|
-
const eventsString = def.events.length > 0 ? def.events.map((e) => `'${e}'`).join(', ') : `'app.event'`;
|
|
78
|
-
const safeId = def.id.replace(/[^a-zA-Z0-9]/g, '') || 'function';
|
|
79
|
-
const body = generateHandlerBody(def);
|
|
80
|
-
return `const ${safeId}Function = inngest.createFunction(
|
|
81
|
-
{ id: '${def.id}' },
|
|
82
|
-
{ event: [${eventsString}] },
|
|
83
|
-
async ({ event, step }) => {
|
|
84
|
-
${indent(body, 4)}
|
|
85
|
-
}
|
|
86
|
-
);`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// New: return only the handler body that backend executes and editor displays
|
|
90
|
-
export function generateHandlerBody(def: InngestFunctionDef): string {
|
|
91
|
-
const stepBlocks = def.steps.map((step, index) => generateStepBlock(step, index + 1)).join('\n');
|
|
92
|
-
// Footer removed: callers should append their own consolidated return as needed
|
|
93
|
-
return `${stepBlocks}`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Generate Inngest function from database-extracted functions
|
|
97
|
-
export function generateStepFunctionsFromDB(
|
|
98
|
-
functionId: string,
|
|
99
|
-
events: string[],
|
|
100
|
-
extractedFunctions: ExtractedFunction[],
|
|
101
|
-
): GeneratedFunctionResult {
|
|
102
|
-
if (!extractedFunctions || extractedFunctions.length === 0) {
|
|
103
|
-
throw new Error('No functions provided to generate');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Use the new unified generator
|
|
107
|
-
const code = generateFromExtractedFunctions(extractedFunctions);
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
code: formatCode(code),
|
|
111
|
-
functionId,
|
|
112
|
-
stepCount: extractedFunctions.length,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Wrap multiple step functions in a single Inngest function
|
|
117
|
-
export function wrapStepsInInngestFunction(functionDef: InngestFunctionDef, stepFunctions: StepFunction[]): string {
|
|
118
|
-
const extractedFunctions: ExtractedFunction[] = stepFunctions.map((sf) => ({
|
|
119
|
-
id: sf.id,
|
|
120
|
-
name: sf.name,
|
|
121
|
-
code: sf.code,
|
|
122
|
-
description: sf.description,
|
|
123
|
-
}));
|
|
124
|
-
|
|
125
|
-
const result = generateStepFunctionsFromDB(functionDef.id, functionDef.events, extractedFunctions);
|
|
126
|
-
|
|
127
|
-
return result.code;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Generate a single step from an extracted function
|
|
131
|
-
export function generateStepFromFunction(stepFunction: StepFunction, index: number): string {
|
|
132
|
-
const stepVar = extractStepVarName(stepFunction.code) || `step_${index}`;
|
|
133
|
-
const functionBody = extractFunctionBody(stepFunction.code);
|
|
134
|
-
|
|
135
|
-
if (!functionBody) {
|
|
136
|
-
return `// ${
|
|
137
|
-
stepFunction.name || `Step ${index}`
|
|
138
|
-
}\nconst ${stepVar}_result = { success: false, error: 'Invalid function format' };`;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const hasDirectOps = hasDirectStepOperations(stepFunction.code);
|
|
142
|
-
const cleanedBody = cleanStepCode(functionBody);
|
|
143
|
-
|
|
144
|
-
if (hasDirectOps) {
|
|
145
|
-
return `// ${stepFunction.name || `Step ${index}`}\n${cleanedBody}`;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return `// ${
|
|
149
|
-
stepFunction.name || `Step ${index}`
|
|
150
|
-
}\nconst ${stepVar}_result = await step.run('${stepVar}', async (event, step) => {\n${indent(cleanedBody, 2)}\n});`;
|
|
151
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './types';
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export type InngestStepType =
|
|
2
|
-
| 'run'
|
|
3
|
-
| 'sleep'
|
|
4
|
-
| 'sendEvent'
|
|
5
|
-
| 'waitForEvent'
|
|
6
|
-
| 'retrieveData'
|
|
7
|
-
| 'parallel'
|
|
8
|
-
| 'validateForm';
|
|
9
|
-
|
|
10
|
-
export interface InngestStep {
|
|
11
|
-
id: string;
|
|
12
|
-
name: string;
|
|
13
|
-
type: InngestStepType;
|
|
14
|
-
code?: string;
|
|
15
|
-
description?: string;
|
|
16
|
-
// Loose optional fields to avoid coupling; extend in callers as needed
|
|
17
|
-
[key: string]: unknown;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface InngestFunctionDef {
|
|
21
|
-
id: string;
|
|
22
|
-
name: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
events: string[];
|
|
25
|
-
steps: InngestStep[];
|
|
26
|
-
concurrency?: number;
|
|
27
|
-
retries?: number;
|
|
28
|
-
timeout?: string | number;
|
|
29
|
-
// Extra passthrough metadata
|
|
30
|
-
[key: string]: unknown;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// New interfaces for database-extracted functions
|
|
34
|
-
export interface ExtractedFunction {
|
|
35
|
-
id: string;
|
|
36
|
-
name: string;
|
|
37
|
-
code?: string; // The complete async function code
|
|
38
|
-
extensionId?: string;
|
|
39
|
-
extensionName?: string;
|
|
40
|
-
generatedCode?: string;
|
|
41
|
-
steps?: StepDefinition[];
|
|
42
|
-
originalStepName?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface StepFunction {
|
|
46
|
-
id: string;
|
|
47
|
-
name: string;
|
|
48
|
-
code: string;
|
|
49
|
-
type?: InngestStepType;
|
|
50
|
-
description?: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface StepDefinition {
|
|
54
|
-
id: string;
|
|
55
|
-
name: string;
|
|
56
|
-
code: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface GeneratedFunctionResult {
|
|
60
|
-
code: string;
|
|
61
|
-
functionId: string;
|
|
62
|
-
stepCount: number;
|
|
63
|
-
}
|