@bubblelab/shared-schemas 0.1.4 → 0.1.6
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 +2 -2
- package/dist/bubble-definition-schema.d.ts +2 -2
- package/dist/bubbleflow-execution-schema.d.ts +4 -4
- package/dist/bubbleflow-schema.d.ts +12 -12
- package/dist/generate-bubbleflow-schema.d.ts +4 -4
- package/dist/mock-data-generator.d.ts.map +1 -1
- package/dist/mock-data-generator.js +11 -1
- package/dist/mock-data-generator.js.map +1 -1
- package/package.json +1 -1
- package/dist/prompts.d.ts +0 -12
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -40
- package/dist/prompts.js.map +0 -1
- package/dist/routes.d.ts +0 -2207
- package/dist/routes.d.ts.map +0 -1
- package/dist/routes.js +0 -978
- package/dist/routes.js.map +0 -1
package/dist/routes.js
DELETED
|
@@ -1,978 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @bubblelab/shared-schemas - API Schema Definitions
|
|
3
|
-
*
|
|
4
|
-
* This file contains all Zod schemas and TypeScript types for the NodeX API.
|
|
5
|
-
*
|
|
6
|
-
* IMPORTANT: All new API schemas should be written in this shared package to ensure
|
|
7
|
-
* type safety and consistency between frontend and backend applications.
|
|
8
|
-
*
|
|
9
|
-
* ## Schema Organization
|
|
10
|
-
*
|
|
11
|
-
* ### Request Schemas (Input Validation)
|
|
12
|
-
* - createBubbleFlowSchema - POST /bubble-flow
|
|
13
|
-
* - executeBubbleFlowSchema - POST /:id/execute
|
|
14
|
-
* - createCredentialSchema - POST /credentials
|
|
15
|
-
* - updateBubbleFlowParametersSchema - PUT /bubble-flow/:id
|
|
16
|
-
*
|
|
17
|
-
* ### Response Schemas (Output Types)
|
|
18
|
-
* - createBubbleFlowResponseSchema - POST /bubble-flow response
|
|
19
|
-
* - executeBubbleFlowResponseSchema - POST /:id/execute response
|
|
20
|
-
* - credentialResponseSchema - GET /credentials response
|
|
21
|
-
* - createCredentialResponseSchema - POST /credentials response
|
|
22
|
-
* - bubbleFlowDetailsResponseSchema - GET /bubble-flow/:id response
|
|
23
|
-
* - listBubbleFlowsResponseSchema - GET /bubble-flow response
|
|
24
|
-
* - webhookResponseSchema - POST /webhook/{userId}/{path} response
|
|
25
|
-
* - errorResponseSchema - Error responses
|
|
26
|
-
* - successMessageResponseSchema - Success responses
|
|
27
|
-
*
|
|
28
|
-
* ### TypeScript Types
|
|
29
|
-
* All schemas have corresponding TypeScript types exported for use in both
|
|
30
|
-
* frontend and backend applications.
|
|
31
|
-
*
|
|
32
|
-
* ## Usage Examples
|
|
33
|
-
*
|
|
34
|
-
* ### Backend (Validation)
|
|
35
|
-
* ```typescript
|
|
36
|
-
* import { createBubbleFlowSchema } from '@bubblelab/shared-schemas';
|
|
37
|
-
*
|
|
38
|
-
* // Validate request body
|
|
39
|
-
* const validatedData = createBubbleFlowSchema.parse(requestBody);
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* ### Frontend (Type Safety)
|
|
43
|
-
* ```typescript
|
|
44
|
-
* import type { CreateBubbleFlowRequest, CreateBubbleFlowResponse } from '@bubblelab/shared-schemas';
|
|
45
|
-
*
|
|
46
|
-
* const createBubbleFlow = async (data: CreateBubbleFlowRequest): Promise<CreateBubbleFlowResponse> => {
|
|
47
|
-
* // API call with full type safety
|
|
48
|
-
* };
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* ## Adding New Schemas
|
|
52
|
-
*
|
|
53
|
-
* 1. Define the Zod schema with proper OpenAPI metadata
|
|
54
|
-
* 2. Export the schema for validation
|
|
55
|
-
* 3. Export the TypeScript type using `z.infer<typeof schemaName>`
|
|
56
|
-
* 4. Update this documentation
|
|
57
|
-
* 5. Rebuild the package: `pnpm build:core`
|
|
58
|
-
*/
|
|
59
|
-
import { z } from 'zod';
|
|
60
|
-
import { databaseMetadataSchema } from './database-definition-schema';
|
|
61
|
-
import { CredentialType } from './types';
|
|
62
|
-
import { BubbleParameterType, ParsedBubbleSchema, ParsedBubbleWithInfoSchema, } from './bubble-definition-schema';
|
|
63
|
-
// ============================================================================
|
|
64
|
-
// BUBBLEFLOW PARSING TYPES (Backend/Frontend Shared)
|
|
65
|
-
// ============================================================================
|
|
66
|
-
// ============================================================================
|
|
67
|
-
// REQUEST SCHEMAS (Input Validation)
|
|
68
|
-
// ============================================================================
|
|
69
|
-
// POST /bubble-flow - Create new BubbleFlow schema
|
|
70
|
-
export const createBubbleFlowSchema = z
|
|
71
|
-
.object({
|
|
72
|
-
name: z.string().min(1).max(100).openapi({
|
|
73
|
-
description: 'Name of the BubbleFlow',
|
|
74
|
-
example: 'My First BubbleFlow',
|
|
75
|
-
}),
|
|
76
|
-
description: z.string().optional().openapi({
|
|
77
|
-
description: 'Optional description of what this BubbleFlow does',
|
|
78
|
-
example: 'A flow that processes webhook data',
|
|
79
|
-
}),
|
|
80
|
-
prompt: z.string().optional().openapi({
|
|
81
|
-
description: 'Optional prompt used to generate the flow',
|
|
82
|
-
example: 'Create a flow that processes webhook data and sends notifications',
|
|
83
|
-
}),
|
|
84
|
-
code: z.string().min(1).openapi({
|
|
85
|
-
description: 'TypeScript code that defines the BubbleFlow class',
|
|
86
|
-
example: 'export class MyFlow extends BubbleFlow { ... }',
|
|
87
|
-
}),
|
|
88
|
-
eventType: z.string().min(1).openapi({
|
|
89
|
-
description: 'Event type this BubbleFlow responds to',
|
|
90
|
-
example: 'webhook/http',
|
|
91
|
-
}),
|
|
92
|
-
webhookPath: z
|
|
93
|
-
.string()
|
|
94
|
-
.min(1)
|
|
95
|
-
.max(50)
|
|
96
|
-
.regex(/^[a-zA-Z0-9-_]+$/)
|
|
97
|
-
.optional()
|
|
98
|
-
.openapi({
|
|
99
|
-
description: 'Custom webhook path (auto-generated if not provided)',
|
|
100
|
-
example: 'my-webhook',
|
|
101
|
-
}),
|
|
102
|
-
webhookActive: z.boolean().default(false).optional().openapi({
|
|
103
|
-
description: 'Whether the webhook should be active immediately',
|
|
104
|
-
example: true,
|
|
105
|
-
}),
|
|
106
|
-
})
|
|
107
|
-
.openapi('CreateBubbleFlowRequest');
|
|
108
|
-
// POST /:id/execute - Execute BubbleFlow schema
|
|
109
|
-
export const executeBubbleFlowSchema = z
|
|
110
|
-
.record(z.string(), z.unknown())
|
|
111
|
-
.openapi('ExecuteBubbleFlowRequest');
|
|
112
|
-
// POST /credentials - Create credential schema
|
|
113
|
-
export const createCredentialSchema = z
|
|
114
|
-
.object({
|
|
115
|
-
credentialType: z.nativeEnum(CredentialType).openapi({
|
|
116
|
-
description: 'Type of credential to store',
|
|
117
|
-
example: CredentialType.OPENAI_CRED,
|
|
118
|
-
}),
|
|
119
|
-
value: z.string().min(1).openapi({
|
|
120
|
-
description: 'The credential value (will be encrypted)',
|
|
121
|
-
example: 'sk-1234567890abcdef',
|
|
122
|
-
}),
|
|
123
|
-
name: z.string().optional().openapi({
|
|
124
|
-
description: 'Optional user-friendly name for the credential',
|
|
125
|
-
example: 'My OpenAI Key',
|
|
126
|
-
}),
|
|
127
|
-
skipValidation: z.boolean().optional().openapi({
|
|
128
|
-
description: 'Skip credential validation before storing (for testing/admin use)',
|
|
129
|
-
example: false,
|
|
130
|
-
}),
|
|
131
|
-
credentialConfigurations: z
|
|
132
|
-
.record(z.string(), z.unknown())
|
|
133
|
-
.optional()
|
|
134
|
-
.openapi({
|
|
135
|
-
description: 'Optional configurations for credential validation (e.g., ignoreSSL for PostgreSQL)',
|
|
136
|
-
example: { ignoreSSL: true },
|
|
137
|
-
}),
|
|
138
|
-
metadata: databaseMetadataSchema.optional().openapi({
|
|
139
|
-
description: 'Optional metadata for the credential (e.g., database schema for DATABASE_CRED)',
|
|
140
|
-
example: {
|
|
141
|
-
tables: {
|
|
142
|
-
users: {
|
|
143
|
-
id: 'integer',
|
|
144
|
-
email: 'character varying',
|
|
145
|
-
created_at: 'timestamp with time zone',
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
rules: [
|
|
149
|
-
{
|
|
150
|
-
id: 'rule-1',
|
|
151
|
-
text: 'No direct DELETE on users table',
|
|
152
|
-
enabled: true,
|
|
153
|
-
createdAt: '2024-01-01T00:00:00Z',
|
|
154
|
-
updatedAt: '2024-01-01T00:00:00Z',
|
|
155
|
-
},
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
}),
|
|
159
|
-
})
|
|
160
|
-
.openapi('CreateCredentialRequest');
|
|
161
|
-
// PUT /credentials/:id - Update credential schema
|
|
162
|
-
export const updateCredentialSchema = z
|
|
163
|
-
.object({
|
|
164
|
-
value: z.string().optional().openapi({
|
|
165
|
-
description: 'The credential value (will be encrypted). Leave empty to keep current value.',
|
|
166
|
-
example: 'sk-1234567890abcdef',
|
|
167
|
-
}),
|
|
168
|
-
name: z.string().optional().openapi({
|
|
169
|
-
description: 'Optional user-friendly name for the credential',
|
|
170
|
-
example: 'My OpenAI Key',
|
|
171
|
-
}),
|
|
172
|
-
skipValidation: z.boolean().optional().openapi({
|
|
173
|
-
description: 'Skip credential validation before storing (for testing/admin use)',
|
|
174
|
-
example: false,
|
|
175
|
-
}),
|
|
176
|
-
credentialConfigurations: z
|
|
177
|
-
.record(z.string(), z.unknown())
|
|
178
|
-
.optional()
|
|
179
|
-
.openapi({
|
|
180
|
-
description: 'Optional configurations for credential validation (e.g., ignoreSSL for PostgreSQL)',
|
|
181
|
-
example: { ignoreSSL: true },
|
|
182
|
-
}),
|
|
183
|
-
metadata: databaseMetadataSchema.optional().openapi({
|
|
184
|
-
description: 'Optional metadata for the credential (e.g., database schema for DATABASE_CRED)',
|
|
185
|
-
example: {
|
|
186
|
-
tables: {
|
|
187
|
-
users: {
|
|
188
|
-
id: 'integer',
|
|
189
|
-
email: 'character varying',
|
|
190
|
-
created_at: 'timestamp with time zone',
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
}),
|
|
195
|
-
})
|
|
196
|
-
.openapi('UpdateCredentialRequest');
|
|
197
|
-
// PUT /bubble-flow/:id - Update BubbleFlow parameters schema
|
|
198
|
-
export const updateBubbleFlowParametersSchema = z
|
|
199
|
-
.object({
|
|
200
|
-
bubbleParameters: z.record(z.string(), z.union([ParsedBubbleWithInfoSchema, ParsedBubbleSchema])),
|
|
201
|
-
})
|
|
202
|
-
.openapi('UpdateBubbleFlowParametersRequest');
|
|
203
|
-
// ============================================================================
|
|
204
|
-
// RESPONSE SCHEMAS (Output Types)
|
|
205
|
-
// ============================================================================
|
|
206
|
-
// POST /bubble-flow - Create BubbleFlow response
|
|
207
|
-
export const createBubbleFlowResponseSchema = z
|
|
208
|
-
.object({
|
|
209
|
-
id: z.number().openapi({
|
|
210
|
-
description: 'ID of the created BubbleFlow',
|
|
211
|
-
example: 123,
|
|
212
|
-
}),
|
|
213
|
-
message: z.string().openapi({
|
|
214
|
-
description: 'Success message',
|
|
215
|
-
example: 'BubbleFlow created successfully',
|
|
216
|
-
}),
|
|
217
|
-
inputSchema: z
|
|
218
|
-
.record(z.string(), z.unknown())
|
|
219
|
-
.optional()
|
|
220
|
-
.openapi({
|
|
221
|
-
description: 'Input schema',
|
|
222
|
-
example: {
|
|
223
|
-
name: 'string',
|
|
224
|
-
age: 'number',
|
|
225
|
-
},
|
|
226
|
-
}),
|
|
227
|
-
bubbleParameters: z.record(z.string(), ParsedBubbleWithInfoSchema).openapi({
|
|
228
|
-
description: 'Parsed bubble parameters from the BubbleFlow code',
|
|
229
|
-
}),
|
|
230
|
-
requiredCredentials: z
|
|
231
|
-
.record(z.string(), z.array(z.nativeEnum(CredentialType)))
|
|
232
|
-
.optional()
|
|
233
|
-
.openapi({
|
|
234
|
-
description: 'Mapping of bubble names to their required credential types',
|
|
235
|
-
example: {
|
|
236
|
-
'database-connection': [CredentialType.DATABASE_CRED],
|
|
237
|
-
'slack-notification': [CredentialType.SLACK_CRED],
|
|
238
|
-
'ai-analysis': [CredentialType.GOOGLE_GEMINI_CRED],
|
|
239
|
-
},
|
|
240
|
-
}),
|
|
241
|
-
webhook: z
|
|
242
|
-
.object({
|
|
243
|
-
id: z.number().openapi({ description: 'Webhook ID', example: 456 }),
|
|
244
|
-
url: z.string().openapi({
|
|
245
|
-
description: 'Full webhook URL',
|
|
246
|
-
example: 'http://localhost:3001/webhook/user123/my-webhook',
|
|
247
|
-
}),
|
|
248
|
-
path: z.string().openapi({
|
|
249
|
-
description: 'Webhook path',
|
|
250
|
-
example: 'my-webhook',
|
|
251
|
-
}),
|
|
252
|
-
active: z.boolean().openapi({
|
|
253
|
-
description: 'Whether webhook is active',
|
|
254
|
-
example: true,
|
|
255
|
-
}),
|
|
256
|
-
})
|
|
257
|
-
.optional()
|
|
258
|
-
.openapi({
|
|
259
|
-
description: 'Webhook information (if webhook was created)',
|
|
260
|
-
}),
|
|
261
|
-
})
|
|
262
|
-
.openapi('CreateBubbleFlowResponse');
|
|
263
|
-
// POST /:id/execute - Execute BubbleFlow response
|
|
264
|
-
export const executeBubbleFlowResponseSchema = z
|
|
265
|
-
.object({
|
|
266
|
-
executionId: z.number().openapi({
|
|
267
|
-
description: 'ID of the execution record',
|
|
268
|
-
example: 789,
|
|
269
|
-
}),
|
|
270
|
-
success: z.boolean().openapi({
|
|
271
|
-
description: 'Whether the execution was successful',
|
|
272
|
-
example: true,
|
|
273
|
-
}),
|
|
274
|
-
data: z
|
|
275
|
-
.any()
|
|
276
|
-
.optional()
|
|
277
|
-
.openapi({
|
|
278
|
-
description: 'Data returned by the BubbleFlow (if successful)',
|
|
279
|
-
example: { result: 'processed successfully', count: 42 },
|
|
280
|
-
}),
|
|
281
|
-
error: z.string().optional().openapi({
|
|
282
|
-
description: 'Error message (if execution failed)',
|
|
283
|
-
example: 'Validation error in BubbleFlow',
|
|
284
|
-
}),
|
|
285
|
-
})
|
|
286
|
-
.openapi('ExecuteBubbleFlowResponse');
|
|
287
|
-
// GET /credentials - List credentials response
|
|
288
|
-
export const credentialResponseSchema = z
|
|
289
|
-
.object({
|
|
290
|
-
id: z.number().openapi({ description: 'Credential ID' }),
|
|
291
|
-
credentialType: z.string().openapi({ description: 'Type of credential' }),
|
|
292
|
-
name: z.string().optional().openapi({ description: 'Credential name' }),
|
|
293
|
-
metadata: databaseMetadataSchema
|
|
294
|
-
.optional()
|
|
295
|
-
.openapi({ description: 'Credential metadata' }),
|
|
296
|
-
createdAt: z.string().openapi({ description: 'Creation timestamp' }),
|
|
297
|
-
// OAuth-specific fields
|
|
298
|
-
isOauth: z
|
|
299
|
-
.boolean()
|
|
300
|
-
.optional()
|
|
301
|
-
.openapi({ description: 'Whether this is an OAuth credential' }),
|
|
302
|
-
oauthProvider: z
|
|
303
|
-
.string()
|
|
304
|
-
.optional()
|
|
305
|
-
.openapi({ description: 'OAuth provider name' }),
|
|
306
|
-
oauthExpiresAt: z
|
|
307
|
-
.string()
|
|
308
|
-
.optional()
|
|
309
|
-
.openapi({ description: 'OAuth token expiration timestamp' }),
|
|
310
|
-
oauthScopes: z
|
|
311
|
-
.array(z.string())
|
|
312
|
-
.optional()
|
|
313
|
-
.openapi({ description: 'OAuth scopes granted' }),
|
|
314
|
-
oauthStatus: z
|
|
315
|
-
.enum(['active', 'expired', 'needs_refresh'])
|
|
316
|
-
.optional()
|
|
317
|
-
.openapi({ description: 'OAuth token status' }),
|
|
318
|
-
})
|
|
319
|
-
.openapi('CredentialResponse');
|
|
320
|
-
// POST /credentials - Create credential response
|
|
321
|
-
export const createCredentialResponseSchema = z
|
|
322
|
-
.object({
|
|
323
|
-
id: z.number().openapi({ description: 'Credential ID' }),
|
|
324
|
-
message: z.string().openapi({ description: 'Success message' }),
|
|
325
|
-
})
|
|
326
|
-
.openapi('CreateCredentialResponse');
|
|
327
|
-
// PUT /credentials/:id - Update credential response
|
|
328
|
-
export const updateCredentialResponseSchema = z
|
|
329
|
-
.object({
|
|
330
|
-
id: z.number().openapi({ description: 'Credential ID' }),
|
|
331
|
-
message: z.string().openapi({ description: 'Success message' }),
|
|
332
|
-
})
|
|
333
|
-
.openapi('UpdateCredentialResponse');
|
|
334
|
-
// General success message response (used by DELETE /credentials/:id, DELETE /bubble-flow/:id, PUT /bubble-flow/:id)
|
|
335
|
-
export const successMessageResponseSchema = z
|
|
336
|
-
.object({
|
|
337
|
-
message: z.string().openapi({ description: 'Success message' }),
|
|
338
|
-
})
|
|
339
|
-
.openapi('SuccessMessageResponse');
|
|
340
|
-
// GET /bubble-flow/:id - Get BubbleFlow details response
|
|
341
|
-
export const bubbleFlowDetailsResponseSchema = z
|
|
342
|
-
.object({
|
|
343
|
-
id: z.number().openapi({ description: 'BubbleFlow ID' }),
|
|
344
|
-
name: z.string().openapi({ description: 'BubbleFlow name' }),
|
|
345
|
-
description: z.string().optional().openapi({ description: 'Description' }),
|
|
346
|
-
prompt: z
|
|
347
|
-
.string()
|
|
348
|
-
.optional()
|
|
349
|
-
.openapi({ description: 'Original prompt used to generate the flow' }),
|
|
350
|
-
eventType: z.string().openapi({ description: 'Event type' }),
|
|
351
|
-
code: z.string().openapi({ description: 'TypeScript source code' }),
|
|
352
|
-
inputSchema: z
|
|
353
|
-
.record(z.string(), z.unknown())
|
|
354
|
-
.optional()
|
|
355
|
-
.openapi({ description: 'Input schema' }),
|
|
356
|
-
isActive: z
|
|
357
|
-
.boolean()
|
|
358
|
-
.openapi({ description: 'Whether the BubbleFlow is active' }),
|
|
359
|
-
requiredCredentials: z
|
|
360
|
-
.record(z.string(), z.array(z.nativeEnum(CredentialType)))
|
|
361
|
-
.openapi({ description: 'Required credentials by bubble' }),
|
|
362
|
-
displayedBubbleParameters: z
|
|
363
|
-
.record(z.string(), z.object({
|
|
364
|
-
variableName: z.string(),
|
|
365
|
-
bubbleName: z.string(),
|
|
366
|
-
className: z.string(),
|
|
367
|
-
parameters: z.array(z.object({
|
|
368
|
-
name: z.string(),
|
|
369
|
-
value: z.unknown(),
|
|
370
|
-
type: z.nativeEnum(BubbleParameterType),
|
|
371
|
-
})),
|
|
372
|
-
hasAwait: z.boolean(),
|
|
373
|
-
hasActionCall: z.boolean(),
|
|
374
|
-
}))
|
|
375
|
-
.optional()
|
|
376
|
-
.openapi({
|
|
377
|
-
description: 'Displayed bubble parameters for visualization',
|
|
378
|
-
}),
|
|
379
|
-
bubbleParameters: z.record(z.string(), ParsedBubbleWithInfoSchema).openapi({
|
|
380
|
-
description: 'Bubble parameters',
|
|
381
|
-
}),
|
|
382
|
-
createdAt: z.string().openapi({ description: 'Creation timestamp' }),
|
|
383
|
-
updatedAt: z.string().openapi({ description: 'Update timestamp' }),
|
|
384
|
-
webhook_url: z
|
|
385
|
-
.string()
|
|
386
|
-
.openapi({ description: 'Webhook URL for this bubble flow' }),
|
|
387
|
-
})
|
|
388
|
-
.openapi('BubbleFlowDetailsResponse');
|
|
389
|
-
// Webhook execution response (used internally)
|
|
390
|
-
export const webhookExecutionResponseSchema = z
|
|
391
|
-
.object({
|
|
392
|
-
executionId: z.number().openapi({ description: 'Execution ID' }),
|
|
393
|
-
success: z.boolean().openapi({ description: 'Execution success' }),
|
|
394
|
-
data: z.unknown().optional().openapi({ description: 'Result data' }),
|
|
395
|
-
error: z.string().optional().openapi({ description: 'Error message' }),
|
|
396
|
-
webhook: z
|
|
397
|
-
.object({
|
|
398
|
-
userId: z.string().openapi({ description: 'User ID' }),
|
|
399
|
-
path: z.string().openapi({ description: 'Webhook path' }),
|
|
400
|
-
triggeredAt: z.string().openapi({ description: 'Trigger timestamp' }),
|
|
401
|
-
method: z.string().openapi({ description: 'HTTP method' }),
|
|
402
|
-
})
|
|
403
|
-
.openapi({ description: 'Webhook info' }),
|
|
404
|
-
})
|
|
405
|
-
.openapi('WebhookExecutionResponse');
|
|
406
|
-
// POST /webhook/{userId}/{path} - Webhook response
|
|
407
|
-
export const webhookResponseSchema = z
|
|
408
|
-
.object({
|
|
409
|
-
// Slack verification fields
|
|
410
|
-
challenge: z
|
|
411
|
-
.string()
|
|
412
|
-
.optional()
|
|
413
|
-
.openapi({ description: 'Slack URL verification challenge' }),
|
|
414
|
-
// Execution fields
|
|
415
|
-
executionId: z.number().optional().openapi({ description: 'Execution ID' }),
|
|
416
|
-
success: z
|
|
417
|
-
.boolean()
|
|
418
|
-
.optional()
|
|
419
|
-
.openapi({ description: 'Execution success' }),
|
|
420
|
-
data: z
|
|
421
|
-
.record(z.string(), z.unknown())
|
|
422
|
-
.or(z.undefined())
|
|
423
|
-
.optional()
|
|
424
|
-
.openapi({ description: 'Result data' }),
|
|
425
|
-
error: z.string().optional().openapi({ description: 'Error message' }),
|
|
426
|
-
webhook: z
|
|
427
|
-
.object({
|
|
428
|
-
userId: z.string().openapi({ description: 'User ID' }),
|
|
429
|
-
path: z.string().openapi({ description: 'Webhook path' }),
|
|
430
|
-
triggeredAt: z.string().openapi({ description: 'Trigger timestamp' }),
|
|
431
|
-
method: z.string().openapi({ description: 'HTTP method' }),
|
|
432
|
-
})
|
|
433
|
-
.optional()
|
|
434
|
-
.openapi({ description: 'Webhook info' }),
|
|
435
|
-
})
|
|
436
|
-
.openapi('WebhookResponse');
|
|
437
|
-
// Individual BubbleFlow list item schema
|
|
438
|
-
export const bubbleFlowListItemSchema = z.object({
|
|
439
|
-
id: z.number().openapi({ description: 'BubbleFlow ID' }),
|
|
440
|
-
name: z.string().openapi({ description: 'BubbleFlow name' }),
|
|
441
|
-
description: z.string().optional().openapi({ description: 'Description' }),
|
|
442
|
-
eventType: z.string().openapi({ description: 'Event type' }),
|
|
443
|
-
isActive: z
|
|
444
|
-
.boolean()
|
|
445
|
-
.openapi({ description: 'Whether the BubbleFlow is active' }),
|
|
446
|
-
webhookExecutionCount: z
|
|
447
|
-
.number()
|
|
448
|
-
.openapi({ description: 'Webhook execution count' }),
|
|
449
|
-
webhookFailureCount: z
|
|
450
|
-
.number()
|
|
451
|
-
.openapi({ description: 'Webhook failure count' }),
|
|
452
|
-
createdAt: z.string().openapi({ description: 'Creation timestamp' }),
|
|
453
|
-
updatedAt: z.string().openapi({ description: 'Update timestamp' }),
|
|
454
|
-
});
|
|
455
|
-
// GET /bubble-flow - List BubbleFlows response with user info
|
|
456
|
-
export const bubbleFlowListResponseSchema = z.object({
|
|
457
|
-
bubbleFlows: z.array(bubbleFlowListItemSchema).default([]),
|
|
458
|
-
userMonthlyUsage: z
|
|
459
|
-
.object({
|
|
460
|
-
count: z.number().openapi({ description: 'Current monthly usage count' }),
|
|
461
|
-
})
|
|
462
|
-
.openapi({ description: 'User monthly usage information' }),
|
|
463
|
-
});
|
|
464
|
-
// Validation schemas
|
|
465
|
-
export const validateBubbleFlowCodeSchema = z.object({
|
|
466
|
-
code: z.string().min(1).openapi({
|
|
467
|
-
description: 'TypeScript BubbleFlow code to validate',
|
|
468
|
-
example: 'export class TestFlow extends BubbleFlow<"webhook/http"> { async handle() { return {}; } }',
|
|
469
|
-
}),
|
|
470
|
-
options: z
|
|
471
|
-
.object({
|
|
472
|
-
includeDetails: z.boolean().default(true).openapi({
|
|
473
|
-
description: 'Include detailed bubble analysis',
|
|
474
|
-
}),
|
|
475
|
-
strictMode: z.boolean().default(true).openapi({
|
|
476
|
-
description: 'Enable strict TypeScript validation',
|
|
477
|
-
}),
|
|
478
|
-
})
|
|
479
|
-
.optional()
|
|
480
|
-
.openapi({
|
|
481
|
-
description: 'Validation options',
|
|
482
|
-
}),
|
|
483
|
-
flowId: z.number().positive().optional().openapi({
|
|
484
|
-
description: 'Optional BubbleFlow ID to update with validation results if user owns the flow',
|
|
485
|
-
example: 123,
|
|
486
|
-
}),
|
|
487
|
-
credentials: z
|
|
488
|
-
.record(z.string(), z.record(z.string(), z.number()))
|
|
489
|
-
.optional()
|
|
490
|
-
.openapi({
|
|
491
|
-
description: 'Optional credentials mapping: bubble name -> credential type -> credential ID',
|
|
492
|
-
example: {
|
|
493
|
-
'slack-sender': {
|
|
494
|
-
SLACK_CRED: 123,
|
|
495
|
-
},
|
|
496
|
-
'ai-agent': {
|
|
497
|
-
OPENAI_CRED: 456,
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
}),
|
|
501
|
-
});
|
|
502
|
-
export const validateBubbleFlowCodeResponseSchema = z.object({
|
|
503
|
-
valid: z.boolean().openapi({
|
|
504
|
-
description: 'Whether the code is valid',
|
|
505
|
-
}),
|
|
506
|
-
errors: z.array(z.string()).optional().openapi({
|
|
507
|
-
description: 'List of validation errors if any',
|
|
508
|
-
}),
|
|
509
|
-
bubbleCount: z.number().optional().openapi({
|
|
510
|
-
description: 'Number of bubbles found in the code',
|
|
511
|
-
}),
|
|
512
|
-
inputSchema: z.record(z.string(), z.unknown()).openapi({
|
|
513
|
-
description: 'Input schema',
|
|
514
|
-
example: {
|
|
515
|
-
name: 'string',
|
|
516
|
-
age: 'number',
|
|
517
|
-
},
|
|
518
|
-
}),
|
|
519
|
-
bubbles: z.record(z.string(), ParsedBubbleWithInfoSchema).optional().openapi({
|
|
520
|
-
description: 'Record mapping bubble IDs to their detailed information',
|
|
521
|
-
}),
|
|
522
|
-
requiredCredentials: z
|
|
523
|
-
.record(z.string(), z.array(z.string()))
|
|
524
|
-
.optional()
|
|
525
|
-
.openapi({
|
|
526
|
-
description: 'Required credentials for the bubbles in the code',
|
|
527
|
-
}),
|
|
528
|
-
metadata: z
|
|
529
|
-
.object({
|
|
530
|
-
validatedAt: z.string().openapi({
|
|
531
|
-
description: 'Timestamp when validation was performed',
|
|
532
|
-
}),
|
|
533
|
-
codeLength: z.number().openapi({
|
|
534
|
-
description: 'Length of the code in characters',
|
|
535
|
-
}),
|
|
536
|
-
strictMode: z.boolean().openapi({
|
|
537
|
-
description: 'Whether strict mode was used',
|
|
538
|
-
}),
|
|
539
|
-
flowUpdated: z.boolean().optional().openapi({
|
|
540
|
-
description: 'Whether the BubbleFlow was updated with validation results',
|
|
541
|
-
}),
|
|
542
|
-
})
|
|
543
|
-
.openapi({
|
|
544
|
-
description: 'Validation metadata',
|
|
545
|
-
}),
|
|
546
|
-
success: z.boolean(),
|
|
547
|
-
error: z.string(),
|
|
548
|
-
});
|
|
549
|
-
// BubbleFlow generation schemas
|
|
550
|
-
export const generateBubbleFlowCodeSchema = z.object({
|
|
551
|
-
prompt: z.string().min(1).openapi({
|
|
552
|
-
description: 'Natural language description of the desired BubbleFlow',
|
|
553
|
-
example: 'Create a flow that queries my database and sends results to Slack',
|
|
554
|
-
}),
|
|
555
|
-
});
|
|
556
|
-
export const generateBubbleFlowCodeResponseSchema = z.object({
|
|
557
|
-
generatedCode: z.string().openapi({
|
|
558
|
-
description: 'The generated BubbleFlow TypeScript code',
|
|
559
|
-
}),
|
|
560
|
-
isValid: z.boolean().openapi({
|
|
561
|
-
description: 'Whether the generated code is valid',
|
|
562
|
-
}),
|
|
563
|
-
success: z.boolean(),
|
|
564
|
-
error: z.string(),
|
|
565
|
-
bubbleParameters: z.record(z.string(), ParsedBubbleWithInfoSchema).openapi({
|
|
566
|
-
description: 'Parsed bubble parameters from the generated code',
|
|
567
|
-
}),
|
|
568
|
-
requiredCredentials: z.record(z.string(), z.array(z.string())).openapi({
|
|
569
|
-
description: 'Required credentials for the bubbles in the generated code',
|
|
570
|
-
}),
|
|
571
|
-
});
|
|
572
|
-
// General error response (used by all routes)
|
|
573
|
-
export const errorResponseSchema = z
|
|
574
|
-
.object({
|
|
575
|
-
error: z.string().openapi({
|
|
576
|
-
description: 'Error message',
|
|
577
|
-
example: 'Validation failed',
|
|
578
|
-
}),
|
|
579
|
-
details: z.string().optional().openapi({
|
|
580
|
-
description: 'Additional error details',
|
|
581
|
-
example: 'Invalid field: name is required',
|
|
582
|
-
}),
|
|
583
|
-
})
|
|
584
|
-
.openapi('ErrorResponse');
|
|
585
|
-
// ============================================================================
|
|
586
|
-
// TYPESCRIPT TYPES (Derived from Schemas)
|
|
587
|
-
// ============================================================================
|
|
588
|
-
// BubbleFlow execution history item schema
|
|
589
|
-
export const bubbleFlowExecutionSchema = z.object({
|
|
590
|
-
id: z.number().openapi({ description: 'Execution ID' }),
|
|
591
|
-
status: z
|
|
592
|
-
.enum(['running', 'success', 'error'])
|
|
593
|
-
.openapi({ description: 'Execution status' }),
|
|
594
|
-
payload: z
|
|
595
|
-
.record(z.string(), z.any())
|
|
596
|
-
.openapi({ description: 'Execution payload' }),
|
|
597
|
-
result: z.any().optional().openapi({ description: 'Execution result data' }),
|
|
598
|
-
error: z
|
|
599
|
-
.string()
|
|
600
|
-
.optional()
|
|
601
|
-
.openapi({ description: 'Error message if failed' }),
|
|
602
|
-
startedAt: z.string().openapi({ description: 'Execution start timestamp' }),
|
|
603
|
-
webhook_url: z.string().openapi({ description: 'Webhook URL' }),
|
|
604
|
-
completedAt: z
|
|
605
|
-
.string()
|
|
606
|
-
.optional()
|
|
607
|
-
.openapi({ description: 'Execution completion timestamp' }),
|
|
608
|
-
});
|
|
609
|
-
// GET /bubble-flow/:id/executions - List BubbleFlow executions response
|
|
610
|
-
export const listBubbleFlowExecutionsResponseSchema = z
|
|
611
|
-
.array(bubbleFlowExecutionSchema)
|
|
612
|
-
.openapi('ListBubbleFlowExecutionsResponse');
|
|
613
|
-
// ============================================================================
|
|
614
|
-
// WEBHOOK SCHEMAS
|
|
615
|
-
// ============================================================================
|
|
616
|
-
// Slack URL verification schema
|
|
617
|
-
export const slackUrlVerificationSchema = z.object({
|
|
618
|
-
token: z.string(),
|
|
619
|
-
challenge: z.string(),
|
|
620
|
-
type: z.literal('url_verification'),
|
|
621
|
-
});
|
|
622
|
-
export const slackUrlVerificationResponseSchema = z
|
|
623
|
-
.object({
|
|
624
|
-
challenge: z
|
|
625
|
-
.string()
|
|
626
|
-
.openapi({ description: 'Slack URL verification challenge' }),
|
|
627
|
-
})
|
|
628
|
-
.openapi('SlackUrlVerificationResponse');
|
|
629
|
-
// POST /bubbleflow-template/data-analyst - Generate template from description
|
|
630
|
-
export const generateBubbleFlowTemplateSchema = z
|
|
631
|
-
.object({
|
|
632
|
-
name: z.string().min(1).max(100).openapi({
|
|
633
|
-
description: 'Name for the workflow',
|
|
634
|
-
example: 'Sam Dix Data Scientist Bot',
|
|
635
|
-
}),
|
|
636
|
-
description: z.string().min(10).max(500).openapi({
|
|
637
|
-
description: 'Description of what the workflow should do',
|
|
638
|
-
example: 'A Slack bot that helps analyze user engagement data and provides insights',
|
|
639
|
-
}),
|
|
640
|
-
roles: z.string().min(10).max(1000).openapi({
|
|
641
|
-
description: "Detailed description of the bot's roles and responsibilities",
|
|
642
|
-
example: 'Be prepared to answer any question on user engagement and come up with proactive insights...',
|
|
643
|
-
}),
|
|
644
|
-
useCase: z.literal('slack-data-scientist').openapi({
|
|
645
|
-
description: 'The specific use case template to generate',
|
|
646
|
-
example: 'slack-data-scientist',
|
|
647
|
-
}),
|
|
648
|
-
// Optional configuration parameters
|
|
649
|
-
verbosity: z.enum(['1', '2', '3', '4', '5']).optional().openapi({
|
|
650
|
-
description: 'Response verbosity level (1=concise, 5=comprehensive)',
|
|
651
|
-
example: '3',
|
|
652
|
-
}),
|
|
653
|
-
technicality: z.enum(['1', '2', '3', '4', '5']).optional().openapi({
|
|
654
|
-
description: 'Technical complexity level (1=plain English, 5=expert)',
|
|
655
|
-
example: '2',
|
|
656
|
-
}),
|
|
657
|
-
includeQuery: z.boolean().optional().openapi({
|
|
658
|
-
description: 'Include the SQL query in the response',
|
|
659
|
-
example: true,
|
|
660
|
-
}),
|
|
661
|
-
includeExplanation: z.boolean().optional().openapi({
|
|
662
|
-
description: 'Include query explanation in the response',
|
|
663
|
-
example: true,
|
|
664
|
-
}),
|
|
665
|
-
maxQueries: z.number().optional().openapi({
|
|
666
|
-
description: 'Maximum number of queries to run',
|
|
667
|
-
example: 10,
|
|
668
|
-
}),
|
|
669
|
-
})
|
|
670
|
-
.openapi('GenerateBubbleFlowTemplateRequest');
|
|
671
|
-
// POST /bubbleflow-template/document-generation - Generate document processing template
|
|
672
|
-
export const generateDocumentGenerationTemplateSchema = z
|
|
673
|
-
.object({
|
|
674
|
-
name: z.string().min(1).max(100).openapi({
|
|
675
|
-
description: 'Name for the document processing workflow',
|
|
676
|
-
example: 'Expense Report Generator',
|
|
677
|
-
}),
|
|
678
|
-
description: z
|
|
679
|
-
.string()
|
|
680
|
-
.max(500)
|
|
681
|
-
.default('Document processing workflow')
|
|
682
|
-
.openapi({
|
|
683
|
-
description: 'Description of what the document processing workflow should do (optional)',
|
|
684
|
-
example: 'Process receipts and invoices to generate structured expense reports',
|
|
685
|
-
}),
|
|
686
|
-
outputDescription: z.string().min(1).max(1000).openapi({
|
|
687
|
-
description: 'Detailed description of the desired output format and data extraction',
|
|
688
|
-
example: 'Extract expense tracking data with vendor name, transaction date, amount, category, and description',
|
|
689
|
-
}),
|
|
690
|
-
// Optional configuration parameters
|
|
691
|
-
outputFormat: z.enum(['html', 'csv', 'json']).optional().openapi({
|
|
692
|
-
description: 'Default output format for generated documents',
|
|
693
|
-
example: 'html',
|
|
694
|
-
}),
|
|
695
|
-
conversionOptions: z
|
|
696
|
-
.object({
|
|
697
|
-
preserveStructure: z.boolean().optional().openapi({
|
|
698
|
-
description: 'Preserve document structure during parsing',
|
|
699
|
-
example: true,
|
|
700
|
-
}),
|
|
701
|
-
includeVisualDescriptions: z.boolean().optional().openapi({
|
|
702
|
-
description: 'Include descriptions of visual elements',
|
|
703
|
-
example: true,
|
|
704
|
-
}),
|
|
705
|
-
extractNumericalData: z.boolean().optional().openapi({
|
|
706
|
-
description: 'Extract and process numerical data',
|
|
707
|
-
example: true,
|
|
708
|
-
}),
|
|
709
|
-
combinePages: z.boolean().optional().openapi({
|
|
710
|
-
description: 'Combine multiple pages into single output',
|
|
711
|
-
example: true,
|
|
712
|
-
}),
|
|
713
|
-
})
|
|
714
|
-
.optional(),
|
|
715
|
-
imageOptions: z
|
|
716
|
-
.object({
|
|
717
|
-
format: z.enum(['png', 'jpg', 'jpeg']).optional().openapi({
|
|
718
|
-
description: 'Image format for document conversion',
|
|
719
|
-
example: 'png',
|
|
720
|
-
}),
|
|
721
|
-
quality: z.number().min(0.1).max(1.0).optional().openapi({
|
|
722
|
-
description: 'Image quality (0.1 to 1.0)',
|
|
723
|
-
example: 0.9,
|
|
724
|
-
}),
|
|
725
|
-
dpi: z.number().min(72).max(300).optional().openapi({
|
|
726
|
-
description: 'Image DPI for conversion',
|
|
727
|
-
example: 200,
|
|
728
|
-
}),
|
|
729
|
-
})
|
|
730
|
-
.optional(),
|
|
731
|
-
aiOptions: z
|
|
732
|
-
.object({
|
|
733
|
-
model: z.string().optional().openapi({
|
|
734
|
-
description: 'AI model to use for processing',
|
|
735
|
-
example: 'google/gemini-2.5-flash',
|
|
736
|
-
}),
|
|
737
|
-
temperature: z.number().min(0).max(2).optional().openapi({
|
|
738
|
-
description: 'AI model temperature (0 to 2)',
|
|
739
|
-
example: 0.2,
|
|
740
|
-
}),
|
|
741
|
-
maxTokens: z.number().min(1000).max(200000).optional().openapi({
|
|
742
|
-
description: 'Maximum tokens for AI processing',
|
|
743
|
-
example: 90000,
|
|
744
|
-
}),
|
|
745
|
-
jsonMode: z.boolean().optional().openapi({
|
|
746
|
-
description: 'Enable JSON mode for structured output',
|
|
747
|
-
example: false,
|
|
748
|
-
}),
|
|
749
|
-
})
|
|
750
|
-
.optional(),
|
|
751
|
-
metadata: z
|
|
752
|
-
.record(z.string(), z.unknown())
|
|
753
|
-
.optional()
|
|
754
|
-
.openapi({
|
|
755
|
-
description: 'Additional metadata for the workflow (e.g., outputDescription)',
|
|
756
|
-
example: { outputDescription: 'Extract expense data from receipts' },
|
|
757
|
-
}),
|
|
758
|
-
})
|
|
759
|
-
.openapi('GenerateDocumentGenerationTemplateRequest');
|
|
760
|
-
// Response for template generation (extends the regular create response)
|
|
761
|
-
export const bubbleFlowTemplateResponseSchema = z
|
|
762
|
-
.object({
|
|
763
|
-
id: z.number().openapi({
|
|
764
|
-
description: 'ID of the created BubbleFlow template',
|
|
765
|
-
example: 123,
|
|
766
|
-
}),
|
|
767
|
-
name: z.string().openapi({
|
|
768
|
-
description: 'Name of the BubbleFlow',
|
|
769
|
-
example: 'Sam Dix Data Scientist Bot',
|
|
770
|
-
}),
|
|
771
|
-
description: z.string().openapi({
|
|
772
|
-
description: 'Description of the BubbleFlow',
|
|
773
|
-
example: 'A Slack bot that helps analyze user engagement data',
|
|
774
|
-
}),
|
|
775
|
-
eventType: z.string().openapi({
|
|
776
|
-
description: 'Event type this BubbleFlow responds to',
|
|
777
|
-
example: 'slack/bot_mentioned',
|
|
778
|
-
}),
|
|
779
|
-
displayedBubbleParameters: z.record(z.string(), z.object({
|
|
780
|
-
variableName: z.string(),
|
|
781
|
-
bubbleName: z.string(),
|
|
782
|
-
className: z.string(),
|
|
783
|
-
parameters: z.array(z.object({
|
|
784
|
-
name: z.string(),
|
|
785
|
-
value: z.unknown(),
|
|
786
|
-
type: z.nativeEnum(BubbleParameterType),
|
|
787
|
-
})),
|
|
788
|
-
hasAwait: z.boolean(),
|
|
789
|
-
hasActionCall: z.boolean(),
|
|
790
|
-
})),
|
|
791
|
-
bubbleParameters: z
|
|
792
|
-
.record(z.string(), z.object({
|
|
793
|
-
variableName: z.string(),
|
|
794
|
-
bubbleName: z.string(),
|
|
795
|
-
className: z.string(),
|
|
796
|
-
parameters: z.array(z.object({
|
|
797
|
-
name: z.string(),
|
|
798
|
-
value: z.unknown(),
|
|
799
|
-
type: z.nativeEnum(BubbleParameterType),
|
|
800
|
-
})),
|
|
801
|
-
hasAwait: z.boolean(),
|
|
802
|
-
hasActionCall: z.boolean(),
|
|
803
|
-
}))
|
|
804
|
-
.openapi({
|
|
805
|
-
description: 'Parsed bubble parameters from the BubbleFlow code',
|
|
806
|
-
}),
|
|
807
|
-
requiredCredentials: z
|
|
808
|
-
.record(z.string(), z.array(z.nativeEnum(CredentialType)))
|
|
809
|
-
.optional()
|
|
810
|
-
.openapi({
|
|
811
|
-
description: 'Mapping of bubble names to their required credential types',
|
|
812
|
-
example: {
|
|
813
|
-
'database-connection': [CredentialType.DATABASE_CRED],
|
|
814
|
-
'slack-notification': [CredentialType.SLACK_CRED],
|
|
815
|
-
'ai-analysis': [CredentialType.GOOGLE_GEMINI_CRED],
|
|
816
|
-
},
|
|
817
|
-
}),
|
|
818
|
-
createdAt: z.string().openapi({
|
|
819
|
-
description: 'ISO timestamp when the template was created',
|
|
820
|
-
example: '2025-01-15T10:30:00.000Z',
|
|
821
|
-
}),
|
|
822
|
-
updatedAt: z.string().openapi({
|
|
823
|
-
description: 'ISO timestamp when the template was last updated',
|
|
824
|
-
example: '2025-01-15T10:30:00.000Z',
|
|
825
|
-
}),
|
|
826
|
-
webhook: z
|
|
827
|
-
.object({
|
|
828
|
-
id: z.number().openapi({ description: 'Webhook ID', example: 456 }),
|
|
829
|
-
url: z.string().openapi({
|
|
830
|
-
description: 'Full webhook URL',
|
|
831
|
-
example: 'http://localhost:3001/webhook/user123/my-webhook',
|
|
832
|
-
}),
|
|
833
|
-
path: z.string().openapi({
|
|
834
|
-
description: 'Webhook path',
|
|
835
|
-
example: 'my-webhook',
|
|
836
|
-
}),
|
|
837
|
-
active: z.boolean().openapi({
|
|
838
|
-
description: 'Whether webhook is active',
|
|
839
|
-
example: true,
|
|
840
|
-
}),
|
|
841
|
-
})
|
|
842
|
-
.optional()
|
|
843
|
-
.openapi({
|
|
844
|
-
description: 'Webhook information (if webhook was created)',
|
|
845
|
-
}),
|
|
846
|
-
})
|
|
847
|
-
.openapi('BubbleFlowTemplateResponse');
|
|
848
|
-
// Export TypeScript types
|
|
849
|
-
// POST /bubble-flow/:id/test - Test workflow
|
|
850
|
-
export const testBubbleFlowSchema = z
|
|
851
|
-
.object({
|
|
852
|
-
message: z.string().min(1).openapi({
|
|
853
|
-
description: 'Test message to send to the workflow',
|
|
854
|
-
example: 'What is our user engagement rate this month?',
|
|
855
|
-
}),
|
|
856
|
-
})
|
|
857
|
-
.openapi('TestBubbleFlowRequest');
|
|
858
|
-
export const testBubbleFlowResponseSchema = z
|
|
859
|
-
.object({
|
|
860
|
-
success: z.boolean().openapi({
|
|
861
|
-
description: 'Whether the test execution was successful',
|
|
862
|
-
example: true,
|
|
863
|
-
}),
|
|
864
|
-
response: z.string().openapi({
|
|
865
|
-
description: 'Response from the workflow',
|
|
866
|
-
example: 'Based on your query, I found 1,247 active users...',
|
|
867
|
-
}),
|
|
868
|
-
executionTime: z.number().openapi({
|
|
869
|
-
description: 'Execution time in milliseconds',
|
|
870
|
-
example: 1500,
|
|
871
|
-
}),
|
|
872
|
-
error: z.string().optional().openapi({
|
|
873
|
-
description: 'Error message if test failed',
|
|
874
|
-
example: 'Database connection failed',
|
|
875
|
-
}),
|
|
876
|
-
})
|
|
877
|
-
.openapi('TestBubbleFlowResponse');
|
|
878
|
-
// POST /bubble-flow/:id/activate - Activate workflow
|
|
879
|
-
export const activateBubbleFlowResponseSchema = z
|
|
880
|
-
.object({
|
|
881
|
-
success: z.boolean().openapi({
|
|
882
|
-
description: 'Whether the activation was successful',
|
|
883
|
-
example: true,
|
|
884
|
-
}),
|
|
885
|
-
webhookUrl: z.string().openapi({
|
|
886
|
-
description: 'Webhook URL for the activated workflow',
|
|
887
|
-
example: 'https://api.nodex.dev/webhook/user123/workflow-123',
|
|
888
|
-
}),
|
|
889
|
-
message: z.string().openapi({
|
|
890
|
-
description: 'Success message',
|
|
891
|
-
example: 'Workflow activated successfully! Your Slack bot is now ready.',
|
|
892
|
-
}),
|
|
893
|
-
})
|
|
894
|
-
.openapi('ActivateBubbleFlowResponse');
|
|
895
|
-
// ============================================================================
|
|
896
|
-
// SUBSCRIPTION SCHEMAS
|
|
897
|
-
// ============================================================================
|
|
898
|
-
// GET /subscription/status - Get user's subscription status
|
|
899
|
-
export const subscriptionStatusResponseSchema = z
|
|
900
|
-
.object({
|
|
901
|
-
userId: z.string().openapi({
|
|
902
|
-
description: 'User ID from Clerk',
|
|
903
|
-
example: 'user_30Gbwrzto1VZvAHcGUm5NLQhpkp',
|
|
904
|
-
}),
|
|
905
|
-
plan: z.string().openapi({
|
|
906
|
-
description: 'Current subscription plan',
|
|
907
|
-
example: 'pro_plus',
|
|
908
|
-
}),
|
|
909
|
-
planDisplayName: z.string().openapi({
|
|
910
|
-
description: 'Human-readable plan name',
|
|
911
|
-
example: 'Pro Plus',
|
|
912
|
-
}),
|
|
913
|
-
features: z.array(z.string()).openapi({
|
|
914
|
-
description: 'List of features available to the user',
|
|
915
|
-
example: ['unlimited_usage', 'priority_support'],
|
|
916
|
-
}),
|
|
917
|
-
usage: z.object({
|
|
918
|
-
current: z.number().openapi({
|
|
919
|
-
description: 'Current monthly usage count',
|
|
920
|
-
example: 42,
|
|
921
|
-
}),
|
|
922
|
-
limit: z.number().openapi({
|
|
923
|
-
description: 'Monthly usage limit',
|
|
924
|
-
example: 100,
|
|
925
|
-
}),
|
|
926
|
-
percentage: z.number().openapi({
|
|
927
|
-
description: 'Usage percentage',
|
|
928
|
-
example: 42,
|
|
929
|
-
}),
|
|
930
|
-
resetDate: z.string().openapi({
|
|
931
|
-
description: 'ISO date when usage resets',
|
|
932
|
-
example: '2025-02-01T00:00:00.000Z',
|
|
933
|
-
}),
|
|
934
|
-
}),
|
|
935
|
-
isActive: z.boolean().openapi({
|
|
936
|
-
description: 'Whether the subscription is active',
|
|
937
|
-
example: true,
|
|
938
|
-
}),
|
|
939
|
-
})
|
|
940
|
-
.openapi('SubscriptionStatusResponse');
|
|
941
|
-
// ============================================================================
|
|
942
|
-
// JOIN WAITLIST SCHEMAS
|
|
943
|
-
// ============================================================================
|
|
944
|
-
// POST /join-waitlist - Join waitlist request schema
|
|
945
|
-
export const joinWaitlistSchema = z
|
|
946
|
-
.object({
|
|
947
|
-
name: z.string().min(1, 'Name is required').openapi({
|
|
948
|
-
description: 'Full name of the user',
|
|
949
|
-
example: 'John Doe',
|
|
950
|
-
}),
|
|
951
|
-
email: z.string().email('Valid email is required').openapi({
|
|
952
|
-
description: 'Email address of the user',
|
|
953
|
-
example: 'john.doe@example.com',
|
|
954
|
-
}),
|
|
955
|
-
database: z.string().min(1, 'Database selection is required').openapi({
|
|
956
|
-
description: 'Database type the user wants to use',
|
|
957
|
-
example: 'postgres',
|
|
958
|
-
}),
|
|
959
|
-
otherDatabase: z.string().optional().openapi({
|
|
960
|
-
description: 'Other database type if "other" was selected',
|
|
961
|
-
example: 'Redis',
|
|
962
|
-
}),
|
|
963
|
-
})
|
|
964
|
-
.openapi('JoinWaitlistRequest');
|
|
965
|
-
// POST /join-waitlist - Join waitlist response schema
|
|
966
|
-
export const joinWaitlistResponseSchema = z
|
|
967
|
-
.object({
|
|
968
|
-
success: z.boolean().openapi({
|
|
969
|
-
description: 'Whether the request was successful',
|
|
970
|
-
example: true,
|
|
971
|
-
}),
|
|
972
|
-
message: z.string().openapi({
|
|
973
|
-
description: 'Success message',
|
|
974
|
-
example: 'Successfully joined the waitlist! Check your email for next steps.',
|
|
975
|
-
}),
|
|
976
|
-
})
|
|
977
|
-
.openapi('JoinWaitlistResponse');
|
|
978
|
-
//# sourceMappingURL=routes.js.map
|