@bubblelab/bubble-runtime 0.1.15 → 0.1.17

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.
@@ -38,7 +38,9 @@ export declare class BubbleParser {
38
38
  /**
39
39
  * Build a JSON Schema object for the payload parameter of the top-level `handle` entrypoint.
40
40
  * Supports primitives, arrays, unions (anyOf), intersections (allOf), type literals, and
41
- * same-file interfaces/type aliases. Interface `extends` are ignored for now.
41
+ * same-file interfaces/type aliases. When an interface extends a known trigger event type
42
+ * (e.g., SlackMentionEvent), the schema includes an `extendsEvent` field and only contains
43
+ * the additional custom properties defined in the interface.
42
44
  */
43
45
  getPayloadJsonSchema(ast: TSESTree.Program): Record<string, unknown> | null;
44
46
  /**
@@ -55,9 +57,15 @@ export declare class BubbleParser {
55
57
  private tsTypeToJsonSchema;
56
58
  private extractTypeReferenceName;
57
59
  private objectTypeToJsonSchema;
58
- private eventKeyToSchema;
59
60
  /** Resolve in-file interface/type alias by name to JSON Schema */
60
61
  private resolveTypeNameToJson;
62
+ /**
63
+ * Resolve an interface declaration to JSON Schema, handling extends clauses.
64
+ * If the interface extends a known trigger event type, the schema will include
65
+ * an `extendsEvent` field indicating the base trigger type, and `properties`
66
+ * will only contain the additional custom properties.
67
+ */
68
+ private resolveInterfaceToJsonSchema;
61
69
  /**
62
70
  * Find the main class that extends BubbleFlow
63
71
  */
@@ -125,8 +133,9 @@ export declare class BubbleParser {
125
133
  **/
126
134
  private extractCommentForNode;
127
135
  /**
128
- * Extract JSDoc info including description and @canBeFile tag from a node's preceding comments.
136
+ * Extract JSDoc info including description, @canBeFile, and @canBeGoogleFile tags from a node's preceding comments.
129
137
  * The @canBeFile tag controls whether file upload is enabled for string fields in the UI.
138
+ * The @canBeGoogleFile tag enables Google Picker UI for Google Drive file/folder ID fields.
130
139
  */
131
140
  private extractJSDocForNode;
132
141
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"BubbleParser.d.ts","sourceRoot":"","sources":["../../src/extraction/BubbleParser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BubbleParser.d.ts","sourceRoot":"","sources":["../../src/extraction/BubbleParser.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree';
2
2
  import { buildClassNameLookup } from '../utils/bubble-helper';
3
- import { BubbleParameterType, hashToVariableId, buildCallSiteKey, } from '@bubblelab/shared-schemas';
3
+ import { BubbleParameterType, hashToVariableId, buildCallSiteKey, getTriggerEventConfig, isValidBubbleTriggerEvent, getTriggerEventTypeFromInterfaceName, } from '@bubblelab/shared-schemas';
4
4
  import { parseToolsParamValue } from '../utils/parameter-formatter';
5
5
  export class BubbleParser {
6
6
  bubbleScript;
@@ -323,7 +323,9 @@ export class BubbleParser {
323
323
  /**
324
324
  * Build a JSON Schema object for the payload parameter of the top-level `handle` entrypoint.
325
325
  * Supports primitives, arrays, unions (anyOf), intersections (allOf), type literals, and
326
- * same-file interfaces/type aliases. Interface `extends` are ignored for now.
326
+ * same-file interfaces/type aliases. When an interface extends a known trigger event type
327
+ * (e.g., SlackMentionEvent), the schema includes an `extendsEvent` field and only contains
328
+ * the additional custom properties defined in the interface.
327
329
  */
328
330
  getPayloadJsonSchema(ast) {
329
331
  const handleNode = this.findHandleFunctionNode(ast);
@@ -595,10 +597,11 @@ export class BubbleParser {
595
597
  obj.typeName.name === 'BubbleTriggerEventRegistry' &&
596
598
  idx.type === 'TSLiteralType' &&
597
599
  idx.literal.type === 'Literal' &&
598
- typeof idx.literal.value === 'string') {
599
- const schema = this.eventKeyToSchema(idx.literal.value);
600
- if (schema)
601
- return schema;
600
+ typeof idx.literal.value === 'string' &&
601
+ isValidBubbleTriggerEvent(idx.literal.value)) {
602
+ const config = getTriggerEventConfig(idx.literal.value);
603
+ if (config?.payloadSchema)
604
+ return config.payloadSchema;
602
605
  }
603
606
  return {};
604
607
  }
@@ -644,6 +647,10 @@ export class BubbleParser {
644
647
  if (jsDocInfo.canBeFile !== undefined) {
645
648
  propSchema.canBeFile = jsDocInfo.canBeFile;
646
649
  }
650
+ // Add canBeGoogleFile flag to schema if explicitly specified in JSDoc
651
+ if (jsDocInfo.canBeGoogleFile !== undefined) {
652
+ propSchema.canBeGoogleFile = jsDocInfo.canBeGoogleFile;
653
+ }
647
654
  properties[keyName] = propSchema;
648
655
  if (!m.optional)
649
656
  required.push(keyName);
@@ -653,60 +660,11 @@ export class BubbleParser {
653
660
  schema.required = required;
654
661
  return schema;
655
662
  }
656
- // Minimal mapping for known trigger event keys to JSON Schema shapes
657
- // Used for the input schema in the BubbleFlow editor if defined as BubbleTriggerEventRegistry[eventType]
658
- eventKeyToSchema(eventKey) {
659
- if (eventKey === 'slack/bot_mentioned') {
660
- return {
661
- type: 'object',
662
- properties: {
663
- text: { type: 'string' },
664
- channel: { type: 'string' },
665
- thread_ts: { type: 'string' },
666
- user: { type: 'string' },
667
- slack_event: { type: 'object' },
668
- // Allow additional field used in flows
669
- monthlyLimitError: {},
670
- },
671
- required: ['text', 'channel', 'user', 'slack_event'],
672
- };
673
- }
674
- if (eventKey === 'webhook/http') {
675
- return {
676
- type: 'object',
677
- properties: {
678
- body: { type: 'object' },
679
- },
680
- };
681
- }
682
- if (eventKey === 'schedule/cron') {
683
- return {
684
- type: 'object',
685
- properties: {
686
- body: { type: 'object' },
687
- },
688
- };
689
- }
690
- if (eventKey === 'slack/message_received') {
691
- return {
692
- type: 'object',
693
- properties: {
694
- text: { type: 'string' },
695
- channel: { type: 'string' },
696
- user: { type: 'string' },
697
- channel_type: { type: 'string' },
698
- slack_event: { type: 'object' },
699
- },
700
- required: ['text', 'channel', 'user', 'slack_event'],
701
- };
702
- }
703
- return null;
704
- }
705
663
  /** Resolve in-file interface/type alias by name to JSON Schema */
706
664
  resolveTypeNameToJson(name, ast) {
707
665
  for (const stmt of ast.body) {
708
666
  if (stmt.type === 'TSInterfaceDeclaration' && stmt.id.name === name) {
709
- return this.objectTypeToJsonSchema(stmt.body, ast);
667
+ return this.resolveInterfaceToJsonSchema(stmt, ast);
710
668
  }
711
669
  if (stmt.type === 'TSTypeAliasDeclaration' && stmt.id.name === name) {
712
670
  return this.tsTypeToJsonSchema(stmt.typeAnnotation, ast) || {};
@@ -714,7 +672,7 @@ export class BubbleParser {
714
672
  if (stmt.type === 'ExportNamedDeclaration' &&
715
673
  stmt.declaration?.type === 'TSInterfaceDeclaration' &&
716
674
  stmt.declaration.id.name === name) {
717
- return this.objectTypeToJsonSchema(stmt.declaration.body, ast);
675
+ return this.resolveInterfaceToJsonSchema(stmt.declaration, ast);
718
676
  }
719
677
  if (stmt.type === 'ExportNamedDeclaration' &&
720
678
  stmt.declaration?.type === 'TSTypeAliasDeclaration' &&
@@ -724,6 +682,39 @@ export class BubbleParser {
724
682
  }
725
683
  return null;
726
684
  }
685
+ /**
686
+ * Resolve an interface declaration to JSON Schema, handling extends clauses.
687
+ * If the interface extends a known trigger event type, the schema will include
688
+ * an `extendsEvent` field indicating the base trigger type, and `properties`
689
+ * will only contain the additional custom properties.
690
+ */
691
+ resolveInterfaceToJsonSchema(interfaceDecl, ast) {
692
+ // Check if this interface extends a known trigger event type
693
+ if (interfaceDecl.extends && interfaceDecl.extends.length > 0) {
694
+ for (const heritage of interfaceDecl.extends) {
695
+ // Get the extended interface name
696
+ let extendedName = null;
697
+ if (heritage.expression.type === 'Identifier') {
698
+ extendedName = heritage.expression.name;
699
+ }
700
+ if (extendedName) {
701
+ // Check if it's a known trigger event interface
702
+ const triggerEventType = getTriggerEventTypeFromInterfaceName(extendedName);
703
+ if (triggerEventType) {
704
+ // Extract only the additional properties from this interface
705
+ const additionalSchema = this.objectTypeToJsonSchema(interfaceDecl.body, ast);
706
+ // Return schema with extendsEvent marker for the UI to handle
707
+ return {
708
+ ...additionalSchema,
709
+ extendsEvent: triggerEventType,
710
+ };
711
+ }
712
+ }
713
+ }
714
+ }
715
+ // No trigger event extension found, use normal processing
716
+ return this.objectTypeToJsonSchema(interfaceDecl.body, ast);
717
+ }
727
718
  /**
728
719
  * Find the main class that extends BubbleFlow
729
720
  */
@@ -1757,8 +1748,9 @@ export class BubbleParser {
1757
1748
  return cleaned || undefined;
1758
1749
  }
1759
1750
  /**
1760
- * Extract JSDoc info including description and @canBeFile tag from a node's preceding comments.
1751
+ * Extract JSDoc info including description, @canBeFile, and @canBeGoogleFile tags from a node's preceding comments.
1761
1752
  * The @canBeFile tag controls whether file upload is enabled for string fields in the UI.
1753
+ * The @canBeGoogleFile tag enables Google Picker UI for Google Drive file/folder ID fields.
1762
1754
  */
1763
1755
  extractJSDocForNode(node) {
1764
1756
  // Get the line number where this node starts
@@ -1808,11 +1800,17 @@ export class BubbleParser {
1808
1800
  return {};
1809
1801
  const fullComment = commentLines.join('\n');
1810
1802
  let canBeFile;
1803
+ let canBeGoogleFile;
1811
1804
  // Parse @canBeFile tag from the raw comment
1812
1805
  const canBeFileMatch = fullComment.match(/@canBeFile\s+(true|false)/i);
1813
1806
  if (canBeFileMatch) {
1814
1807
  canBeFile = canBeFileMatch[1].toLowerCase() === 'true';
1815
1808
  }
1809
+ // Parse @canBeGoogleFile tag from the raw comment
1810
+ const canBeGoogleFileMatch = fullComment.match(/@canBeGoogleFile\s+(true|false)/i);
1811
+ if (canBeGoogleFileMatch) {
1812
+ canBeGoogleFile = canBeGoogleFileMatch[1].toLowerCase() === 'true';
1813
+ }
1816
1814
  let description;
1817
1815
  if (isBlockComment) {
1818
1816
  description = fullComment
@@ -1820,7 +1818,9 @@ export class BubbleParser {
1820
1818
  .replace(/\s*\*\/\s*$/, '')
1821
1819
  .split('\n')
1822
1820
  .map((line) => line.replace(/^\s*\*\s?/, '').trim())
1823
- .filter((line) => line.length > 0 && !line.startsWith('@canBeFile'))
1821
+ .filter((line) => line.length > 0 &&
1822
+ !line.startsWith('@canBeFile') &&
1823
+ !line.startsWith('@canBeGoogleFile'))
1824
1824
  .join(' ')
1825
1825
  .trim();
1826
1826
  }
@@ -1828,13 +1828,16 @@ export class BubbleParser {
1828
1828
  description = fullComment
1829
1829
  .split('\n')
1830
1830
  .map((line) => line.replace(/^\/\/\s?/, '').trim())
1831
- .filter((line) => line.length > 0 && !line.startsWith('@canBeFile'))
1831
+ .filter((line) => line.length > 0 &&
1832
+ !line.startsWith('@canBeFile') &&
1833
+ !line.startsWith('@canBeGoogleFile'))
1832
1834
  .join(' ')
1833
1835
  .trim();
1834
1836
  }
1835
1837
  return {
1836
1838
  description: description || undefined,
1837
1839
  canBeFile,
1840
+ canBeGoogleFile,
1838
1841
  };
1839
1842
  }
1840
1843
  /**