@superblocksteam/cli 2.0.0 → 2.0.1-next.1

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 CHANGED
@@ -14,7 +14,7 @@ $ npm install -g @superblocksteam/cli
14
14
  $ superblocks COMMAND
15
15
  running command...
16
16
  $ superblocks (--version)
17
- @superblocksteam/cli/2.0.0 linux-x64 node-v20.19.0
17
+ @superblocksteam/cli/2.0.1-next.1 linux-x64 node-v20.19.0
18
18
  $ superblocks --help [COMMAND]
19
19
  USAGE
20
20
  $ superblocks COMMAND
@@ -27,7 +27,7 @@ init_cjs_shims();
27
27
 
28
28
  // ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-api.js
29
29
  init_cjs_shims();
30
- var content = '### APIs\n\nThe Superblocks framework allows you to create backend APIs. The high level structure for creating APIs is as follows:\n\n1. APIs are defined using TypeScript files that live inside the apis directory inside the page they are scoped to. Example: /pages/Page1/apis/myApi.ts\n2. This pattern is a declarative workflow builder, where you define each API step, its configuration, and its execution order within the API workflow.\n3. To make the API available for use, you must import it into the scope file and register it with `SbApi()`, then import and destructure it in your page component for use.\n\n#### Rules\n\n1. CRITICAL: The name of the API must be consistent across the API\'s TypeScript definition, the API\'s file name, references in page files, and the key used to register it in the scope file. See the consistent use of \'myApi\' below as an example.\n2. ALWAYS import ALL API classes from the superblocks library at the top of every API file. Use this complete import statement for every API file:\n3. When using database integrations (PostgreSQL, Snowflake, Databricks), the integration_id parameter should be the actual integration ID from your Superblocks workspace, not a placeholder string.\n\n```ts\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n```\n\n#### Examples\n\n##### Creating and registering a Superblocks API\n\nCreate the API by adding the myApi.ts file:\n\n```ts\n// /pages/Page1/apis/myApi.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("myApi", [\n new JavaScript("retrieve_orders", {\n fn: () => {\n return [\n {\n id: "ORD-001",\n customerName: "John Smith",\n total: 149.99,\n },\n {\n id: "ORD-002",\n customerName: "Sarah Jones",\n total: 89.5,\n },\n ];\n },\n }),\n]);\n```\n\nThen register the myApi API in the scope file:\n\n```ts\n// /pages/Page1/scope.ts\n\nimport { createSbScope, SbApi } from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope(\n () => ({\n // Register the API in the scope\n myApi: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen use the API in your page component:\n\n```tsx\n// /pages/Page1/index.tsx\n\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbButton,\n SbTable,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { myApi } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbButton\n // APIs can be invoked with the SbEventFlow API\n onClick={SbEventFlow.runApis([myApi])}\n label="Fetch Data"\n />\n {/* Access API response using sbComputed */}\n <SbTable tableData={sbComputed(() => myApi.response)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\n##### Referencing the output of a previous block\n\nThink hard about how you access the output of previous steps. You MUST use the output property of the previous step variable. There is no other way to access the output of a previous step (other than using a Variable block, but that is not what you want in this case and should only be used in very specific cases).\n\n```ts\n// Path to this api would be: /pages/Page1/apis/getOrders.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("getOrders", [\n new JavaScript("retrieve_orders", {\n fn: () => {\n return [\n {\n id: 1,\n customer: "John Smith",\n date: "2024-01-15",\n total: 199.99,\n status: "Pending",\n },\n {\n id: 2,\n customer: "Jane Doe",\n date: "2024-01-14",\n total: 149.99,\n status: "Shipped",\n },\n {\n id: 3,\n customer: "Bob Wilson",\n date: "2024-01-13",\n total: 299.99,\n status: "Delivered",\n },\n ];\n },\n }),\n new JavaScript("format_orders", {\n fn: ({ retrieve_orders }) => {\n return retrieve_orders.output.map((order) => ({\n ...order,\n date: new Date(order.date).toLocaleDateString(),\n }));\n },\n }),\n]);\n```\n\nThen you would register the API in your scope file and use it in your page component:\n\n```ts\n// /pages/Page1/scope.ts\nexport const Page1Scope = createSbScope(\n () => ({\n getOrders: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\n// /pages/Page1/index.tsx\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n sbComputed,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { getOrders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbTable tableData={sbComputed(() => getOrders.response)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\n##### Ensuring variable existence in application\n\nWhen creating an API that references variables like `firstName`, `lastName`, and `userId`, since these variables are not previous blocks or variables from a Variables block, you MUST ensure that they exist as part of the page\'s entities. You must establish these variables in the proper order:\n\nFirst, create the variables in the scope file. Since you\'ve determined that we\'ll use input components to take in the first name and last name, you MUST ensure that you use the same names for the entities in the `scope.ts` file as the variable names in the API.\n\n```ts\n// /pages/Page1/scope.ts\n\nimport {\n createSbScope,\n SbApi,\n SbVariable,\n SbVariablePersistence,\n Global,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n firstName: any;\n lastName: any;\n}>(\n // register non-component entities in the scope\n ({ entities: { firstName, lastName, handlePeopleUpdates, userId } }) => ({\n handlePeopleUpdates: SbApi({}),\n userId: SbVariable({\n defaultValue: Global.user.id,\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n // configure page options\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen, use the variables in your page component:\n\n```tsx\n// /pages/Page1/index.tsx\n\nimport {\n SbPage,\n SbInput,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { handlePeopleUpdates, firstName, lastName, userId } = Page1;\n\n return (\n <SbPage name="Page1">\n <SbInput\n label="First Name"\n bind={firstName}\n minLength={1}\n inputType="TEXT"\n />\n <SbInput\n label="Last Name"\n bind={lastName}\n minLength={1}\n inputType="TEXT"\n />\n {/* The rest of the page... */}\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\nFinally, create the API that references these variables:\n\n```ts\n// /pages/Page1/apis/handlePeopleUpdates.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("handlePeopleUpdates", [\n new Conditional("validate", {\n if: {\n when: ({ firstName, lastName }): boolean =>\n !firstName.isValid || !lastName.isValid,\n then: [\n new Throw("reject", {\n error: "either the first name or last name is invalid",\n }),\n ],\n },\n }),\n new PostgreSQL("update", "your-postgresql-integration-id", {\n statement: ({ firstName, lastName, userId }) =>\n `UPDATE people SET first_name = \'${firstName.value}\', last_name = \'${lastName.value}\' WHERE id = ${userId.value}`,\n }),\n]);\n```\n\n#### The Superblocks API TypeScript Type\n\nBelow is the full TypeScript spec for the APIs you create:\n\n````ts\n// @superblocksteam/library\n\nexport type JsonValue =\n | undefined\n | null\n | number\n | string\n | boolean\n | JsonValue[]\n | object;\nexport type State = { [key: string]: JsonValue };\nexport type Binding<T> = T | ((state: State) => T);\ntype Integrations = { id: string; description: string; metadata: JsonValue }[];\n\nclass Block {\n constructor(name: string) {}\n public run(): { output: JsonValue } {\n /* ... */\n }\n}\n\nclass Integration extends Block {\n constructor(name: string, integration_id: string) {}\n}\n\ntype State = Record<string, JsonValue>;\n\nclass JavaScript extends Integration {\n constructor(\n name: string,\n config: {\n fn: (\n {\n /* ... */\n },\n ) => JsonValue;\n },\n ) {\n super(name, "javascript");\n }\n}\n\nclass Python extends Integration {\n constructor(\n name: string,\n config: {\n // We want to just put the python function body here. The scope is the same as it would be if it were a JavaScript integration.\n fn: string;\n },\n ) {\n super(name, "python");\n }\n}\n\nclass Databricks extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass Snowflake extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass PostgreSQL extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass RestApi extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n constructor(\n name: string,\n // If you need to make a request that is detached from an integration, you MUST set this to "restapi".\n integration: string = "restapi",\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n // If you\'re using a path from an integration that has an OpenAPI spec, you MUST set this to true.\n fromOpenApiSpec: boolean = false,\n ) {\n super(name, integration);\n }\n}\n\nclass Email extends Integration {\n constructor(\n name: string,\n config: {\n from: Binding<string>;\n to: Binding<string>;\n subject: Binding<string>;\n cc?: Binding<string>;\n bcc?: Binding<string>;\n body?: Binding<string>;\n },\n ) {\n super(name);\n }\n}\n\nexport type Condition = {\n when: boolean | ((state: State) => boolean);\n then: Block[];\n};\n\nexport type Conditions = {\n if: Condition;\n elif?: Condition[];\n else?: Block[];\n};\n\nclass Conditional extends Block {\n constructor(name: string, config: Conditions) {\n super(name);\n }\n}\n\nclass TryCatch extends Block {\n constructor(\n name: string,\n config: {\n try: Block[];\n catch: Block[];\n finally?: Block[];\n variables: { error: string };\n },\n ) {\n super(name);\n }\n}\n\n/**\n * A Superblocks variable has the following access pattern:\n *\n * How to retrieve the value of a variable:\n * ```ts\n * CORRECT\n * my_variable.value\n *\n * // INCORRECT\n * my_variable\n * ```\n *\n * How to set the value of a variable:\n * ```ts\n * CORRECT\n * my_variable.set(value)\n *\n * // INCORRECT\n * my_variable = value\n * ```\n *\n */\n\nclass Variables extends Block {\n constructor(\n name: string,\n variables: {\n // The name of the variable.\n key: string;\n // The value of the variable.\n value: Binding<JsonValue>;\n }[],\n ) {\n super(name);\n }\n}\n\nclass Loop extends Block {\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: {\n // What the variable name for the current item is.\n item: string;\n // What the variable name for the current index is.\n index: string;\n };\n blocks: Block[];\n },\n ) {\n super(name);\n }\n}\n\nclass Parallel extends Block {\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: {\n // What the variable name for the current item is.\n item: string;\n };\n blocks: Block[];\n },\n ) {\n super(name);\n }\n}\n\nclass Throw extends Block {\n constructor(\n name: string,\n config: {\n error: Binding<JsonValue>;\n },\n ) {\n super(name);\n }\n}\n\nclass Return extends Block {\n constructor(\n name: string,\n config: {\n data: Binding<JsonValue>;\n },\n ) {\n super(name);\n }\n}\n\nclass Api {\n constructor(name: string, steps: Block[]) {}\n public get response(): JsonValue {\n /* ... */\n }\n public get error(): string | undefined {\n /* ... */\n }\n public run(): void {\n /* ... */\n }\n public cancel(): void {\n /* ... */\n }\n}\n````\n\n#### Rules for using Superblocks APIs\n\nThink hard about the following important rules for correctly using Superblocks APIs:\n\n- You MUST use a destructured state object as the function parameter for dynamic block fields.\n\n```ts\n// CORRECT: uses destructured state\n({ Dropdown1, TextInput1 }) => Dropdown1.selectedOptionsValue + TextInput1.value\n\n// INCORRECT: uses state object directly\n(state) => state.Dropdown1.selectedOptionsValue + state.TextInput1.value\n```\n\n- DO NOT reference variables that are not in scope or that don\'t exist. The ONLY things in scope are (1) the outputs of previous blocks that are in lexical scope and (2) page entities.\n\n- The result of each scope is the result of the last block in that scope. In the following example, the value of `sendEmail.response` is the result of the `return_summary` block. Use this information to carefully ensure that the last block in your API is the one that returns the value you want.\n\n```ts\nexport default new Api("sendEmail", [\n new Email("send_email", {\n from: "noreply@company.com",\n to: "test@test.com",\n subject: "Test Email",\n body: "This is a test email",\n }),\n new JavaScript("return_summary", {\n fn: () => "Email sent successfully!",\n }),\n]);\n```\n\n- Block outputs are immutable. Do not mutate the output of a block.\n\n- Backend APIs CANNOT mutate frontend state inside of the API\n\n- APIs are registered in scope files using `SbApi()` and then accessed in page components by destructuring from the scope entities. Make sure you name the key used in registerScope the same as the imported API, but do not pass the imported Api into the SbApi() call.\n\n- To access API responses in your UI, use `sbComputed(() => apiName.response)` or `sbComputed(() => apiName.error)`.\n\n- You will not always be told which integrations to use in your API; you will have to determine that yourself based on the data you need to fetch.\n\n- Never add comments to code you (the ai) generate. User added comments are fine - leave those!\n';
30
+ var content = '### APIs\n\nThe Superblocks framework allows you to create backend APIs. The high level structure for creating APIs is as follows:\n\n1. APIs are defined using TypeScript files that live inside the apis directory inside the page they are scoped to. Example: /pages/Page1/apis/myApi.ts\n2. This pattern is a declarative workflow builder, where you define each API step, its configuration, and its execution order within the API workflow.\n3. To make the API available for use, you must import it into the scope file and register it with `SbApi()`, then import and destructure it in your page component for use.\n\n#### CRITICAL VARIABLE SCOPING RULES\n\n**\u{1F6A8} EXTREMELY IMPORTANT**: Variables referenced in API blocks can ONLY come from these sources:\n\n1. **Outputs of previous blocks** in the same API (accessed via the block name)\n2. **Page entities defined in the scope file** (passed as destructured parameters)\n3. **Never reference variables that don\'t exist** - this is the #1 cause of API generation errors\n\n**\u274C WRONG - Variables that don\'t exist in scope:**\n\n```ts\nnew PostgreSQL("insert_data", "postgres-integration-id", {\n statement: ({ customerId, productName, issueType }) =>\n `INSERT INTO issues VALUES (${customerId.value}, \'${productName.value}\', \'${issueType.value}\')`,\n // \u274C ERROR: customerId, productName, issueType are not defined anywhere!\n});\n```\n\n**\u2705 CORRECT - Variables from scope entities:**\n\n```ts\n// First, define in scope.ts:\nexport const Page1Scope = createSbScope<{\n CustomerIdInput: any;\n ProductNameInput: any;\n IssueTypeDropdown: any;\n}>(\n () => ({\n // Register the API\n submitIssue: SbApi({}),\n }),\n { name: "Page1" },\n);\n\n// Then use in API:\nnew PostgreSQL("insert_data", "postgres-integration-id", {\n statement: ({ CustomerIdInput, ProductNameInput, IssueTypeDropdown }) =>\n `INSERT INTO issues VALUES (${CustomerIdInput.value}, \'${ProductNameInput.value}\', \'${IssueTypeDropdown.selectedOptionValue}\')`,\n // \u2705 CORRECT: These are page entities defined in the scope\n});\n```\n\n**\u2705 CORRECT - Variables from previous blocks:**\n\n```ts\nexport default new Api("processOrder", [\n new JavaScript("get_customer_data", {\n fn: () => ({ customerId: 123, customerName: "John Doe" }),\n }),\n new PostgreSQL("insert_order", "postgres-integration-id", {\n statement: ({ get_customer_data }) =>\n `INSERT INTO orders VALUES (${get_customer_data.output.customerId}, \'${get_customer_data.output.customerName}\')`,\n // \u2705 CORRECT: get_customer_data is a previous block in this API\n }),\n]);\n```\n\n#### Rules\n\n1. CRITICAL: The name of the API must be consistent across the API\'s TypeScript definition, the API\'s file name, references in page files, and the key used to register it in the scope file. See the consistent use of \'myApi\' below as an example.\n2. ALWAYS import ALL API classes from the superblocks library at the top of every API file. Use this complete import statement for every API file:\n3. When using database integrations (PostgreSQL, Snowflake, Databricks), the integration_id parameter should be the actual integration ID from your Superblocks workspace, not a placeholder string.\n4. **CRITICAL**: DO NOT reference variables that are not in scope. The ONLY things in scope are (1) the outputs of previous blocks that are in lexical scope and (2) page entities defined in the scope file.\n\n```ts\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n```\n\n#### Examples\n\n##### Complete Example: Scope \u2192 Components \u2192 API Flow\n\nThis example shows the complete flow from defining variables in scope, to binding them to components, to using them in APIs.\n\n**Step 1: Define entities in scope file**\n\n```ts\n// /pages/Page1/scope.ts\nimport { createSbScope, SbApi } from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n CustomerNameInput: any;\n ProductNameInput: any;\n IssueTypeDropdown: any;\n IssueNotesInput: any;\n}>(\n () => ({\n // Register the API\n submitProductIssue: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n**Step 2: Use entities in page components**\n\n```tsx\n// /pages/Page1/index.tsx\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbInput,\n SbDropdown,\n SbButton,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const {\n CustomerNameInput,\n ProductNameInput,\n IssueTypeDropdown,\n IssueNotesInput,\n submitProductIssue,\n } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbInput bind={CustomerNameInput} label="Customer Name" />\n <SbInput bind={ProductNameInput} label="Product Name" />\n <SbDropdown\n bind={IssueTypeDropdown}\n label="Issue Type"\n options={[\n { label: "Defect", value: "defect" },\n { label: "Complaint", value: "complaint" },\n { label: "Return", value: "return" },\n ]}\n />\n <SbInput bind={IssueNotesInput} label="Notes" multiline={true} />\n <SbButton\n label="Submit Issue"\n onClick={SbEventFlow.runApis([submitProductIssue])}\n />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\n**Step 3: Create API that uses the scope entities**\n\n```ts\n// /pages/Page1/apis/submitProductIssue.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("submitProductIssue", [\n new Conditional("validate_inputs", {\n if: {\n when: ({\n CustomerNameInput,\n ProductNameInput,\n IssueTypeDropdown,\n }): boolean =>\n !CustomerNameInput.value ||\n !ProductNameInput.value ||\n !IssueTypeDropdown.selectedOptionValue,\n then: [\n new Throw("validation_error", {\n error: "Customer name, product name, and issue type are required",\n }),\n ],\n },\n }),\n new PostgreSQL("insert_issue", "your-postgresql-integration-id", {\n statement: ({\n CustomerNameInput,\n ProductNameInput,\n IssueTypeDropdown,\n IssueNotesInput,\n }) =>\n `INSERT INTO product_issues \n (customer_name, product_name, issue_type, notes, status, date_reported, created_by)\n VALUES (\n \'${CustomerNameInput.value}\', \n \'${ProductNameInput.value}\', \n \'${IssueTypeDropdown.selectedOptionValue}\', \n \'${IssueNotesInput.value || ""}\', \n \'Open\', \n NOW(), \n 1\n )`,\n }),\n new JavaScript("return_success", {\n fn: ({ insert_issue }) => ({\n success: true,\n message: "Issue submitted successfully",\n issueId: insert_issue.output?.insertId || null,\n }),\n }),\n]);\n```\n\n##### \u274C COMMON MISTAKES TO AVOID\n\n**\u274C WRONG: Using undefined variables**\n\n```ts\n// This is WRONG - these variables don\'t exist!\nexport default new Api("badExample", [\n new PostgreSQL("insert_data", "postgres-integration-id", {\n statement: ({ customerId, productName, issueType }) =>\n `INSERT INTO issues VALUES (${customerId.value}, \'${productName.value}\', \'${issueType.value}\')`,\n // \u274C ERROR: customerId, productName, issueType are not defined in scope!\n }),\n]);\n```\n\n**\u274C WRONG: Mixing up variable names**\n\n```ts\n// Scope defines CustomerNameInput but API tries to use customerName\nexport default new Api("badExample", [\n new PostgreSQL("insert_data", "postgres-integration-id", {\n statement: (\n { customerName }, // \u274C ERROR: Should be CustomerNameInput\n ) => `INSERT INTO issues VALUES (\'${customerName.value}\')`,\n }),\n]);\n```\n\n**\u274C WRONG: Not destructuring function parameters**\n\n```ts\n// This is WRONG - you must destructure the parameters\nexport default new Api("badExample", [\n new PostgreSQL("insert_data", "postgres-integration-id", {\n statement: (\n state, // \u274C ERROR: Should destructure { CustomerNameInput }\n ) => `INSERT INTO issues VALUES (\'${state.CustomerNameInput.value}\')`,\n }),\n]);\n```\n\n##### Creating and registering a Superblocks API\n\nCreate the API by adding the myApi.ts file:\n\n```ts\n// /pages/Page1/apis/myApi.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("myApi", [\n new JavaScript("retrieve_orders", {\n fn: () => {\n return [\n {\n id: "ORD-001",\n customerName: "John Smith",\n total: 149.99,\n },\n {\n id: "ORD-002",\n customerName: "Sarah Jones",\n total: 89.5,\n },\n ];\n },\n }),\n]);\n```\n\nThen register the myApi API in the scope file:\n\n```ts\n// /pages/Page1/scope.ts\n\nimport { createSbScope, SbApi } from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope(\n () => ({\n // Register the API in the scope\n myApi: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen use the API in your page component:\n\n```tsx\n// /pages/Page1/index.tsx\n\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbButton,\n SbTable,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { myApi } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbButton\n // APIs can be invoked with the SbEventFlow API\n onClick={SbEventFlow.runApis([myApi])}\n label="Fetch Data"\n />\n {/* Access API response using sbComputed */}\n <SbTable tableData={sbComputed(() => myApi.response)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\n##### Referencing the output of a previous block\n\nThink hard about how you access the output of previous steps. You MUST use the output property of the previous step variable. There is no other way to access the output of a previous step (other than using a Variable block, but that is not what you want in this case and should only be used in very specific cases).\n\n```ts\n// Path to this api would be: /pages/Page1/apis/getOrders.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("getOrders", [\n new JavaScript("retrieve_orders", {\n fn: () => {\n return [\n {\n id: 1,\n customer: "John Smith",\n date: "2024-01-15",\n total: 199.99,\n status: "Pending",\n },\n {\n id: 2,\n customer: "Jane Doe",\n date: "2024-01-14",\n total: 149.99,\n status: "Shipped",\n },\n {\n id: 3,\n customer: "Bob Wilson",\n date: "2024-01-13",\n total: 299.99,\n status: "Delivered",\n },\n ];\n },\n }),\n new JavaScript("format_orders", {\n fn: ({ retrieve_orders }) => {\n return retrieve_orders.output.map((order) => ({\n ...order,\n date: new Date(order.date).toLocaleDateString(),\n }));\n },\n }),\n]);\n```\n\nThen you would register the API in your scope file and use it in your page component:\n\n```ts\n// /pages/Page1/scope.ts\nexport const Page1Scope = createSbScope(\n () => ({\n getOrders: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\n// /pages/Page1/index.tsx\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n sbComputed,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { getOrders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbTable tableData={sbComputed(() => getOrders.response)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\n##### Ensuring variable existence in application\n\nWhen creating an API that references variables like `firstName`, `lastName`, and `userId`, since these variables are not previous blocks or variables from a Variables block, you MUST ensure that they exist as part of the page\'s entities. You must establish these variables in the proper order:\n\nFirst, create the variables in the scope file. Since you\'ve determined that we\'ll use input components to take in the first name and last name, you MUST ensure that you use the same names for the entities in the `scope.ts` file as the variable names in the API.\n\n```ts\n// /pages/Page1/scope.ts\n\nimport {\n createSbScope,\n SbApi,\n SbVariable,\n SbVariablePersistence,\n Global,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n firstName: any;\n lastName: any;\n}>(\n // register non-component entities in the scope\n ({ entities: { firstName, lastName, handlePeopleUpdates, userId } }) => ({\n handlePeopleUpdates: SbApi({}),\n userId: SbVariable({\n defaultValue: Global.user.id,\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n // configure page options\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen, use the variables in your page component:\n\n```tsx\n// /pages/Page1/index.tsx\n\nimport {\n SbPage,\n SbInput,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nconst Page1Component = () => {\n const { handlePeopleUpdates, firstName, lastName, userId } = Page1;\n\n return (\n <SbPage name="Page1">\n <SbInput\n label="First Name"\n bind={firstName}\n minLength={1}\n inputType="TEXT"\n />\n <SbInput\n label="Last Name"\n bind={lastName}\n minLength={1}\n inputType="TEXT"\n />\n {/* The rest of the page... */}\n </SbPage>\n );\n};\n\nexport default registerPage(Page1Component, Page1Scope);\n```\n\nFinally, create the API that references these variables:\n\n```ts\n// /pages/Page1/apis/handlePeopleUpdates.ts\n\nimport {\n Api,\n JavaScript,\n Python,\n Databricks,\n Snowflake,\n PostgreSQL,\n RestApi,\n Email,\n Conditional,\n TryCatch,\n Variables,\n Loop,\n Parallel,\n Throw,\n Return,\n} from "@superblocksteam/library";\n\nexport default new Api("handlePeopleUpdates", [\n new Conditional("validate", {\n if: {\n when: ({ firstName, lastName }): boolean =>\n !firstName.isValid || !lastName.isValid,\n then: [\n new Throw("reject", {\n error: "either the first name or last name is invalid",\n }),\n ],\n },\n }),\n new PostgreSQL("update", "your-postgresql-integration-id", {\n statement: ({ firstName, lastName, userId }) =>\n `UPDATE people SET first_name = \'${firstName.value}\', last_name = \'${lastName.value}\' WHERE id = ${userId.value}`,\n }),\n]);\n```\n\n#### The Superblocks API TypeScript Type\n\nBelow is the full TypeScript spec for the APIs you create:\n\n````ts\n// @superblocksteam/library\n\nexport type JsonValue =\n | undefined\n | null\n | number\n | string\n | boolean\n | JsonValue[]\n | object;\nexport type State = { [key: string]: JsonValue };\nexport type Binding<T> = T | ((state: State) => T);\ntype Integrations = { id: string; description: string; metadata: JsonValue }[];\n\nclass Block {\n constructor(name: string) {}\n public run(): { output: JsonValue } {\n /* ... */\n }\n}\n\nclass Integration extends Block {\n constructor(name: string, integration_id: string) {}\n}\n\ntype State = Record<string, JsonValue>;\n\nclass JavaScript extends Integration {\n constructor(\n name: string,\n config: {\n fn: (\n {\n /* ... */\n },\n ) => JsonValue;\n },\n ) {\n super(name, "javascript");\n }\n}\n\nclass Python extends Integration {\n constructor(\n name: string,\n config: {\n // We want to just put the python function body here. The scope is the same as it would be if it were a JavaScript integration.\n fn: string;\n },\n ) {\n super(name, "python");\n }\n}\n\nclass Databricks extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass Snowflake extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass PostgreSQL extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n /**\n * @param {string} name The name of the block.\n * @param {string} integration_id The id of the integration.\n * @param {object} config The config object.\n * @returns {void}\n */\n constructor(\n name: string,\n integration_id: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration_id);\n }\n}\n\nclass RestApi extends Integration {\n static integrations: Integrations = [\n /* ... */\n ];\n\n constructor(\n name: string,\n // If you need to make a request that is detached from an integration, you MUST set this to "restapi".\n integration: string = "restapi",\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n // If you\'re using a path from an integration that has an OpenAPI spec, you MUST set this to true.\n fromOpenApiSpec: boolean = false,\n ) {\n super(name, integration);\n }\n}\n\nclass Email extends Integration {\n constructor(\n name: string,\n config: {\n from: Binding<string>;\n to: Binding<string>;\n subject: Binding<string>;\n cc?: Binding<string>;\n bcc?: Binding<string>;\n body?: Binding<string>;\n },\n ) {\n super(name);\n }\n}\n\nexport type Condition = {\n when: boolean | ((state: State) => boolean);\n then: Block[];\n};\n\nexport type Conditions = {\n if: Condition;\n elif?: Condition[];\n else?: Block[];\n};\n\nclass Conditional extends Block {\n constructor(name: string, config: Conditions) {\n super(name);\n }\n}\n\nclass TryCatch extends Block {\n constructor(\n name: string,\n config: {\n try: Block[];\n catch: Block[];\n finally?: Block[];\n variables: { error: string };\n },\n ) {\n super(name);\n }\n}\n\n/**\n * A Superblocks variable has the following access pattern:\n *\n * How to retrieve the value of a variable:\n * ```ts\n * CORRECT\n * my_variable.value\n *\n * // INCORRECT\n * my_variable\n * ```\n *\n * How to set the value of a variable:\n * ```ts\n * CORRECT\n * my_variable.set(value)\n *\n * // INCORRECT\n * my_variable = value\n * ```\n *\n */\n\nclass Variables extends Block {\n constructor(\n name: string,\n variables: {\n // The name of the variable.\n key: string;\n // The value of the variable.\n value: Binding<JsonValue>;\n }[],\n ) {\n super(name);\n }\n}\n\nclass Loop extends Block {\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: {\n // What the variable name for the current item is.\n item: string;\n // What the variable name for the current index is.\n index: string;\n };\n blocks: Block[];\n },\n ) {\n super(name);\n }\n}\n\nclass Parallel extends Block {\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: {\n // What the variable name for the current item is.\n item: string;\n };\n blocks: Block[];\n },\n ) {\n super(name);\n }\n}\n\nclass Throw extends Block {\n constructor(\n name: string,\n config: {\n error: Binding<JsonValue>;\n },\n ) {\n super(name);\n }\n}\n\nclass Return extends Block {\n constructor(\n name: string,\n config: {\n data: Binding<JsonValue>;\n },\n ) {\n super(name);\n }\n}\n\nclass Api {\n constructor(name: string, steps: Block[]) {}\n public get response(): JsonValue {\n /* ... */\n }\n public get error(): string | undefined {\n /* ... */\n }\n public run(): void {\n /* ... */\n }\n public cancel(): void {\n /* ... */\n }\n}\n````\n\n#### Rules for using Superblocks APIs\n\nThink hard about the following important rules for correctly using Superblocks APIs:\n\n- You MUST use a destructured state object as the function parameter for dynamic block fields.\n\n```ts\n// CORRECT: uses destructured state\n({ Dropdown1, TextInput1 }) => Dropdown1.selectedOptionsValue + TextInput1.value\n\n// INCORRECT: uses state object directly\n(state) => state.Dropdown1.selectedOptionsValue + state.TextInput1.value\n```\n\n- DO NOT reference variables that are not in scope or that don\'t exist. The ONLY things in scope are (1) the outputs of previous blocks that are in lexical scope and (2) page entities.\n\n- The result of each scope is the result of the last block in that scope. In the following example, the value of `sendEmail.response` is the result of the `return_summary` block. Use this information to carefully ensure that the last block in your API is the one that returns the value you want.\n\n```ts\nexport default new Api("sendEmail", [\n new Email("send_email", {\n from: "noreply@company.com",\n to: "test@test.com",\n subject: "Test Email",\n body: "This is a test email",\n }),\n new JavaScript("return_summary", {\n fn: () => "Email sent successfully!",\n }),\n]);\n```\n\n- Block outputs are immutable. Do not mutate the output of a block.\n\n- Backend APIs CANNOT mutate frontend state inside of the API\n\n- APIs are registered in scope files using `SbApi()` and then accessed in page components by destructuring from the scope entities. Make sure you name the key used in registerScope the same as the imported API, but do not pass the imported Api into the SbApi() call.\n\n- To access API responses in your UI, use `sbComputed(() => apiName.response)` or `sbComputed(() => apiName.error)`.\n\n- You will not always be told which integrations to use in your API; you will have to determine that yourself based on the data you need to fetch.\n\n- Never add comments to code you (the ai) generate. User added comments are fine - leave those!\n';
31
31
 
32
32
  // ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.js
33
33
  init_cjs_shims();
@@ -47,7 +47,7 @@ var content5 = '# Event handlers with SbEventFlow\n\nRather than using standard
47
47
 
48
48
  // ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-forms.js
49
49
  init_cjs_shims();
50
- var content6 = '### Form Layouts in Superblocks\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout="vertical"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label="First Name" bind={FirstName} width={Dim.fill()} />\n <SbInput label="Last Name" bind={LastName} width={Dim.fill()} />\n <SbInput label="Email" bind={Email} inputType="EMAIL" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt\'s common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from "@superblocksteam/library";\nimport { Page1 } from "./scope";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout="vertical" spacing={Dim.px(8)}>\n <SbText\n text="Create New Order"\n textStyle={{\n variant: "heading4",\n }}\n />\n <SbText text="Fill out the form below to create a new order" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label="Customer Name"\n placeholderText="Enter customer name"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label="Customer Email"\n inputType="EMAIL"\n placeholderText="Enter customer email"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label="Order Amount"\n placeholderText="Enter order amount"\n inputType="NUMBER"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label="Order Status"\n options={[\n {\n label: "Pending",\n value: "pending",\n },\n {\n label: "Processing",\n value: "processing",\n },\n {\n label: "En route",\n value: "en_route",\n },\n {\n label: "Delivered",\n value: "delivered",\n },\n {\n label: "Refunded",\n value: "refunded",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label="Order Notes"\n placeholderText="Optional notes about the order"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout="horizontal"\n horizontalAlign="right"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label="Cancel"\n variant="secondary"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = "";\n NewOrderCustomerEmail.text = "";\n NewOrderAmount.text = "";\n NewOrderStatus.metaSelectedOptionValue = "";\n NewOrderNotes.text = "";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal\'s open property directly\n .controlModal("CreateOrderModal", "close")}\n />\n <SbButton\n label="Create Order"\n variant="primary"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, "0")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = "";\n NewOrderCustomerEmail.text = "";\n NewOrderAmount.text = "";\n NewOrderStatus.metaSelectedOptionValue = "";\n NewOrderNotes.text = "";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal\'s open property directly\n .controlModal("CreateOrderModal", "close")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from "@superblocksteam/library";\nimport { Page1 } from "./scope";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text="Orders Management"\n textStyle={{ variant: "heading2" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS((event) => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = event.row.customerName;\n EditOrderCustomerEmail.text = event.row.customerEmail;\n EditOrderAmount.text = event.row.amount;\n EditOrderStatus.metaSelectedOptionValue = event.row.status;\n EditOrderNotes.text = event.row.notes || "";\n })\n // Open the edit modal\n .controlModal("EditOrderModal", "open")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout="vertical" spacing={Dim.px(8)}>\n <SbText\n text="Edit Order"\n textStyle={{\n variant: "heading4",\n }}\n />\n <SbText text="Update the order details below" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label="Customer Name"\n placeholderText="Enter customer name"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label="Customer Email"\n inputType="EMAIL"\n placeholderText="Enter customer email"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label="Order Amount"\n placeholderText="Enter order amount"\n inputType="NUMBER"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label="Order Status"\n options={[\n {\n label: "Pending",\n value: "pending",\n },\n {\n label: "Processing",\n value: "processing",\n },\n {\n label: "En route",\n value: "en_route",\n },\n {\n label: "Delivered",\n value: "delivered",\n },\n {\n label: "Refunded",\n value: "refunded",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label="Order Notes"\n placeholderText="Optional notes about the order"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout="horizontal"\n horizontalAlign="right"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label="Cancel"\n variant="secondary"\n onClick={SbEventFlow.controlModal("EditOrderModal", "close")}\n />\n <SbButton\n label="Save Changes"\n variant="primary"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal("EditOrderModal", "close")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: "John Doe",\n customerEmail: "john@example.com",\n amount: 150.0,\n status: "pending",\n notes: "Rush order",\n createdAt: "2024-01-15T10:30:00Z",\n },\n {\n id: 2,\n customerName: "Jane Smith",\n customerEmail: "jane@example.com",\n amount: 89.99,\n status: "delivered",\n notes: "",\n createdAt: "2024-01-14T14:20:00Z",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere\'s another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label="Edit Selected User"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal("EditUserModal", "open")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `s.row.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout="vertical"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign="right"` for the footer containers in modals that contain buttons\n';
50
+ var content6 = '### Form Layouts in Superblocks\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout="vertical"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label="First Name" bind={FirstName} width={Dim.fill()} />\n <SbInput label="Last Name" bind={LastName} width={Dim.fill()} />\n <SbInput label="Email" bind={Email} inputType="EMAIL" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt\'s common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from "@superblocksteam/library";\nimport { Page1 } from "./scope";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout="vertical" spacing={Dim.px(8)}>\n <SbText\n text="Create New Order"\n textStyle={{\n variant: "heading4",\n }}\n />\n <SbText text="Fill out the form below to create a new order" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label="Customer Name"\n placeholderText="Enter customer name"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label="Customer Email"\n inputType="EMAIL"\n placeholderText="Enter customer email"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label="Order Amount"\n placeholderText="Enter order amount"\n inputType="NUMBER"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label="Order Status"\n options={[\n {\n label: "Pending",\n value: "pending",\n },\n {\n label: "Processing",\n value: "processing",\n },\n {\n label: "En route",\n value: "en_route",\n },\n {\n label: "Delivered",\n value: "delivered",\n },\n {\n label: "Refunded",\n value: "refunded",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label="Order Notes"\n placeholderText="Optional notes about the order"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout="horizontal"\n horizontalAlign="right"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label="Cancel"\n variant="secondary"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = "";\n NewOrderCustomerEmail.text = "";\n NewOrderAmount.text = "";\n NewOrderStatus.metaSelectedOptionValue = "";\n NewOrderNotes.text = "";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal\'s open property directly\n .controlModal("CreateOrderModal", "close")}\n />\n <SbButton\n label="Create Order"\n variant="primary"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, "0")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = "";\n NewOrderCustomerEmail.text = "";\n NewOrderAmount.text = "";\n NewOrderStatus.metaSelectedOptionValue = "";\n NewOrderNotes.text = "";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal\'s open property directly\n .controlModal("CreateOrderModal", "close")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from "@superblocksteam/library";\nimport { Page1 } from "./scope";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text="Orders Management"\n textStyle={{ variant: "heading2" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS(() => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = OrdersTable.selectedRow.customerName;\n EditOrderCustomerEmail.text = OrdersTable.selectedRow.customerEmail;\n EditOrderAmount.text = OrdersTable.selectedRow.amount;\n EditOrderStatus.metaSelectedOptionValue = OrdersTable.selectedRow.status;\n EditOrderNotes.text = OrdersTable.selectedRow.notes || "";\n })\n // Open the edit modal\n .controlModal("EditOrderModal", "open")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout="vertical" spacing={Dim.px(8)}>\n <SbText\n text="Edit Order"\n textStyle={{\n variant: "heading4",\n }}\n />\n <SbText text="Update the order details below" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout="vertical" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label="Customer Name"\n placeholderText="Enter customer name"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label="Customer Email"\n inputType="EMAIL"\n placeholderText="Enter customer email"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label="Order Amount"\n placeholderText="Enter order amount"\n inputType="NUMBER"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label="Order Status"\n options={[\n {\n label: "Pending",\n value: "pending",\n },\n {\n label: "Processing",\n value: "processing",\n },\n {\n label: "En route",\n value: "en_route",\n },\n {\n label: "Delivered",\n value: "delivered",\n },\n {\n label: "Refunded",\n value: "refunded",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label="Order Notes"\n placeholderText="Optional notes about the order"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout="horizontal"\n horizontalAlign="right"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label="Cancel"\n variant="secondary"\n onClick={SbEventFlow.controlModal("EditOrderModal", "close")}\n />\n <SbButton\n label="Save Changes"\n variant="primary"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal("EditOrderModal", "close")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: "John Doe",\n customerEmail: "john@example.com",\n amount: 150.0,\n status: "pending",\n notes: "Rush order",\n createdAt: "2024-01-15T10:30:00Z",\n },\n {\n id: 2,\n customerName: "Jane Smith",\n customerEmail: "jane@example.com",\n amount: 89.99,\n status: "delivered",\n notes: "",\n createdAt: "2024-01-14T14:20:00Z",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere\'s another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label="Edit Selected User"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal("EditUserModal", "open")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `{TableName}.selectedRow.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout="vertical"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign="right"` for the footer containers in modals that contain buttons\n';
51
51
 
52
52
  // ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.js
53
53
  init_cjs_shims();
@@ -177,7 +177,7 @@ var content30 = '## Dim\n\nThe `Dim` class is used to define dimensions for size
177
177
 
178
178
  // ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js
179
179
  init_cjs_shims();
180
- var content31 = '## SbEventFlow\n\nThe `SbEventFlow` class is used to define responses to events triggered on components (like onClick) in Superblocks. It has a number of methods that can be chained together.\n\n```typescript\nclass SbEventFlow {\n // Run custom JavaScript code\n // currentEntity represents the context where the event flow is executed:\n // - If run on a component event handler, currentEntity is the component\n // - If run on an API, currentEntity is the API\n // - etc.\n // NOTE: The actual handler functions should be written in vanilla JavaScript, not TypeScript\n // Arrow functions signature:\n static runJS(handler: (event?: Record<string, any>) => void): SbEventFlow;\n runJS(handler: (event?: Record<string, any>) => void): this;\n\n // Function expressions/declarations signature:\n static runJS(\n handler: (currentEntity: any, event?: Record<string, any>) => void,\n ): SbEventFlow;\n runJS(\n handler: (currentEntity: any, event?: Record<string, any>) => void,\n ): this;\n\n // Navigation methods\n static navigateTo(props: { url: string; newWindow?: boolean }): SbEventFlow;\n navigateTo(props: { url: string; newWindow?: boolean }): this;\n\n static navigateToApp(appId: string): SbEventFlow;\n navigateToApp(appId: string): this;\n\n static navigateToRoute(route: string): SbEventFlow;\n navigateToRoute(route: string): this;\n\n static setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): SbEventFlow;\n setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): this;\n\n // Control whether modals are opened or closed\n // modalId should be the name of the string value of the bind property on the modal component\n static controlModal(modalId: string, action: "open" | "close"): SbEventFlow;\n controlModal(modalId: string, action: "open" | "close"): this;\n\n static controlTimer(\n timerId: string,\n action: "start" | "stop" | "toggle",\n ): SbEventFlow;\n controlTimer(timerId: string, action: "start" | "stop" | "toggle"): this;\n\n // API methods\n static runApis(\n apis: SbApi[],\n onSuccess?: SbEventFlow,\n onError?: SbEventFlow,\n ): SbEventFlow;\n runApis(apis: SbApi[], onSuccess?: SbEventFlow, onError?: SbEventFlow): this;\n\n static cancelApis(apiNames: string[], onCancel?: SbEventFlow): SbEventFlow;\n cancelApis(apiNames: string[], onCancel?: SbEventFlow): this;\n\n // Component and state manipulation\n static resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): SbEventFlow;\n resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): this;\n\n static resetStateVar(stateVar: SbVariable): SbEventFlow;\n resetStateVar(stateVar: SbVariable): this;\n\n static setStateVar(stateVar: SbVariable, value: any): SbEventFlow;\n setStateVar(stateVar: SbVariable, value: any): this;\n\n static setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): SbEventFlow;\n setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): this;\n\n // Utility methods\n static showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): SbEventFlow;\n showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): this;\n\n static setProfile(\n profileId: string,\n profileAction: "set" | "unset",\n ): SbEventFlow;\n setProfile(profileId: string, profileAction: "set" | "unset"): this;\n\n static triggerEvent(\n eventName: string,\n eventData: Record<string, string>,\n ): SbEventFlow;\n triggerEvent(eventName: string, eventData: Record<string, string>): this;\n}\n```\n';
180
+ var content31 = '## SbEventFlow\n\nThe `SbEventFlow` class is used to define responses to events triggered on components (like onClick) in Superblocks. It has a number of methods that can be chained together.\n\n```typescript\nclass SbEventFlow {\n // Run custom JavaScript code\n static runJS(handler: () => void): SbEventFlow;\n runJS(handler: () => void): this;\n\n // Navigation methods\n static navigateTo(props: { url: string; newWindow?: boolean }): SbEventFlow;\n navigateTo(props: { url: string; newWindow?: boolean }): this;\n\n static navigateToApp(appId: string): SbEventFlow;\n navigateToApp(appId: string): this;\n\n static navigateToRoute(route: string): SbEventFlow;\n navigateToRoute(route: string): this;\n\n static setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): SbEventFlow;\n setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): this;\n\n // Control whether modals are opened or closed\n // modalId should be the name of the string value of the bind property on the modal component\n static controlModal(modalId: string, action: "open" | "close"): SbEventFlow;\n controlModal(modalId: string, action: "open" | "close"): this;\n\n static controlTimer(\n timerId: string,\n action: "start" | "stop" | "toggle",\n ): SbEventFlow;\n controlTimer(timerId: string, action: "start" | "stop" | "toggle"): this;\n\n // API methods\n static runApis(\n apis: SbApi[],\n onSuccess?: SbEventFlow,\n onError?: SbEventFlow,\n ): SbEventFlow;\n runApis(apis: SbApi[], onSuccess?: SbEventFlow, onError?: SbEventFlow): this;\n\n static cancelApis(apiNames: string[], onCancel?: SbEventFlow): SbEventFlow;\n cancelApis(apiNames: string[], onCancel?: SbEventFlow): this;\n\n // Component and state manipulation\n static resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): SbEventFlow;\n resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): this;\n\n static resetStateVar(stateVar: SbVariable): SbEventFlow;\n resetStateVar(stateVar: SbVariable): this;\n\n static setStateVar(stateVar: SbVariable, value: any): SbEventFlow;\n setStateVar(stateVar: SbVariable, value: any): this;\n\n static setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): SbEventFlow;\n setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): this;\n\n // Utility methods\n static showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): SbEventFlow;\n showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): this;\n\n static setProfile(\n profileId: string,\n profileAction: "set" | "unset",\n ): SbEventFlow;\n setProfile(profileId: string, profileAction: "set" | "unset"): this;\n\n static triggerEvent(\n eventName: string,\n eventData: Record<string, string>,\n ): SbEventFlow;\n triggerEvent(eventName: string, eventData: Record<string, string>): this;\n}\n```\n';
181
181
  export {
182
182
  library_components_exports as library_components,
183
183
  library_typedefs_exports as library_typedefs,