This guide will help you migrate your existing Pipedream SDK v2.x integration to the latest version. If you are still on v1.x, start with the v1.x migration guide first.
- Migrating from v2.x
- Table of contents
- Deprecation
- Breaking changes
- Unchanged in v3.x
- Type migration
- Type mapping
- New features in v3.x
- Partial migration
- Important removed functionality
- Migration checklist
The v2.x version of the Pipedream SDK is now deprecated. This means that no changes will be made to this version unless there are critical security issues. We recommend that you migrate to the latest version of the SDK to take advantage of new features, improvements, and bug fixes if possible.
The v3.x SDK is a focused type-system release. The runtime behavior, network calls, environment variables, and public method surface are all unchanged from v2.x — the only changes you need to make are to TypeScript code that imports or narrows the affected types. Below is a summary of the breaking changes:
- Flattened
ConfigurablePropunion: TheConfigurablePropnamespace has been removed. Variants likePipedream.ConfigurableProp.Alertare now imported directly asPipedream.ConfigurablePropAlert. - Flattened
Emitterunion: TheEmitternamespace has been removed.Pipedream.Emitter.DeployedComponentis nowPipedream.DeployedComponent, and likewise forHttpInterfaceandTimerInterface. ConfigurablePropBaseno longer extended: EachConfigurableProp{Variant}interface now inlines the base fields (name,label,description,optional,disabled,readOnly,hidden,remoteOptions,useQuery,reloadProps,withLabel) and includes its literaltypefield directly. The shape of values your code receives is unchanged, but any code that referencesConfigurablePropBasedirectly must be updated.- Discord prop types removed:
ConfigurablePropDiscordandConfigurablePropDiscordTypehave been removed. Use the existingConfigurablePropDiscordChannelandConfigurablePropDiscordChannelArrayvariants instead. typediscriminator added to emitter members:DeployedComponent,HttpInterface, andTimerInterfaceeach now carry a literaltypefield ("DeployedComponent","HttpInterface","TimerInterface"). This is additive on responses you read, but if your code constructs these objects by hand you'll need to include the new field.
To save you time scanning the rest of this guide, the following remain identical to v2.x:
- Client initialization (
new PipedreamClient({ … })) and all constructor options (clientId,clientSecret,projectId,projectEnvironment,workflowDomain,tokenCallback, etc.). - All environment variables (
PIPEDREAM_CLIENT_ID,PIPEDREAM_CLIENT_SECRET,PIPEDREAM_PROJECT_ID,PIPEDREAM_PROJECT_ENVIRONMENT,PIPEDREAM_BASE_URL,PIPEDREAM_WORKFLOW_DOMAIN). - All namespaced method names and signatures (
client.actions.run(),client.proxy.get(),client.workflows.invoke(), etc.). - Browser/server entrypoints (
@pipedream/sdk,@pipedream/sdk/browser,@pipedream/sdk/server). - Pagination, request options, abort signals, and
.withRawResponse()chaining. - The
PipedreamErrorclass and error-handling shape.
If your v2.x code does not import any ConfigurableProp* or Emitter* types
explicitly, it will most likely compile against v3.x without changes.
The ConfigurableProp discriminated union now references the per-variant
interfaces directly instead of nesting them under a namespace.
import { Pipedream } from '@pipedream/sdk';
function describeProp(prop: Pipedream.ConfigurableProp) {
if (prop.type === 'alert') {
const alert: Pipedream.ConfigurableProp.Alert = prop;
return alert.content;
}
if (prop.type === 'app') {
const app: Pipedream.ConfigurableProp.App = prop;
return app.name;
}
}import { Pipedream } from '@pipedream/sdk';
function describeProp(prop: Pipedream.ConfigurableProp) {
if (prop.type === 'alert') {
const alert: Pipedream.ConfigurablePropAlert = prop;
return alert.content;
}
if (prop.type === 'app') {
const app: Pipedream.ConfigurablePropApp = prop;
return app.name;
}
}A complete name-by-name table is in Type mapping below.
Each ConfigurableProp{Variant} interface used to extend
ConfigurablePropBase. In v3.x, the base fields are inlined into every variant
and the literal type field is part of the variant interface itself. The fields
you can read from a value are unchanged — only code that references
ConfigurablePropBase directly needs to be updated.
import { type Pipedream } from '@pipedream/sdk';
// `ConfigurablePropBase` could be used to type any "shared" prop fields
function isOptional(prop: Pipedream.ConfigurablePropBase): boolean {
return prop.optional ?? false;
}import { type Pipedream } from '@pipedream/sdk';
// Use the union directly — every variant carries the previously-shared fields
function isOptional(prop: Pipedream.ConfigurableProp): boolean {
return prop.optional ?? false;
}Same flattening as ConfigurableProp: Pipedream.Emitter is now a union of the
underlying types directly, with no namespaced wrappers.
import { Pipedream } from '@pipedream/sdk';
function emitterId(e: Pipedream.Emitter): string {
if (e.type === 'DeployedComponent') {
const dc: Pipedream.Emitter.DeployedComponent = e;
return dc.id;
}
if (e.type === 'HttpInterface') {
const http: Pipedream.Emitter.HttpInterface = e;
return http.id;
}
const timer: Pipedream.Emitter.TimerInterface = e;
return timer.id;
}import { Pipedream } from '@pipedream/sdk';
function emitterId(e: Pipedream.Emitter): string {
if (e.type === 'DeployedComponent') {
const dc: Pipedream.DeployedComponent = e;
return dc.id;
}
if (e.type === 'HttpInterface') {
const http: Pipedream.HttpInterface = e;
return http.id;
}
const timer: Pipedream.TimerInterface = e;
return timer.id;
}DeployedComponent, HttpInterface, and TimerInterface each gained a literal
type field. This makes the Emitter union narrowable via the standard
discriminated-union pattern. The field is always present on responses, so
existing code that consumed these types will see the new field on objects it
already had — typically a transparent change. The only caveat is if your code
constructs these objects by hand (e.g. for tests or fixtures), in which case the
type field is now required.
const fixture: Pipedream.DeployedComponent = {
id: 'dc_1',
ownerId: 'u_1',
componentId: 'c_1',
componentKey: 'k_1',
configurableProps: [],
configuredProps: {},
active: true,
createdAt: 1,
updatedAt: 1,
name: 'fixture',
nameSlug: 'fixture',
};const fixture: Pipedream.DeployedComponent = {
type: 'DeployedComponent', // now required
id: 'dc_1',
ownerId: 'u_1',
componentId: 'c_1',
componentKey: 'k_1',
configurableProps: [],
configuredProps: {},
active: true,
createdAt: 1,
updatedAt: 1,
name: 'fixture',
nameSlug: 'fixture',
};The generic ConfigurablePropDiscord wrapper and its
ConfigurablePropDiscordType enum have been removed. The concrete variants that
were already exported in v2.x — ConfigurablePropDiscordChannel and
ConfigurablePropDiscordChannelArray — remain and should be used directly.
import { type Pipedream } from '@pipedream/sdk';
function isDiscordChannelProp(p: Pipedream.ConfigurableProp): boolean {
return (p as Pipedream.ConfigurablePropDiscord).type ===
Pipedream.ConfigurablePropDiscordType.DiscordChannel;
}import { type Pipedream } from '@pipedream/sdk';
function isDiscordChannelProp(p: Pipedream.ConfigurableProp): boolean {
return p.type === '$.discord.channel';
}
// Or, with full type narrowing:
function asDiscordChannel(
p: Pipedream.ConfigurableProp,
): Pipedream.ConfigurablePropDiscordChannel | undefined {
return p.type === '$.discord.channel' ? p : undefined;
}Here's a complete list of how v2.x namespaced types map to v3.x flat types:
| v2.x Type | v3.x Type |
|---|---|
ConfigurableProp.Alert |
ConfigurablePropAlert |
ConfigurableProp.Any |
ConfigurablePropAny |
ConfigurableProp.App |
ConfigurablePropApp |
ConfigurableProp.Boolean |
ConfigurablePropBoolean |
ConfigurableProp.DataStore |
ConfigurablePropDataStore |
ConfigurableProp.Dir |
ConfigurablePropDir |
ConfigurableProp.InterfaceTimer |
ConfigurablePropTimer |
ConfigurableProp.InterfaceApphook |
ConfigurablePropApphook |
ConfigurableProp.IntegerArray |
ConfigurablePropIntegerArray |
ConfigurableProp.InterfaceHttp |
ConfigurablePropHttp |
ConfigurableProp.HttpRequest |
ConfigurablePropHttpRequest |
ConfigurableProp.ServiceDb |
ConfigurablePropDb |
ConfigurableProp.Sql |
ConfigurablePropSql |
ConfigurableProp.AirtableBaseId |
ConfigurablePropAirtableBaseId |
ConfigurableProp.AirtableTableId |
ConfigurablePropAirtableTableId |
ConfigurableProp.AirtableViewId |
ConfigurablePropAirtableViewId |
ConfigurableProp.AirtableFieldId |
ConfigurablePropAirtableFieldId |
ConfigurableProp.DiscordChannel |
ConfigurablePropDiscordChannel |
ConfigurableProp.DiscordChannelArray |
ConfigurablePropDiscordChannelArray |
ConfigurableProp.Integer |
ConfigurablePropInteger |
ConfigurableProp.Object |
ConfigurablePropObject |
ConfigurableProp.String |
ConfigurablePropString |
ConfigurableProp.StringArray |
ConfigurablePropStringArray |
ConfigurablePropBase |
Removed (fields inlined per variant) |
ConfigurablePropDiscord |
Removed (use ConfigurablePropDiscordChannel) |
ConfigurablePropDiscordType |
Removed (use the literal type strings) |
Emitter.DeployedComponent |
DeployedComponent |
Emitter.HttpInterface |
HttpInterface |
Emitter.TimerInterface |
TimerInterface |
The v3.x SDK does not introduce new endpoints or new methods. The improvements are entirely in the type system:
Each ConfigurableProp{Variant} interface now stands on its own, with the
literal type field declared on the variant itself rather than imposed by a
nested namespace wrapper. This means TypeScript narrows
Pipedream.ConfigurableProp cleanly with a plain switch (prop.type) or if (prop.type === 'alert') — without any namespace gymnastics — and IDE
autocomplete surfaces every prop field directly.
import { type Pipedream } from '@pipedream/sdk';
function summarize(prop: Pipedream.ConfigurableProp): string {
switch (prop.type) {
case 'alert':
return prop.content; // narrowed to ConfigurablePropAlert
case 'string':
return prop.label ?? prop.name; // narrowed to ConfigurablePropString
case 'integer':
return String(prop.default ?? prop.name);
default:
return prop.name;
}
}DeployedComponent, HttpInterface, and TimerInterface now each carry a
literal type field, which makes Pipedream.Emitter narrowable the same way:
import { type Pipedream } from '@pipedream/sdk';
function describe(e: Pipedream.Emitter): string {
switch (e.type) {
case 'DeployedComponent':
return `component ${e.componentKey}`;
case 'HttpInterface':
return `http ${e.id}`;
case 'TimerInterface':
return `timer ${e.id}`;
}
}If you are unable to migrate all your code at once, you can use the new SDK alongside the old one by leveraging package aliases. This allows you to migrate incrementally without breaking your existing codebase. To do this, you can install the new SDK with an alias:
npm install @pipedream/sdk-v3@npm:@pipedream/sdk@^3.0.0 --saveThen, in your code, you can import each version separately:
import { Pipedream as PipedreamV2 } from '@pipedream/sdk';
import { Pipedream as PipedreamV3, PipedreamClient } from '@pipedream/sdk-v3';
const client = new PipedreamClient({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
projectId: 'your-project-id',
projectEnvironment: 'development',
});
// Old code continues to type-check against v2.x types
function legacyHandler(prop: PipedreamV2.ConfigurableProp.Alert) {
return prop.content;
}
// Newly migrated code uses v3.x types
function migratedHandler(prop: PipedreamV3.ConfigurablePropAlert) {
return prop.content;
}The following exports have been removed in v3.x:
ConfigurablePropnamespace members (e.g.Pipedream.ConfigurableProp.Alert) — replaced by flat per-variant interfaces (e.g.Pipedream.ConfigurablePropAlert). See Type mapping.Emitternamespace members (e.g.Pipedream.Emitter.HttpInterface) — replaced by direct references to the underlying types (Pipedream.HttpInterface).ConfigurablePropBase— base fields are now inlined into eachConfigurableProp{Variant}interface. There is no longer a single shared base type.ConfigurablePropDiscord— use the concrete variantsConfigurablePropDiscordChannelorConfigurablePropDiscordChannelArrayinstead.ConfigurablePropDiscordType— use the literaltypestrings (e.g.'$.discord.channel') directly.
- Update imports of
Pipedream.ConfigurableProp.{Variant}types to the flatPipedream.ConfigurableProp{Variant}form. - Update imports of
Pipedream.Emitter.{Member}types toPipedream.{Member}(e.g.Pipedream.DeployedComponent). - Replace any references to
ConfigurablePropBasewith theConfigurablePropunion (or with the specific variant your code expects). - Replace any usage of
ConfigurablePropDiscord/ConfigurablePropDiscordTypewithConfigurablePropDiscordChannel/ConfigurablePropDiscordChannelArrayand the literaltypestrings. - If you construct
DeployedComponent,HttpInterface, orTimerInterfaceobjects by hand (e.g. in tests or fixtures), add the newtypediscriminator field. - Run
tsc --noEmitto surface any remaining type-only call sites. - Test all migrated code thoroughly.
- Remove the v2 SDK dependency once migration is complete.