Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/connect-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

# Changelog

## [2.5.0] - 2025-12-11

### Added

- Support for new app filtering options in `SelectApp` and `useApps`: `hasActions`, `hasTriggers`, `hasComponents`

### Changed

- Updated `@pipedream/sdk` dependency to `^2.3.4`

## [2.4.1] - 2025-12-11

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions packages/connect-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/connect-react",
"version": "2.4.1",
"version": "2.5.0",
"description": "Pipedream Connect library for React",
"files": [
"dist"
Expand Down Expand Up @@ -31,7 +31,7 @@
"author": "Pipedream Engineering",
"license": "MIT",
"dependencies": {
"@pipedream/sdk": "^2.0.13",
"@pipedream/sdk": "^2.3.4",
"@tanstack/react-query": "^5.59.16",
"lodash.isequal": "^4.5.0",
"react-markdown": "^9.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/connect-react/src/components/Control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function Control<T extends ConfigurableProps, U extends ConfigurableProp>

if ("options" in prop && Array.isArray(prop.options) && prop.options.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const options: LabelValueOption<any>[] = prop.options.map(sanitizeOption);
const options: LabelValueOption<any>[] = (prop.options as any[]).map(sanitizeOption);
return <ControlSelect options={options} components={{
IndicatorSeparator: () => null,
}} />;
Expand Down
4 changes: 2 additions & 2 deletions packages/connect-react/src/components/ControlApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type { OptionProps } from "react-select";
import type {
Account,
App,
ConfigurablePropApp,
ConfigurableProp,
} from "@pipedream/sdk";

const BaseOption = (props: OptionProps<SelectValue>) => {
Expand Down Expand Up @@ -46,7 +46,7 @@ export function ControlApp({ app }: ControlAppProps) {
const {
externalUserId, oauthAppConfig,
} = useFormContext();
const formFieldCtx = useFormFieldContext<ConfigurablePropApp>();
const formFieldCtx = useFormFieldContext<ConfigurableProp.App>();
const {
id, prop, value, onChange,
} = formFieldCtx;
Expand Down
4 changes: 2 additions & 2 deletions packages/connect-react/src/components/ControlBoolean.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ConfigurablePropBoolean } from "@pipedream/sdk";
import type { ConfigurableProp } from "@pipedream/sdk";
import { useFormFieldContext } from "../hooks/form-field-context";
import { useCustomize } from "../hooks/customization-context";
import type { CSSProperties } from "react";

export function ControlBoolean() {
const formFieldContextProps = useFormFieldContext<ConfigurablePropBoolean>();
const formFieldContextProps = useFormFieldContext<ConfigurableProp.Boolean>();
const {
id, value, onChange,
} = formFieldContextProps;
Expand Down
12 changes: 4 additions & 8 deletions packages/connect-react/src/hooks/customization-context.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import type {
ConfigurableProp,
ConfigurablePropApp,
ConfigurablePropBoolean,
} from "@pipedream/sdk";
import type { ConfigurableProp } from "@pipedream/sdk";
import type {
ComponentProps, CSSProperties, JSXElementConstructor,
} from "react";
Expand Down Expand Up @@ -75,11 +71,11 @@ export type CustomizationOpts<P extends ComponentProps<JSXElementConstructor<any

export type CustomizableProps = {
componentForm: ComponentProps<typeof ComponentForm>;
connectButton: ComponentProps<typeof ControlApp> & FormFieldContext<ConfigurablePropApp>;
connectButton: ComponentProps<typeof ControlApp> & FormFieldContext<ConfigurableProp.App>;
controlAny: ComponentProps<typeof ControlAny> & FormFieldContext<ConfigurableProp>;
controlApp: ComponentProps<typeof ControlApp> & FormFieldContext<ConfigurablePropApp>;
controlApp: ComponentProps<typeof ControlApp> & FormFieldContext<ConfigurableProp.App>;
controlArray: ComponentProps<typeof ControlArray> & FormFieldContext<ConfigurableProp>;
controlBoolean: ComponentProps<typeof ControlBoolean> & FormFieldContext<ConfigurablePropBoolean>;
controlBoolean: ComponentProps<typeof ControlBoolean> & FormFieldContext<ConfigurableProp.Boolean>;
controlHttpRequest: ComponentProps<typeof ControlHttpRequest> & FormFieldContext<ConfigurableProp>;
controlInput: ComponentProps<typeof ControlInput> & FormFieldContext<ConfigurableProp>;
controlObject: ComponentProps<typeof ControlObject> & FormFieldContext<ConfigurableProp>;
Expand Down
3 changes: 1 addition & 2 deletions packages/connect-react/src/hooks/form-field-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import {
} from "react";
import type {
ConfigurableProp,
ConfigurablePropApp,
PropValue,
} from "@pipedream/sdk";
import type { App } from "@pipedream/sdk";

export type FormFieldContextExtra<T extends ConfigurableProp> = T extends ConfigurablePropApp ? {
export type FormFieldContextExtra<T extends ConfigurableProp> = T extends ConfigurableProp.App ? {
app?: App;
} : object;

Expand Down
2 changes: 2 additions & 0 deletions packages/connect-react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export type RawPropOption<
| NestedLabelValueOption<T>
| { lv: LabelValueOption<T> | LabelValueOption<T>[] }
| LabelValueOption<T>
| null
| undefined

export type ConfigureComponentContext = Record<string, unknown>

Expand Down
5 changes: 3 additions & 2 deletions packages/connect-react/src/utils/component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type {
App,
ConfigurableProp,
ConfigurablePropApp,
ConfigurablePropBoolean,
ConfigurablePropInteger,
Expand Down Expand Up @@ -57,7 +56,9 @@ export function valuesFromOptions<T extends SdkPropOptionValue>(value: unknown |
return value as T[]
}

export type ValidationOpts<T extends ConfigurableProp> = {
// Use a more permissive constraint that works with base prop types
// (e.g., ConfigurablePropInteger) which don't have the 'type' discriminator
export type ValidationOpts<T> = {
prop: T
value: unknown
app?: App
Expand Down
63 changes: 23 additions & 40 deletions packages/connect-react/src/utils/type-guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,6 @@ import {
} from "../types";
import type {
ConfigurableProp,
ConfigurablePropAirtableBaseId,
ConfigurablePropAirtableFieldId,
ConfigurablePropAirtableTableId,
ConfigurablePropAirtableViewId,
ConfigurablePropAlert,
ConfigurablePropAny,
ConfigurablePropApp,
ConfigurablePropApphook,
ConfigurablePropBoolean,
ConfigurablePropDb,
ConfigurablePropDiscordChannel,
ConfigurablePropDiscordChannelArray,
ConfigurablePropHttp,
ConfigurablePropInteger,
ConfigurablePropIntegerArray,
ConfigurablePropObject,
ConfigurablePropSql,
ConfigurablePropString,
ConfigurablePropStringArray,
ConfigurablePropTimer,
PropOptionNested, PropOptionValue,
} from "@pipedream/sdk";

Expand All @@ -40,28 +20,31 @@ export function isString(value: unknown): value is string {
* Mapping of configurable prop types to their corresponding TypeScript types.
* This map is used to determine the specific type of a ConfigurableProp based
* on its 'type' discriminator.
*
* Note: Uses ConfigurableProp namespace types (not base types) because these
* include the 'type' discriminator needed for narrowing.
*/
type DiscriminatorPropTypeMap = {
"$.airtable.baseId": ConfigurablePropAirtableBaseId;
"$.airtable.fieldId": ConfigurablePropAirtableFieldId;
"$.airtable.tableId": ConfigurablePropAirtableTableId;
"$.airtable.viewId": ConfigurablePropAirtableViewId;
"$.discord.channel": ConfigurablePropDiscordChannel;
"$.discord.channel[]": ConfigurablePropDiscordChannelArray;
"$.interface.apphook": ConfigurablePropApphook;
"$.interface.http": ConfigurablePropHttp;
"$.interface.timer": ConfigurablePropTimer;
"$.service.db": ConfigurablePropDb;
"integer[]": ConfigurablePropIntegerArray;
"string[]": ConfigurablePropStringArray;
alert: ConfigurablePropAlert;
any: ConfigurablePropAny;
app: ConfigurablePropApp;
boolean: ConfigurablePropBoolean;
integer: ConfigurablePropInteger;
object: ConfigurablePropObject;
sql: ConfigurablePropSql;
string: ConfigurablePropString;
"$.airtable.baseId": ConfigurableProp.AirtableBaseId;
"$.airtable.fieldId": ConfigurableProp.AirtableFieldId;
"$.airtable.tableId": ConfigurableProp.AirtableTableId;
"$.airtable.viewId": ConfigurableProp.AirtableViewId;
"$.discord.channel": ConfigurableProp.DiscordChannel;
"$.discord.channel[]": ConfigurableProp.DiscordChannelArray;
"$.interface.apphook": ConfigurableProp.InterfaceApphook;
"$.interface.http": ConfigurableProp.InterfaceHttp;
"$.interface.timer": ConfigurableProp.InterfaceTimer;
"$.service.db": ConfigurableProp.ServiceDb;
"integer[]": ConfigurableProp.IntegerArray;
"string[]": ConfigurableProp.StringArray;
alert: ConfigurableProp.Alert;
any: ConfigurableProp.Any;
app: ConfigurableProp.App;
boolean: ConfigurableProp.Boolean;
integer: ConfigurableProp.Integer;
object: ConfigurableProp.Object_;
sql: ConfigurableProp.Sql;
string: ConfigurableProp.String;
}

/**
Expand Down
Loading
Loading