@bluealba/conduit-plugins-sdk
v1.2.0-feature-rms-366-add-new-advanced--273
Published
SDK for building Resource Management Interactions plugins
Readme
@bluealba/conduit-plugins-sdk
SDK for building Conduit plugins.
Installation
You can use the SDK in two ways: globally or locally within your plugin project.
Global Installation (Recommended for CLI usage)
Install the SDK globally to use the conduit command from anywhere:
# Using npm
npm install -g @bluealba/conduit-plugins-sdk
# Using pnpm
pnpm install -g @bluealba/conduit-plugins-sdk
# Using yarn
yarn global add @bluealba/conduit-plugins-sdkAfter global installation, the conduit command is available system-wide:
conduit help
conduit create plugin my-plugin --type=source
cd my-plugin && conduit buildTo uninstall globally:
# Using npm
npm uninstall -g @bluealba/conduit-plugins-sdk
# Using pnpm
pnpm uninstall -g @bluealba/conduit-plugins-sdk
# Using yarn
yarn global remove @bluealba/conduit-plugins-sdkLocal Installation (Per-project)
Install the SDK as a dependency in your plugin project:
# Using npm
npm install @bluealba/conduit-plugins-sdk
# Using pnpm
pnpm add @bluealba/conduit-plugins-sdk
# Using yarn
yarn add @bluealba/conduit-plugins-sdkThe SDK has a peer dependency on zod, so make sure it is installed in your project:
pnpm add zodWith local installation, use package manager executors to run commands:
# Using npm
npx conduit build
# Using pnpm
pnpm conduit build
# Using yarn
yarn conduit buildUsage
This SDK provides type definitions and utilities for creating plugins for the Conduit system.
Plugin Types
The SDK includes interfaces for four plugin types:
- SourcePlugin - Fetches data from external sources and normalizes it into
NormalizedInteractionobjects - EnrichPlugin - Processes and modifies normalized interactions
- RejectionPlugin - Determines whether an interaction should be rejected and provides a reason
- PricePlugin - Calculates pricing for interactions
Source Plugin Example
import type {
SourcePlugin,
NormalizedInteraction,
RawDataItem,
SyncContext,
} from "@bluealba/conduit-plugins-sdk";
import { z } from "zod";
const ConfigSchema = z.object({
apiKey: z.string(),
});
type Config = z.infer<typeof ConfigSchema>;
export class MySourcePlugin implements SourcePlugin<unknown, Config> {
readonly metadata = {
type: "source" as const,
name: "my-source-plugin",
version: "1.0.0",
displayName: "My Source Plugin",
description: "Fetches interactions from my system",
sdkVersion: "1.0.0",
};
readonly configSchema = ConfigSchema;
readonly secretFields = ["apiKey"];
async sync(
context: SyncContext<Config>,
): Promise<{ rawData: RawDataItem; normalizedInteraction: NormalizedInteraction }[]> {
const { config, logger, lastSyncDate } = context;
logger.info({ lastSyncDate }, "Starting sync");
// Fetch and normalize data using config.apiKey
return [];
}
}Enrich Plugin Example
import type {
EnrichPlugin,
RawInteraction,
NormalizedInteraction,
} from "@bluealba/conduit-plugins-sdk";
import { z } from "zod";
const ConfigSchema = z.object({});
type Config = z.infer<typeof ConfigSchema>;
export class MyEnrichPlugin implements EnrichPlugin<Config> {
readonly metadata = {
type: "enrich" as const,
name: "my-enrich-plugin",
version: "1.0.0",
displayName: "My Enrich Plugin",
description: "Enriches normalized interactions",
sdkVersion: "1.0.0",
};
readonly configSchema = ConfigSchema;
readonly secretFields: string[] = [];
process(
_raw: RawInteraction,
normalized: NormalizedInteraction,
_config?: Config,
): NormalizedInteraction {
// Modify and return the normalized interaction
return normalized;
}
}Rejection Plugin Example
import type {
RejectionPlugin,
RawInteraction,
NormalizedInteraction,
RejectionResult,
DeepReadonly,
} from "@bluealba/conduit-plugins-sdk";
import { z } from "zod";
const ConfigSchema = z.object({});
type Config = z.infer<typeof ConfigSchema>;
export class MyRejectionPlugin implements RejectionPlugin<Config> {
readonly metadata = {
type: "rejection" as const,
name: "my-rejection-plugin",
version: "1.0.0",
displayName: "My Rejection Plugin",
description: "Rejects interactions matching custom criteria",
sdkVersion: "1.0.0",
};
readonly configSchema = ConfigSchema;
readonly secretFields: string[] = [];
reject(
_raw: DeepReadonly<RawInteraction>,
normalized: DeepReadonly<NormalizedInteraction>,
_config?: Config,
): RejectionResult | undefined {
if (normalized.buysideAttendees.length === 0) {
return { rejected: true, reason: "No buyside attendees" };
}
return { rejected: false, reason: null };
}
}Price Plugin Example
import type {
PricePlugin,
RawInteraction,
NormalizedInteraction,
PricingResult,
DeepReadonly,
} from "@bluealba/conduit-plugins-sdk";
import { z } from "zod";
const ConfigSchema = z.object({
pricePerAttendee: z.number().nonnegative(),
});
type Config = z.infer<typeof ConfigSchema>;
export class MyPricePlugin implements PricePlugin<Config> {
readonly metadata = {
type: "price" as const,
name: "my-price-plugin",
version: "1.0.0",
displayName: "My Price Plugin",
description: "Calculates pricing based on attendee count",
sdkVersion: "1.0.0",
};
readonly configSchema = ConfigSchema;
readonly secretFields: string[] = [];
calculatePricing(
_raw: DeepReadonly<RawInteraction>,
normalized: DeepReadonly<NormalizedInteraction>,
config?: Config,
): PricingResult {
const pricePerAttendee = config?.pricePerAttendee ?? 50;
const value = normalized.buysideAttendees.length * pricePerAttendee;
return {
strategy: "per-attendee",
matchedRule: `${normalized.buysideAttendees.length}-attendees`,
value,
};
}
}CLI Commands
The SDK provides command-line tools for scaffolding, building, and publishing plugins.
Available Commands
Check available commands
conduit helpCreate a new plugin
conduit create plugin <name> --type=<type>If --type is omitted, an interactive prompt lets you select the plugin type.
Plugin types: source, enrich, rejection, price
Build a plugin
conduit buildPublish a plugin to the server
conduit publishUploads dist/bundle.js to the Conduit server. Set the CONDUIT_URL environment variable to point to a non-default server (default: http://localhost:3000).
Usage with Different Package Managers
Using npm
# Check available commands
npx conduit help
# Create a new plugin
npx conduit create plugin my-plugin --type=source
# Build the plugin
npx conduit build
# Publish the plugin
npx conduit publish
# Or via package.json scripts
npm run buildUsing pnpm
# Check available commands
pnpm conduit help
# Create a new plugin (pnpm automatically finds binaries)
pnpm conduit create plugin my-plugin --type=source
# Build the plugin
pnpm conduit build
# Publish the plugin
pnpm conduit publish
# Or via package.json scripts
pnpm buildUsing yarn
# Check available commands
yarn conduit help
# Create a new plugin
yarn conduit create plugin my-plugin --type=source
# Build the plugin
yarn conduit build
# Publish the plugin
yarn conduit publish
# Or via package.json scripts
yarn buildExample Workflow
# 1. Create a new source plugin
pnpm conduit create plugin salesforce-source --type=source
# 2. Navigate into the plugin directory
cd salesforce-source
# 3. Install dependencies
pnpm install
# 4. Implement the plugin logic in src/plugin.ts
# 5. Build the plugin
pnpm conduit build
# 6. Publish to the Conduit server
pnpm conduit publishAdding to package.json scripts
For convenience, add this script to your plugin's package.json:
{
"scripts": {
"build": "conduit build"
}
}Environment Variables
| Variable | Description | Default |
|---------------|------------------------------------------|--------------------------|
| CONDUIT_URL | Conduit server base URL for publish | http://localhost:3000 |
Development
# Install dependencies
pnpm install
# Build the SDK
pnpm build
# Watch mode for development
pnpm dev
# Run tests
pnpm test