@bubblelab/bubble-runtime 0.1.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.
Files changed (70) hide show
  1. package/LICENSE.txt +202 -0
  2. package/dist/extraction/BubbleParser.d.ts +80 -0
  3. package/dist/extraction/BubbleParser.d.ts.map +1 -0
  4. package/dist/extraction/BubbleParser.js +926 -0
  5. package/dist/extraction/BubbleParser.js.map +1 -0
  6. package/dist/extraction/index.d.ts +2 -0
  7. package/dist/extraction/index.d.ts.map +1 -0
  8. package/dist/extraction/index.js +4 -0
  9. package/dist/extraction/index.js.map +1 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +8 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/injection/BubbleInjector.d.ts +71 -0
  15. package/dist/injection/BubbleInjector.d.ts.map +1 -0
  16. package/dist/injection/BubbleInjector.js +326 -0
  17. package/dist/injection/BubbleInjector.js.map +1 -0
  18. package/dist/injection/LoggerInjector.d.ts +33 -0
  19. package/dist/injection/LoggerInjector.d.ts.map +1 -0
  20. package/dist/injection/LoggerInjector.js +154 -0
  21. package/dist/injection/LoggerInjector.js.map +1 -0
  22. package/dist/injection/index.d.ts +3 -0
  23. package/dist/injection/index.d.ts.map +1 -0
  24. package/dist/injection/index.js +3 -0
  25. package/dist/injection/index.js.map +1 -0
  26. package/dist/parse/BubbleScript.d.ts +141 -0
  27. package/dist/parse/BubbleScript.d.ts.map +1 -0
  28. package/dist/parse/BubbleScript.js +513 -0
  29. package/dist/parse/BubbleScript.js.map +1 -0
  30. package/dist/parse/index.d.ts +3 -0
  31. package/dist/parse/index.d.ts.map +1 -0
  32. package/dist/parse/index.js +3 -0
  33. package/dist/parse/index.js.map +1 -0
  34. package/dist/parse/traceDependencies.d.ts +18 -0
  35. package/dist/parse/traceDependencies.d.ts.map +1 -0
  36. package/dist/parse/traceDependencies.js +181 -0
  37. package/dist/parse/traceDependencies.js.map +1 -0
  38. package/dist/runtime/BubbleRunner.d.ts +91 -0
  39. package/dist/runtime/BubbleRunner.d.ts.map +1 -0
  40. package/dist/runtime/BubbleRunner.js +586 -0
  41. package/dist/runtime/BubbleRunner.js.map +1 -0
  42. package/dist/runtime/index.d.ts +2 -0
  43. package/dist/runtime/index.d.ts.map +1 -0
  44. package/dist/runtime/index.js +2 -0
  45. package/dist/runtime/index.js.map +1 -0
  46. package/dist/runtime/types.d.ts +29 -0
  47. package/dist/runtime/types.d.ts.map +1 -0
  48. package/dist/runtime/types.js +2 -0
  49. package/dist/runtime/types.js.map +1 -0
  50. package/dist/types/index.d.ts +8 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/index.js +2 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/utils/bubble-helper.d.ts +11 -0
  55. package/dist/utils/bubble-helper.d.ts.map +1 -0
  56. package/dist/utils/bubble-helper.js +15 -0
  57. package/dist/utils/bubble-helper.js.map +1 -0
  58. package/dist/utils/parameter-formatter.d.ts +22 -0
  59. package/dist/utils/parameter-formatter.d.ts.map +1 -0
  60. package/dist/utils/parameter-formatter.js +219 -0
  61. package/dist/utils/parameter-formatter.js.map +1 -0
  62. package/dist/validation/BubbleValidator.d.ts +43 -0
  63. package/dist/validation/BubbleValidator.d.ts.map +1 -0
  64. package/dist/validation/BubbleValidator.js +172 -0
  65. package/dist/validation/BubbleValidator.js.map +1 -0
  66. package/dist/validation/index.d.ts +27 -0
  67. package/dist/validation/index.d.ts.map +1 -0
  68. package/dist/validation/index.js +126 -0
  69. package/dist/validation/index.js.map +1 -0
  70. package/package.json +47 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { ParsedBubble } from '@bubblelab/shared-schemas';
2
+ export interface ParseResult {
3
+ success: boolean;
4
+ bubbles: Record<string, ParsedBubble>;
5
+ errors?: string[];
6
+ warnings?: string[];
7
+ }
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { BubbleFactory } from '@bubblelab/bubble-core';
2
+ import { BubbleNodeType } from '@bubblelab/shared-schemas';
3
+ /**
4
+ * Build a lookup map from className to bubble metadata
5
+ */
6
+ export declare function buildClassNameLookup(factory: BubbleFactory): Map<string, {
7
+ bubbleName: string;
8
+ className: string;
9
+ nodeType: BubbleNodeType;
10
+ }>;
11
+ //# sourceMappingURL=bubble-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bubble-helper.d.ts","sourceRoot":"","sources":["../../src/utils/bubble-helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,GACrB,GAAG,CACJ,MAAM,EACN;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CACpE,CAiBA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Build a lookup map from className to bubble metadata
3
+ */
4
+ export function buildClassNameLookup(factory) {
5
+ const lookup = new Map();
6
+ const all = factory.getAll();
7
+ for (const ctor of all) {
8
+ const className = ctor.name;
9
+ const bubbleName = ctor.bubbleName ?? className;
10
+ const nodeType = ctor.type ?? 'unknown';
11
+ lookup.set(className, { bubbleName, className, nodeType });
12
+ }
13
+ return lookup;
14
+ }
15
+ //# sourceMappingURL=bubble-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bubble-helper.js","sourceRoot":"","sources":["../../src/utils/bubble-helper.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAsB;IAKtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAGnB,CAAC;IACJ,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAA+B,CAAC;IAE1D,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAI,IAAoC,CAAC,IAAI,CAAC;QAC7D,MAAM,UAAU,GACb,IAA2C,CAAC,UAAU,IAAI,SAAS,CAAC;QACvE,MAAM,QAAQ,GACX,IAA6C,CAAC,IAAI,IAAI,SAAS,CAAC;QACnE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Utility functions for formatting bubble parameters
3
+ */
4
+ /**
5
+ * Build parameters object string from bubble parameters
6
+ */
7
+ import { BubbleParameter, ParsedBubbleWithInfo } from '@bubblelab/shared-schemas';
8
+ export declare function buildParametersObject(parameters: BubbleParameter[], variableId?: number, includeLoggerConfig?: boolean, dependencyGraphLiteral?: string, currentUniqueId?: string): string;
9
+ /**
10
+ * Format a parameter value based on its type
11
+ */
12
+ export declare function formatParameterValue(value: unknown, type: string): string;
13
+ /**
14
+ * Try to parse a tools parameter that may be provided as JSON or a JS-like array literal.
15
+ * Returns an array of objects with at least a name field, or null if parsing fails.
16
+ */
17
+ export declare function parseToolsParamValue(raw: unknown): Array<Record<string, unknown>> | null;
18
+ /**
19
+ * Replace a bubble instantiation with updated parameters
20
+ */
21
+ export declare function replaceBubbleInstantiation(lines: string[], bubble: ParsedBubbleWithInfo): void;
22
+ //# sourceMappingURL=parameter-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/parameter-formatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,OAAO,EACL,eAAe,EACf,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAAE,EAC7B,UAAU,CAAC,EAAE,MAAM,EACnB,mBAAmB,GAAE,OAAc,EACnC,sBAAsB,CAAC,EAAE,MAAM,EAC/B,eAAe,GAAE,MAAW,GAC3B,MAAM,CAuBR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA+CzE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,GACX,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAyBvC;AAkBD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,oBAAoB,QAsI7B"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Utility functions for formatting bubble parameters
3
+ */
4
+ export function buildParametersObject(parameters, variableId, includeLoggerConfig = true, dependencyGraphLiteral, currentUniqueId = '') {
5
+ if (!parameters || parameters.length === 0) {
6
+ return '{}';
7
+ }
8
+ const paramEntries = parameters.map((param) => {
9
+ const value = formatParameterValue(param.value, param.type);
10
+ return `${param.name}: ${value}`;
11
+ });
12
+ const paramsString = `{\n ${paramEntries.join(',\n ')}\n }`;
13
+ // Only add the logger configuration if explicitly requested
14
+ if (includeLoggerConfig) {
15
+ const depGraphPart = dependencyGraphLiteral && dependencyGraphLiteral.length > 0
16
+ ? `, dependencyGraph: ${dependencyGraphLiteral}`
17
+ : '';
18
+ const currentIdPart = `, currentUniqueId: ${JSON.stringify(currentUniqueId)}`;
19
+ return `${paramsString}, {logger: this.logger, variableId: ${variableId}${depGraphPart}${currentIdPart}}`;
20
+ }
21
+ return paramsString;
22
+ }
23
+ /**
24
+ * Format a parameter value based on its type
25
+ */
26
+ export function formatParameterValue(value, type) {
27
+ switch (type) {
28
+ case 'string': {
29
+ const stringValue = String(value);
30
+ // If it's a template literal, pass through unchanged
31
+ if (stringValue.startsWith('`') && stringValue.endsWith('`')) {
32
+ return stringValue;
33
+ }
34
+ // Check if the value is already quoted
35
+ if (stringValue.startsWith("'") && stringValue.endsWith("'")) {
36
+ return stringValue; // Already quoted
37
+ }
38
+ return `\`'${stringValue}'\``;
39
+ }
40
+ case 'number':
41
+ return String(value);
42
+ case 'boolean':
43
+ return String(value);
44
+ case 'object':
45
+ // If caller provided a source literal string, keep it as code
46
+ if (typeof value === 'string') {
47
+ const trimmed = value.trim();
48
+ if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
49
+ trimmed.startsWith('new ')) {
50
+ return value;
51
+ }
52
+ }
53
+ return JSON.stringify(value, null, 2);
54
+ case 'array':
55
+ if (typeof value === 'string') {
56
+ const trimmed = value.trim();
57
+ if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
58
+ return value;
59
+ }
60
+ }
61
+ return JSON.stringify(value);
62
+ case 'env':
63
+ return `process.env.${String(value)}`;
64
+ case 'variable':
65
+ return String(value); // Reference to another variable
66
+ case 'expression':
67
+ return String(value); // Return expressions unquoted so they can be evaluated
68
+ default:
69
+ return JSON.stringify(value);
70
+ }
71
+ }
72
+ /**
73
+ * Try to parse a tools parameter that may be provided as JSON or a JS-like array literal.
74
+ * Returns an array of objects with at least a name field, or null if parsing fails.
75
+ */
76
+ export function parseToolsParamValue(raw) {
77
+ if (Array.isArray(raw))
78
+ return raw;
79
+ if (typeof raw !== 'string')
80
+ return null;
81
+ // 1) Try strict JSON first
82
+ try {
83
+ const parsed = JSON.parse(raw);
84
+ if (Array.isArray(parsed))
85
+ return parsed;
86
+ }
87
+ catch {
88
+ // Handle JSON parse error gracefully
89
+ }
90
+ // 2) Coerce common JS-like literal into valid JSON and parse
91
+ const coerced = coerceJsArrayLiteralToJson(raw);
92
+ if (coerced) {
93
+ try {
94
+ const parsed = JSON.parse(coerced);
95
+ if (Array.isArray(parsed))
96
+ return parsed;
97
+ }
98
+ catch {
99
+ // Handle JSON parse error gracefully
100
+ }
101
+ }
102
+ return null;
103
+ }
104
+ function coerceJsArrayLiteralToJson(input) {
105
+ let s = input.trim();
106
+ if (!s.startsWith('['))
107
+ return null;
108
+ // Remove trailing commas before } or ]
109
+ s = s.replace(/,(\s*[}\]])/g, '$1');
110
+ // Quote unquoted object keys: { name: 'x' } -> { "name": 'x' }
111
+ s = s.replace(/([{,]\s*)([A-Za-z_][A-Za-z0-9_-]*)(\s*:)/g, '$1"$2"$3');
112
+ // Replace single-quoted strings with double-quoted strings
113
+ s = s.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'/g, '"$1"');
114
+ return s;
115
+ }
116
+ /**
117
+ * Replace a bubble instantiation with updated parameters
118
+ */
119
+ export function replaceBubbleInstantiation(lines, bubble) {
120
+ const { location, className, parameters } = bubble;
121
+ // Build the new instantiation code
122
+ // Only include logger config for bubbles that need it (typically those with logging capabilities)
123
+ const dependencyGraphLiteral = JSON.stringify(bubble.dependencyGraph || { name: bubble.bubbleName, dependencies: [] }).replace(/</g, '\u003c');
124
+ const parametersObject = buildParametersObject(parameters, bubble.variableId, true, dependencyGraphLiteral, String(bubble.variableId));
125
+ const newInstantiationBase = `new ${className}(${parametersObject})`;
126
+ // Find the bubble instantiation lines and replace them
127
+ for (let i = location.startLine - 1; i <= location.endLine - 1; i++) {
128
+ if (i < lines.length) {
129
+ const line = lines[i];
130
+ // Replace the bubble instantiation
131
+ if (line.includes(`new ${className}`)) {
132
+ // Pattern 1: variableName = new BubbleClass(...)
133
+ const variableMatch = line.match(/^(\s*)(const|let|var)\s+([A-Za-z_$][\w$]*)\s*(?::\s*[^=]+)?=\s*/);
134
+ if (variableMatch) {
135
+ const [, indentation, declaration, variableName] = variableMatch;
136
+ const hadAwait = /\bawait\b/.test(line);
137
+ const actionCall = bubble.hasActionCall ? '.action()' : '';
138
+ const newExpression = `${hadAwait ? 'await ' : ''}${newInstantiationBase}${actionCall}`;
139
+ const replacement = `${indentation}${declaration} ${variableName} = ${newExpression};`;
140
+ lines[i] = replacement;
141
+ // Delete only the parameter lines, not the entire block
142
+ // Find the actual end of the bubble parameters by looking for the closing });
143
+ // We need to be more precise - look for the }); that matches the indentation
144
+ let actualEndLine = i;
145
+ const startIndentation = lines[i].match(/^(\s*)/)?.[1] || '';
146
+ for (let j = i + 1; j < lines.length; j++) {
147
+ const line = lines[j];
148
+ // Look for a line that contains '});' and has the same or less indentation than the start
149
+ // For regular bubbles, it might end with '});' or '}).action();'
150
+ const hasClosingBrace = line.includes('});');
151
+ const endsWithClosingBrace = line.trim().endsWith('});');
152
+ const containsActionCall = line.trim().includes('}).action();');
153
+ if ((hasClosingBrace && endsWithClosingBrace) ||
154
+ containsActionCall) {
155
+ const lineIndentation = line.match(/^(\s*)/)?.[1] || '';
156
+ // If this line has the same or less indentation than the start line, it's likely the end
157
+ if (lineIndentation.length <= startIndentation.length) {
158
+ actualEndLine = j;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ const deleteCount = Math.max(0, actualEndLine - i);
164
+ if (deleteCount > 0) {
165
+ lines.splice(i + 1, deleteCount);
166
+ }
167
+ }
168
+ else {
169
+ // Pattern 2: Anonymous bubbles like "await new BubbleClass(...).action()"
170
+ // Check if this is an anonymous bubble (synthetic variable name)
171
+ if (bubble.variableName.startsWith('_anonymous_')) {
172
+ // For anonymous bubbles, we need to replace the new expression part only
173
+ // while preserving the await and adding .action() if needed
174
+ const beforePattern = line.substring(0, line.indexOf(`new ${className}`));
175
+ const hadAwait = /\bawait\b/.test(beforePattern);
176
+ const actionCall = bubble.hasActionCall ? '.action()' : '';
177
+ const newExpression = `${hadAwait ? 'await ' : ''}${newInstantiationBase}${actionCall}`;
178
+ // Construct the new single-line expression; ensure it ends with semicolon
179
+ const beforeClean = beforePattern.replace(/\bawait\s*$/, '');
180
+ const replacement = `${beforeClean}${newExpression};`;
181
+ console.debug(`Anonymous replacement: "${lines[i]}" -> "${replacement}"`);
182
+ lines[i] = replacement;
183
+ // Delete only the parameter lines, not the entire block
184
+ // Find the actual end of the bubble parameters by looking for the closing });
185
+ // We need to be more precise - look for the }); that matches the indentation
186
+ let actualEndLine = i;
187
+ const startIndentation = lines[i].match(/^(\s*)/)?.[1] || '';
188
+ for (let j = i + 1; j < lines.length; j++) {
189
+ const line = lines[j];
190
+ // Look for a line that contains '});' and has the same or less indentation than the start
191
+ // For anonymous bubbles, it might end with '}).action();' instead of just '});'
192
+ const hasClosingBrace = line.includes('});');
193
+ const endsWithClosingBrace = line.trim().endsWith('});');
194
+ const containsActionCall = line.trim().includes('}).action();');
195
+ if ((hasClosingBrace && endsWithClosingBrace) ||
196
+ containsActionCall) {
197
+ const lineIndentation = line.match(/^(\s*)/)?.[1] || '';
198
+ // If this line has the same or less indentation than the start line, it's likely the end
199
+ if (lineIndentation.length <= startIndentation.length) {
200
+ actualEndLine = j;
201
+ break;
202
+ }
203
+ }
204
+ }
205
+ const deleteCount = Math.max(0, actualEndLine - i);
206
+ console.debug(`Anonymous: Deleting ${deleteCount} lines starting from line ${i + 1} (actualEndLine: ${actualEndLine}, original endLine: ${location.endLine})`);
207
+ if (deleteCount > 0) {
208
+ const deletedLines = lines.slice(i + 1, i + 1 + deleteCount);
209
+ console.debug(`Anonymous deleted lines:`, deletedLines);
210
+ lines.splice(i + 1, deleteCount);
211
+ }
212
+ }
213
+ }
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ }
219
+ //# sourceMappingURL=parameter-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-formatter.js","sourceRoot":"","sources":["../../src/utils/parameter-formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ type DiagnosticsResult = {
2
+ success: boolean;
3
+ errors?: Record<number, string>;
4
+ };
5
+ /**
6
+ * Minimal warmed TypeScript checker for validating string scripts.
7
+ * - Uses LanguageService for fast incremental diagnostics
8
+ * - Keeps shared libs/graphs in memory across requests
9
+ * - Backend callers pass only a code string; imports resolve via tsconfig
10
+ */
11
+ declare class LanguageServiceTypechecker {
12
+ private readonly projectDir;
13
+ private readonly options;
14
+ private readonly sanitizedOptions;
15
+ private readonly configFileNames;
16
+ private readonly snapshots;
17
+ private readonly documentRegistry;
18
+ private readonly moduleResolutionCache;
19
+ private languageService;
20
+ constructor(configPath?: string);
21
+ private normalize;
22
+ private getVirtualFiles;
23
+ /**
24
+ * Validate an in-memory script and return diagnostics.
25
+ * fileName affects caching identity and relative module resolution.
26
+ */
27
+ checkCode(code: string, fileName?: string): DiagnosticsResult;
28
+ prewarm(): void;
29
+ removeVirtualFile(fileName: string): void;
30
+ private createFormatHost;
31
+ }
32
+ export declare function getWarmChecker(configPath?: string): LanguageServiceTypechecker;
33
+ /**
34
+ * Convenience API for backend use: pass code string and receive diagnostics.
35
+ * - fileName only influences cache identity and relative module resolution.
36
+ * - configPath selects the tsconfig used to resolve libs and types.
37
+ */
38
+ export declare function validateScript(code: string, options?: {
39
+ fileName?: string;
40
+ configPath?: string;
41
+ }): DiagnosticsResult;
42
+ export {};
43
+ //# sourceMappingURL=BubbleValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BubbleValidator.d.ts","sourceRoot":"","sources":["../../src/validation/BubbleValidator.ts"],"names":[],"mappings":"AAGA,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;GAKG;AACH,cAAM,0BAA0B;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGtB;IACJ,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;IAChE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA2B;IACjE,OAAO,CAAC,eAAe,CAAqB;gBAEhC,UAAU,SAAoB;IA8F1C,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,eAAe;IAIvB;;;OAGG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,QAAQ,SAA0B,GACjC,iBAAiB;IAqCpB,OAAO,IAAI,IAAI;IAKf,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKzC,OAAO,CAAC,gBAAgB;CAQzB;AAID,wBAAgB,cAAc,CAC5B,UAAU,SAAoB,GAC7B,0BAA0B,CAe5B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,iBAAiB,CAGnB"}
@@ -0,0 +1,172 @@
1
+ import path from 'path';
2
+ import ts from 'typescript';
3
+ /**
4
+ * Minimal warmed TypeScript checker for validating string scripts.
5
+ * - Uses LanguageService for fast incremental diagnostics
6
+ * - Keeps shared libs/graphs in memory across requests
7
+ * - Backend callers pass only a code string; imports resolve via tsconfig
8
+ */
9
+ class LanguageServiceTypechecker {
10
+ projectDir;
11
+ options;
12
+ sanitizedOptions;
13
+ configFileNames;
14
+ snapshots = new Map();
15
+ documentRegistry = ts.createDocumentRegistry();
16
+ moduleResolutionCache;
17
+ languageService;
18
+ constructor(configPath = './tsconfig.json') {
19
+ const resolvedConfigPath = path.isAbsolute(configPath)
20
+ ? configPath
21
+ : path.join(ts.sys.getCurrentDirectory(), configPath);
22
+ const configFile = ts.readConfigFile(resolvedConfigPath, ts.sys.readFile);
23
+ if (configFile.error) {
24
+ const message = ts.formatDiagnosticsWithColorAndContext([configFile.error], this.createFormatHost());
25
+ throw new Error(`Failed to read tsconfig at ${resolvedConfigPath}:\n${message}`);
26
+ }
27
+ const projectDir = path.dirname(resolvedConfigPath);
28
+ const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, projectDir);
29
+ this.projectDir = projectDir;
30
+ this.options = parsed.options;
31
+ // Disable options that cause irrelevant diagnostics for in-memory checks
32
+ this.sanitizedOptions = {
33
+ ...this.options,
34
+ incremental: false,
35
+ tsBuildInfoFile: undefined,
36
+ };
37
+ this.configFileNames = parsed.fileNames;
38
+ this.moduleResolutionCache = ts.createModuleResolutionCache(this.projectDir, (s) => s, this.sanitizedOptions);
39
+ // Initialize language service with a host capable of resolving packages
40
+ const host = {
41
+ getCompilationSettings: () => this.sanitizedOptions,
42
+ getCurrentDirectory: () => this.projectDir,
43
+ getDefaultLibFileName: (opts) => ts.getDefaultLibFilePath(opts),
44
+ getScriptFileNames: () => [
45
+ ...this.configFileNames,
46
+ ...this.getVirtualFiles(),
47
+ ],
48
+ getScriptVersion: (fileName) => this.snapshots.get(this.normalize(fileName))?.version.toString() ?? '0',
49
+ getScriptSnapshot: (fileName) => {
50
+ const normalized = this.normalize(fileName);
51
+ const virtual = this.snapshots.get(normalized);
52
+ if (virtual) {
53
+ return ts.ScriptSnapshot.fromString(virtual.text);
54
+ }
55
+ const text = ts.sys.readFile(normalized);
56
+ if (text === undefined)
57
+ return undefined;
58
+ return ts.ScriptSnapshot.fromString(text);
59
+ },
60
+ fileExists: ts.sys.fileExists,
61
+ readFile: ts.sys.readFile,
62
+ readDirectory: ts.sys.readDirectory,
63
+ directoryExists: ts.sys.directoryExists,
64
+ getDirectories: ts.sys.getDirectories,
65
+ realpath: ts.sys.realpath,
66
+ useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
67
+ // Cache module resolution for performance
68
+ resolveModuleNameLiterals: (moduleNames, containingFile, redirectedReference, options) => {
69
+ const results = moduleNames.map((m) => {
70
+ const res = ts.resolveModuleName(m.text, containingFile, options, ts.sys, this.moduleResolutionCache, redirectedReference);
71
+ return res;
72
+ });
73
+ return results;
74
+ },
75
+ };
76
+ this.languageService = ts.createLanguageService(host, this.documentRegistry);
77
+ }
78
+ normalize(fileName) {
79
+ // Place virtual files under the configured rootDir to avoid TS6059.
80
+ const rootDir = this.options.rootDir
81
+ ? path.isAbsolute(this.options.rootDir)
82
+ ? this.options.rootDir
83
+ : path.join(this.projectDir, this.options.rootDir)
84
+ : this.projectDir;
85
+ const p = path.isAbsolute(fileName)
86
+ ? fileName
87
+ : path.join(rootDir, fileName);
88
+ return ts.sys.useCaseSensitiveFileNames ? p : p.toLowerCase();
89
+ }
90
+ getVirtualFiles() {
91
+ return Array.from(this.snapshots.keys());
92
+ }
93
+ /**
94
+ * Validate an in-memory script and return diagnostics.
95
+ * fileName affects caching identity and relative module resolution.
96
+ */
97
+ checkCode(code, fileName = 'virtual/bubbleflow.ts') {
98
+ const normalized = this.normalize(fileName);
99
+ const prev = this.snapshots.get(normalized);
100
+ const version = prev ? prev.version + 1 : 1;
101
+ this.snapshots.set(normalized, { version, text: code });
102
+ const syntactic = this.languageService.getSyntacticDiagnostics(normalized);
103
+ const semantic = this.languageService.getSemanticDiagnostics(normalized);
104
+ // Skip compiler options diagnostics (e.g., incremental) for in-memory validation
105
+ const all = [...syntactic, ...semantic].filter((d) => d.code !== 6133); // Ignore TS6133 (unused variable)
106
+ // Build a simple line -> message map for the checked file
107
+ const lineErrors = {};
108
+ for (const d of all) {
109
+ if (!d.file || d.start === undefined)
110
+ continue;
111
+ const lc = d.file.getLineAndCharacterOfPosition(d.start);
112
+ const line = lc.line + 1; // 1-based line numbers
113
+ const message = ts.flattenDiagnosticMessageText(d.messageText, ts.sys.newLine);
114
+ const code = d.code ? `TS${d.code}: ` : '';
115
+ const entry = `${code}${message}`;
116
+ if (lineErrors[line]) {
117
+ lineErrors[line] = `${lineErrors[line]}\n${entry}`;
118
+ }
119
+ else {
120
+ lineErrors[line] = entry;
121
+ }
122
+ }
123
+ return {
124
+ success: all.length === 0,
125
+ errors: Object.keys(lineErrors).length ? lineErrors : undefined,
126
+ };
127
+ }
128
+ // Warm the service by building a Program once. Speeds up first query.
129
+ prewarm() {
130
+ this.languageService.getProgram();
131
+ }
132
+ // Drop a virtual file from the service cache
133
+ removeVirtualFile(fileName) {
134
+ const normalized = this.normalize(fileName);
135
+ this.snapshots.delete(normalized);
136
+ }
137
+ createFormatHost() {
138
+ return {
139
+ getCurrentDirectory: () => this.projectDir,
140
+ getCanonicalFileName: (f) => ts.sys.useCaseSensitiveFileNames ? f : f.toLowerCase(),
141
+ getNewLine: () => ts.sys.newLine,
142
+ };
143
+ }
144
+ }
145
+ // Pool warm services by tsconfig path for server reuse
146
+ const checkerPool = new Map();
147
+ export function getWarmChecker(configPath = './tsconfig.json') {
148
+ const cwd = ts.sys.getCurrentDirectory();
149
+ const resolved = path.isAbsolute(configPath)
150
+ ? configPath
151
+ : path.join(cwd, configPath);
152
+ const key = ts.sys.useCaseSensitiveFileNames
153
+ ? resolved
154
+ : resolved.toLowerCase();
155
+ let service = checkerPool.get(key);
156
+ if (!service) {
157
+ service = new LanguageServiceTypechecker(resolved);
158
+ service.prewarm();
159
+ checkerPool.set(key, service);
160
+ }
161
+ return service;
162
+ }
163
+ /**
164
+ * Convenience API for backend use: pass code string and receive diagnostics.
165
+ * - fileName only influences cache identity and relative module resolution.
166
+ * - configPath selects the tsconfig used to resolve libs and types.
167
+ */
168
+ export function validateScript(code, options) {
169
+ const svc = getWarmChecker(options?.configPath);
170
+ return svc.checkCode(code, options?.fileName ?? 'virtual/script.ts');
171
+ }
172
+ //# sourceMappingURL=BubbleValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BubbleValidator.js","sourceRoot":"","sources":["../../src/validation/BubbleValidator.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,YAAY,CAAC;AAO5B;;;;;GAKG;AACH,MAAM,0BAA0B;IACb,UAAU,CAAS;IACnB,OAAO,CAAqB;IAC5B,gBAAgB,CAAqB;IACrC,eAAe,CAAW;IAC1B,SAAS,GAAG,IAAI,GAAG,EAGjC,CAAC;IACa,gBAAgB,GAAG,EAAE,CAAC,sBAAsB,EAAE,CAAC;IAC/C,qBAAqB,CAA2B;IACzD,eAAe,CAAqB;IAE5C,YAAY,UAAU,GAAG,iBAAiB;QACxC,MAAM,kBAAkB,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACpD,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,UAAU,CAAC,CAAC;QAExD,MAAM,UAAU,GAAG,EAAE,CAAC,cAAc,CAAC,kBAAkB,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1E,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,EAAE,CAAC,oCAAoC,CACrD,CAAC,UAAU,CAAC,KAAK,CAAC,EAClB,IAAI,CAAC,gBAAgB,EAAE,CACxB,CAAC;YACF,MAAM,IAAI,KAAK,CACb,8BAA8B,kBAAkB,MAAM,OAAO,EAAE,CAChE,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,EAAE,CAAC,0BAA0B,CAC1C,UAAU,CAAC,MAAM,EACjB,EAAE,CAAC,GAAG,EACN,UAAU,CACX,CAAC;QACF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,yEAAyE;QACzE,IAAI,CAAC,gBAAgB,GAAG;YACtB,GAAG,IAAI,CAAC,OAAO;YACf,WAAW,EAAE,KAAK;YAClB,eAAe,EAAE,SAAS;SAC3B,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC;QACxC,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,2BAA2B,CACzD,IAAI,CAAC,UAAU,EACf,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EACR,IAAI,CAAC,gBAAgB,CACtB,CAAC;QAEF,wEAAwE;QACxE,MAAM,IAAI,GAA2B;YACnC,sBAAsB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB;YACnD,mBAAmB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU;YAC1C,qBAAqB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAC/D,kBAAkB,EAAE,GAAG,EAAE,CAAC;gBACxB,GAAG,IAAI,CAAC,eAAe;gBACvB,GAAG,IAAI,CAAC,eAAe,EAAE;aAC1B;YACD,gBAAgB,EAAE,CAAC,QAAQ,EAAE,EAAE,CAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,GAAG;YACzE,iBAAiB,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAC/C,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACpD,CAAC;gBACD,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACzC,IAAI,IAAI,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBACzC,OAAO,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC5C,CAAC;YACD,UAAU,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU;YAC7B,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ;YACzB,aAAa,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa;YACnC,eAAe,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe;YACvC,cAAc,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc;YACrC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ;YACzB,yBAAyB,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,yBAAyB;YACjE,0CAA0C;YAC1C,yBAAyB,EAAE,CACzB,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,OAAO,EACP,EAAE;gBACF,MAAM,OAAO,GACX,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACpB,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAC9B,CAAC,CAAC,IAAI,EACN,cAAc,EACd,OAAO,EACP,EAAE,CAAC,GAAG,EACN,IAAI,CAAC,qBAAqB,EAC1B,mBAAmB,CACpB,CAAC;oBACF,OAAO,GAAG,CAAC;gBACb,CAAC,CAAC,CAAC;gBACL,OAAO,OAAkE,CAAC;YAC5E,CAAC;SACF,CAAC;QAEF,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC,qBAAqB,CAC7C,IAAI,EACJ,IAAI,CAAC,gBAAgB,CACtB,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,QAAgB;QAChC,oEAAoE;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO;YAClC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;gBACrC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;gBACtB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACpB,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YACjC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjC,OAAO,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAChE,CAAC;IAEO,eAAe;QACrB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;;OAGG;IACH,SAAS,CACP,IAAY,EACZ,QAAQ,GAAG,uBAAuB;QAElC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAExD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACzE,iFAAiF;QACjF,MAAM,GAAG,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,kCAAkC;QAE1G,0DAA0D;QAC1D,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;gBAAE,SAAS;YAC/C,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,uBAAuB;YACjD,MAAM,OAAO,GAAG,EAAE,CAAC,4BAA4B,CAC7C,CAAC,CAAC,WAAW,EACb,EAAE,CAAC,GAAG,CAAC,OAAO,CACf,CAAC;YACF,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC;YAClC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC;YACzB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;SAChE,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,OAAO;QACL,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED,6CAA6C;IAC7C,iBAAiB,CAAC,QAAgB;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEO,gBAAgB;QACtB,OAAO;YACL,mBAAmB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU;YAC1C,oBAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,CAC1B,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACxD,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO;SACjC,CAAC;IACJ,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsC,CAAC;AAClE,MAAM,UAAU,cAAc,CAC5B,UAAU,GAAG,iBAAiB;IAE9B,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAC1C,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,yBAAyB;QAC1C,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAC;QACnD,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,OAAoD;IAEpD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAChD,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,IAAI,mBAAmB,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { ParsedBubbleWithInfo } from '@bubblelab/shared-schemas';
2
+ import { BubbleFactory } from '@bubblelab/bubble-core';
3
+ export interface ValidationResult {
4
+ valid: boolean;
5
+ errors?: string[];
6
+ }
7
+ export interface ValidationAndExtractionResult extends ValidationResult {
8
+ bubbleParameters?: Record<number, ParsedBubbleWithInfo>;
9
+ inputSchema?: Record<string, unknown>;
10
+ }
11
+ /**
12
+ * Validates a BubbleFlow TypeScript code
13
+ * This focuses purely on validation without extraction
14
+ *
15
+ * @param code - The TypeScript code to validate
16
+ * @returns ValidationResult with success status and errors
17
+ */
18
+ export declare function validateBubbleFlow(code: string): Promise<ValidationResult>;
19
+ /**
20
+ * Validates a BubbleFlow TypeScript code and extracts bubble parameters
21
+ * This is the main entry point for bubble runtime validation with extraction
22
+ *
23
+ * @param code - The TypeScript code to validate
24
+ * @returns ValidationAndExtractionResult with success status, errors, and extracted parameters
25
+ */
26
+ export declare function validateAndExtract(code: string, bubbleFactory: BubbleFactory): Promise<ValidationAndExtractionResult>;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGtE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,6BAA8B,SAAQ,gBAAgB;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC,CA8B3B;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,6BAA6B,CAAC,CA0BxC"}