use serde::{Deserialize, Serialize}; use std::collections::HashMap; use tauri::{Runtime, WebviewWindow}; use ts_rs::TS; use yaak_common::window::WorkspaceWindowTrait; use yaak_models::models::{ Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, WebsocketRequest, Workspace, }; use yaak_models::util::generate_prefixed_id; #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct InternalEvent { pub id: String, pub plugin_ref_id: String, pub plugin_name: String, pub reply_id: Option, pub context: PluginContext, pub payload: InternalEventPayload, } /// Special type used to deserialize everything but the payload. This is so we can /// catch any plugin-related type errors, since payload is sent by the plugin author /// and all other fields are sent by Yaak first-party code. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct InternalEventRawPayload { pub id: String, pub plugin_ref_id: String, pub plugin_name: String, pub reply_id: Option, pub context: PluginContext, pub payload: serde_json::Value, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct PluginContext { pub id: String, pub label: Option, pub workspace_id: Option, } impl PluginContext { pub fn new_empty() -> Self { Self { id: "default".to_string(), label: None, workspace_id: None } } pub fn new(window: &WebviewWindow) -> Self { Self { label: Some(window.label().to_string()), workspace_id: window.workspace_id(), id: generate_prefixed_id("pctx"), } } } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case", tag = "type")] #[ts(export, export_to = "gen_events.ts")] pub enum InternalEventPayload { BootRequest(BootRequest), BootResponse, ReloadResponse(ReloadResponse), TerminateRequest, TerminateResponse, ImportRequest(ImportRequest), ImportResponse(ImportResponse), FilterRequest(FilterRequest), FilterResponse(FilterResponse), ExportHttpRequestRequest(ExportHttpRequestRequest), ExportHttpRequestResponse(ExportHttpRequestResponse), SendHttpRequestRequest(SendHttpRequestRequest), SendHttpRequestResponse(SendHttpRequestResponse), ListCookieNamesRequest(ListCookieNamesRequest), ListCookieNamesResponse(ListCookieNamesResponse), GetCookieValueRequest(GetCookieValueRequest), GetCookieValueResponse(GetCookieValueResponse), // HTTP Request Actions GetHttpRequestActionsRequest(EmptyPayload), GetHttpRequestActionsResponse(GetHttpRequestActionsResponse), CallHttpRequestActionRequest(CallHttpRequestActionRequest), // Grpc Request Actions GetGrpcRequestActionsRequest(EmptyPayload), GetGrpcRequestActionsResponse(GetGrpcRequestActionsResponse), CallGrpcRequestActionRequest(CallGrpcRequestActionRequest), // Template Functions GetTemplateFunctionSummaryRequest(EmptyPayload), GetTemplateFunctionSummaryResponse(GetTemplateFunctionSummaryResponse), GetTemplateFunctionConfigRequest(GetTemplateFunctionConfigRequest), GetTemplateFunctionConfigResponse(GetTemplateFunctionConfigResponse), CallTemplateFunctionRequest(CallTemplateFunctionRequest), CallTemplateFunctionResponse(CallTemplateFunctionResponse), // Http Authentication GetHttpAuthenticationSummaryRequest(EmptyPayload), GetHttpAuthenticationSummaryResponse(GetHttpAuthenticationSummaryResponse), GetHttpAuthenticationConfigRequest(GetHttpAuthenticationConfigRequest), GetHttpAuthenticationConfigResponse(GetHttpAuthenticationConfigResponse), CallHttpAuthenticationRequest(CallHttpAuthenticationRequest), CallHttpAuthenticationResponse(CallHttpAuthenticationResponse), CallHttpAuthenticationActionRequest(CallHttpAuthenticationActionRequest), CallHttpAuthenticationActionResponse(EmptyPayload), CopyTextRequest(CopyTextRequest), CopyTextResponse(EmptyPayload), RenderHttpRequestRequest(RenderHttpRequestRequest), RenderHttpRequestResponse(RenderHttpRequestResponse), RenderGrpcRequestRequest(RenderGrpcRequestRequest), RenderGrpcRequestResponse(RenderGrpcRequestResponse), TemplateRenderRequest(TemplateRenderRequest), TemplateRenderResponse(TemplateRenderResponse), GetKeyValueRequest(GetKeyValueRequest), GetKeyValueResponse(GetKeyValueResponse), SetKeyValueRequest(SetKeyValueRequest), SetKeyValueResponse(SetKeyValueResponse), DeleteKeyValueRequest(DeleteKeyValueRequest), DeleteKeyValueResponse(DeleteKeyValueResponse), OpenWindowRequest(OpenWindowRequest), WindowNavigateEvent(WindowNavigateEvent), WindowCloseEvent, CloseWindowRequest(CloseWindowRequest), ShowToastRequest(ShowToastRequest), ShowToastResponse(EmptyPayload), PromptTextRequest(PromptTextRequest), PromptTextResponse(PromptTextResponse), WindowInfoRequest(WindowInfoRequest), WindowInfoResponse(WindowInfoResponse), GetHttpRequestByIdRequest(GetHttpRequestByIdRequest), GetHttpRequestByIdResponse(GetHttpRequestByIdResponse), FindHttpResponsesRequest(FindHttpResponsesRequest), FindHttpResponsesResponse(FindHttpResponsesResponse), GetThemesRequest(GetThemesRequest), GetThemesResponse(GetThemesResponse), /// Returned when a plugin doesn't get run, just so the server /// has something to listen for EmptyResponse(EmptyPayload), ErrorResponse(ErrorResponse), } impl InternalEventPayload { pub fn type_name(&self) -> String { if let Ok(serde_json::Value::Object(map)) = serde_json::to_value(self) { map.get("type").map(|s| s.as_str().unwrap_or("unknown").to_string()) } else { None } .unwrap_or("invalid_event".to_string()) } } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default)] #[ts(export, type = "{}", export_to = "gen_events.ts")] pub struct EmptyPayload {} #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default)] #[ts(export, export_to = "gen_events.ts")] pub struct ErrorResponse { pub error: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct BootRequest { pub dir: String, pub watch: bool, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ReloadResponse { pub silent: bool, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ImportRequest { pub content: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ImportResponse { pub resources: ImportResources, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct FilterRequest { pub content: String, pub filter: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct FilterResponse { pub content: String, #[ts(optional)] pub error: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ExportHttpRequestRequest { pub http_request: HttpRequest, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ExportHttpRequestResponse { pub content: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct SendHttpRequestRequest { #[ts(type = "Partial")] pub http_request: HttpRequest, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct SendHttpRequestResponse { pub http_response: HttpResponse, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default)] #[ts(export, type = "{}", export_to = "gen_events.ts")] pub struct ListCookieNamesRequest {} #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ListCookieNamesResponse { pub names: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetCookieValueRequest { pub name: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetCookieValueResponse { pub value: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CopyTextRequest { pub text: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct RenderHttpRequestRequest { pub http_request: HttpRequest, pub purpose: RenderPurpose, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct RenderHttpRequestResponse { pub http_request: HttpRequest, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct RenderGrpcRequestRequest { pub grpc_request: GrpcRequest, pub purpose: RenderPurpose, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct RenderGrpcRequestResponse { pub grpc_request: GrpcRequest, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetThemesRequest {} #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ThemeComponents { #[ts(optional)] pub dialog: Option, #[ts(optional)] pub menu: Option, #[ts(optional)] pub toast: Option, #[ts(optional)] pub sidebar: Option, #[ts(optional)] pub response_pane: Option, #[ts(optional)] pub app_header: Option, #[ts(optional)] pub button: Option, #[ts(optional)] pub banner: Option, #[ts(optional)] pub template_tag: Option, #[ts(optional)] pub url_bar: Option, #[ts(optional)] pub editor: Option, #[ts(optional)] pub input: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ThemeComponentColors { #[ts(optional)] pub surface: Option, #[ts(optional)] pub surface_highlight: Option, #[ts(optional)] pub surface_active: Option, #[ts(optional)] pub text: Option, #[ts(optional)] pub text_subtle: Option, #[ts(optional)] pub text_subtlest: Option, #[ts(optional)] pub border: Option, #[ts(optional)] pub border_subtle: Option, #[ts(optional)] pub border_focus: Option, #[ts(optional)] pub shadow: Option, #[ts(optional)] pub backdrop: Option, #[ts(optional)] pub selection: Option, #[ts(optional)] pub primary: Option, #[ts(optional)] pub secondary: Option, #[ts(optional)] pub info: Option, #[ts(optional)] pub success: Option, #[ts(optional)] pub notice: Option, #[ts(optional)] pub warning: Option, #[ts(optional)] pub danger: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct Theme { /// How the theme is identified. This should never be changed pub id: String, /// The friendly name of the theme to be displayed to the user pub label: String, /// Whether the theme will be used for dark or light appearance pub dark: bool, /// The default top-level colors for the theme pub base: ThemeComponentColors, /// Optionally override theme for individual UI components for more control #[ts(optional)] pub components: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetThemesResponse { pub themes: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct TemplateRenderRequest { pub data: serde_json::Value, pub purpose: RenderPurpose, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct TemplateRenderResponse { pub data: serde_json::Value, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct OpenWindowRequest { pub url: String, /// Label for the window. If not provided, a random one will be generated. pub label: String, #[ts(optional)] pub title: Option, #[ts(optional)] pub size: Option, #[ts(optional)] pub data_dir_key: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct WindowSize { pub width: f64, pub height: f64, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CloseWindowRequest { pub label: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct WindowNavigateEvent { pub url: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct ShowToastRequest { pub message: String, #[ts(optional)] pub color: Option, #[ts(optional)] pub icon: Option, #[ts(optional)] pub timeout: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct PromptTextRequest { // A unique ID to identify the prompt (eg. "enter-password") pub id: String, // Title to show on the prompt dialog pub title: String, // Text to show on the label above the input pub label: String, #[ts(optional)] pub description: Option, #[ts(optional)] pub default_value: Option, #[ts(optional)] pub placeholder: Option, /// Text to add to the confirmation button #[ts(optional)] pub confirm_text: Option, #[ts(optional)] pub password: Option, /// Text to add to the cancel button #[ts(optional)] pub cancel_text: Option, /// Require the user to enter a non-empty value #[ts(optional)] pub required: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct PromptTextResponse { pub value: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct WindowInfoRequest { pub label: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct WindowInfoResponse { pub request_id: Option, pub environment_id: Option, pub workspace_id: Option, pub label: String, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case")] #[ts(export, export_to = "gen_events.ts")] pub enum Color { Primary, Secondary, Info, Success, Notice, Warning, Danger, } impl Default for Color { fn default() -> Self { Color::Secondary } } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case")] #[ts(export, export_to = "gen_events.ts")] pub enum Icon { AlertTriangle, Check, CheckCircle, ChevronDown, Copy, Info, Pin, Search, Trash, #[serde(untagged)] #[ts(type = "\"_unknown\"")] _Unknown(String), } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetHttpAuthenticationSummaryResponse { pub name: String, pub label: String, pub short_label: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct HttpAuthenticationAction { pub label: String, #[ts(optional)] pub icon: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetHttpAuthenticationConfigRequest { pub context_id: String, pub values: HashMap, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetHttpAuthenticationConfigResponse { pub args: Vec, pub plugin_ref_id: String, #[ts(optional)] pub actions: Option>, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct HttpHeader { pub name: String, pub value: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CallHttpAuthenticationRequest { pub context_id: String, pub values: HashMap, pub method: String, pub url: String, pub headers: Vec, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CallHttpAuthenticationActionRequest { pub index: i32, pub plugin_ref_id: String, pub args: CallHttpAuthenticationActionArgs, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CallHttpAuthenticationActionArgs { pub context_id: String, pub values: HashMap, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(untagged)] #[ts(export, export_to = "gen_events.ts")] pub enum JsonPrimitive { String(String), Number(f64), Boolean(bool), Null, } impl From for JsonPrimitive { fn from(value: serde_json::Value) -> Self { match value { serde_json::Value::Null => JsonPrimitive::Null, serde_json::Value::Bool(b) => JsonPrimitive::Boolean(b), serde_json::Value::Number(n) => JsonPrimitive::Number(n.as_f64().unwrap()), serde_json::Value::String(s) => JsonPrimitive::String(s), v => panic!("Unsupported JSON primitive type {:?}", v), } } } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct CallHttpAuthenticationResponse { /// HTTP headers to add to the request. Existing headers will be replaced, while /// new headers will be added. #[ts(optional)] pub set_headers: Option>, /// Query parameters to add to the request. Existing params will be replaced, while /// new params will be added. #[ts(optional)] pub set_query_parameters: Option>, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetTemplateFunctionSummaryResponse { pub functions: Vec, pub plugin_ref_id: String, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetTemplateFunctionConfigRequest { pub context_id: String, pub name: String, pub values: HashMap, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct GetTemplateFunctionConfigResponse { pub function: TemplateFunction, pub plugin_ref_id: String, } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case")] #[ts(export, export_to = "gen_events.ts")] pub enum TemplateFunctionPreviewType { Live, Click, None, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct TemplateFunction { pub name: String, #[ts(optional)] pub preview_type: Option, #[ts(optional)] pub description: Option, /// Also support alternative names. This is useful for not breaking existing /// tags when changing the `name` property #[ts(optional)] pub aliases: Option>, pub args: Vec, /// A list of arg names to show in the inline preview. If not provided, none will be shown (for privacy reasons). #[ts(optional)] pub preview_args: Option>, } /// Similar to FormInput, but contains #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case", untagged)] #[ts(export, export_to = "gen_events.ts")] pub enum TemplateFunctionArg { FormInput(FormInput), } #[derive(Debug, Clone, Serialize, Deserialize, TS)] #[serde(rename_all = "snake_case", tag = "type")] #[ts(export, export_to = "gen_events.ts")] pub enum FormInput { Text(FormInputText), Editor(FormInputEditor), Select(FormInputSelect), Checkbox(FormInputCheckbox), File(FormInputFile), HttpRequest(FormInputHttpRequest), Accordion(FormInputAccordion), HStack(FormInputHStack), Banner(FormInputBanner), Markdown(FormInputMarkdown), } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct FormInputBase { /// The name of the input. The value will be stored at this object attribute in the resulting data pub name: String, /// Whether this input is visible for the given configuration. Use this to /// make branching forms. #[ts(optional)] pub hidden: Option, /// Whether the user must fill in the argument #[ts(optional)] pub optional: Option, /// The label of the input #[ts(optional)] pub label: Option, /// Visually hide the label of the input #[ts(optional)] pub hide_label: Option, /// The default value #[ts(optional)] pub default_value: Option, #[ts(optional)] pub disabled: Option, /// Longer description of the input, likely shown in a tooltip #[ts(optional)] pub description: Option, } #[derive(Debug, Clone, Default, Serialize, Deserialize, TS)] #[serde(default, rename_all = "camelCase")] #[ts(export, export_to = "gen_events.ts")] pub struct FormInputText { #[serde(flatten)] pub base: FormInputBase, /// Placeholder for the text input #[ts(optional = nullable)] pub placeholder: Option, /// Placeholder for the text input #[ts(optional)] pub password: Option, /// Whether to allow newlines in the input, like a