diff --git a/packages/connect-react/CHANGELOG.md b/packages/connect-react/CHANGELOG.md index 80d81233656f6..b300a3464ff29 100644 --- a/packages/connect-react/CHANGELOG.md +++ b/packages/connect-react/CHANGELOG.md @@ -2,6 +2,10 @@ # Changelog +# [1.0.3] - 2025-05-16 + +- Improved `ConfigurableProp` type + # [1.0.2] - 2025-04-24 - Updating README to remove note about this package being in early preview diff --git a/packages/sdk/src/shared/component.ts b/packages/sdk/src/shared/component.ts index 1821740db0eac..dbe35179db594 100644 --- a/packages/sdk/src/shared/component.ts +++ b/packages/sdk/src/shared/component.ts @@ -54,8 +54,11 @@ type BaseConfigurableProp = { withLabel?: boolean; }; -// XXX fix duplicating mapping to value type here and with PropValue -type Defaultable = { default?: T; options?: T[]; }; +type Defaultable = { default?: T; options?: T[] }; + +// Define a type for string-based property options +export type StringPropOptionObject = { label?: string; value: string }; +export type StringPropOption = string | StringPropOptionObject; export type ConfigurablePropAlert = BaseConfigurableProp & { type: "alert"; @@ -69,7 +72,9 @@ export type ConfigurablePropApp = BaseConfigurableProp & { type: "app"; app: string; }; -export type ConfigurablePropBoolean = BaseConfigurableProp & { type: "boolean"; }; +export type ConfigurablePropBoolean = BaseConfigurableProp & { + type: "boolean"; +} & Defaultable; export type ConfigurablePropInteger = BaseConfigurableProp & { type: "integer"; min?: number; @@ -81,54 +86,114 @@ export type ConfigurablePropObject = BaseConfigurableProp & { export type ConfigurablePropString = BaseConfigurableProp & { type: "string"; secret?: boolean; -} & Defaultable; + default?: string; + options?: StringPropOption[]; +}; export type ConfigurablePropStringArray = BaseConfigurableProp & { type: "string[]"; secret?: boolean; // TODO is this supported -} & Defaultable; // TODO -// | { type: "$.interface.http" } // source only -// | { type: "$.interface.timer" } // source only -// | { type: "$.service.db" } -// | { type: "data_store" } -// | { type: "http_request" } -// | { type: "sql" } -- not in component api docs! + default?: string[]; + options?: StringPropOption[]; +}; +export type ConfigurablePropIntegerArray = BaseConfigurableProp & { + type: "integer[]"; +} & Defaultable; +export type ConfigurablePropBooleanArray = BaseConfigurableProp & { + type: "boolean[]"; +} & Defaultable; +export type ConfigurablePropDiscordChannel = BaseConfigurableProp & { + type: "$.discord.channel"; + [key: string]: unknown; +} & Defaultable; +export type ConfigurablePropDiscordChannelArray = BaseConfigurableProp & { + type: "$.discord.channel[]"; + [key: string]: unknown; +} & Defaultable; + +export type ConfigurablePropInterfaceHttp = BaseConfigurableProp & { + type: "$.interface.http"; + [key: string]: unknown; +}; +export type ConfigurablePropInterfaceTimer = BaseConfigurableProp & { + type: "$.interface.timer"; + [key: string]: unknown; +}; +export type ConfigurablePropServiceDb = BaseConfigurableProp & { + type: "$.service.db"; + [key: string]: unknown; +}; +export type ConfigurablePropDataStore = BaseConfigurableProp & { + type: "datastore"; + [key: string]: unknown; +}; +export type ConfigurablePropHttpRequest = BaseConfigurableProp & { + type: "http_request"; + [key: string]: unknown; +}; +export type ConfigurablePropSql = BaseConfigurableProp & { type: "sql" }; + export type ConfigurableProp = | ConfigurablePropAlert | ConfigurablePropAny | ConfigurablePropApp | ConfigurablePropBoolean + | ConfigurablePropBooleanArray | ConfigurablePropInteger + | ConfigurablePropIntegerArray | ConfigurablePropObject | ConfigurablePropString | ConfigurablePropStringArray - | (BaseConfigurableProp & { type: "$.discord.channel"; }); + | ConfigurablePropDiscordChannel + | ConfigurablePropDiscordChannelArray + | ConfigurablePropInterfaceHttp + | ConfigurablePropInterfaceTimer + | ConfigurablePropServiceDb + | ConfigurablePropDataStore + | ConfigurablePropHttpRequest + | ConfigurablePropSql; export type ConfigurableProps = Readonly; export type PropValue = T extends "alert" ? never : T extends "any" - ? any // eslint-disable-line @typescript-eslint/no-explicit-any - : T extends "app" - ? { authProvisionId: string; } - : T extends "boolean" - ? boolean - : T extends "integer" - ? number - : T extends "object" - ? object - : T extends "string" - ? string - : T extends "string[]" - ? string[] // XXX support arrays differently? - : never; + ? any // eslint-disable-line @typescript-eslint/no-explicit-any + : T extends "app" + ? { authProvisionId: string } + : T extends "boolean" + ? boolean + : T extends "boolean[]" + ? boolean[] + : T extends "integer" + ? number + : T extends "integer[]" + ? number[] + : T extends "object" + ? object + : T extends "string" + ? string + : T extends "string[]" + ? string[] + : T extends "$.discord.channel" + ? string + : T extends "$.discord.channel[]" + ? string[] + : T extends + | "$.interface.http" + | "$.interface.timer" + | "$.service.db" + | "datastore" + | "http_request" + | "sql" + ? unknown + : never; export type ConfiguredProps = { - [K in T[number] as K["name"]]?: PropValue + [K in T[number] as K["name"]]?: PropValue; }; // as returned by API (configurable_props_json from `afterSave`) -export type V1Component = { // eslint-disable-line @typescript-eslint/no-explicit-any +export type V1Component = { name: string; key: string; version: string; @@ -137,7 +202,9 @@ export type V1Component = { // eslint-disable component_type?: string; }; -export type V1DeployedComponent = { // eslint-disable-line @typescript-eslint/no-explicit-any +export type V1DeployedComponent< + T extends ConfigurableProps = ConfigurableProps, +> = { id: string; owner_id: string; component_id: string; @@ -171,4 +238,4 @@ export type V1EmittedEvent = { * The event's unique ID. */ id: string; -} +};