Existing Components in Code-Native
Prismatic provides a number of existing components that you can use in your code-native integrations. By leveraging an existing component, you can save time and effort by reusing existing functionality.
An example integration that uses the existing Slack OAuth 2.0 connection, Slack "Select Channel" data source, and Slack "Post Message" action is available in GitHub.
Adding component manifests to your code-native project
If you are using an AI coding agent like Cursor or GitHub Copilot, you can leverage prism-mcp to accelerate code-native integration development.
prism-mcp
comes with tools that generate code snippets for referencing existing components.
To use an existing trigger, connection, data source, or action, you need to add the component's manifest to your code-native project. This can be done in one of two ways:
-
Recommended Method: Generate a component manifest from Prismatic's API. From a terminal in your code-native directory, run:
Generate a component manifest from Prismatic's API for Slacknpx cni-component-manifest slack
The component key that you supply to the
cni-component-manifest
command can be found at the top of a component's docs page.A private component manifest can be generated by adding the
--private
flag to the command:Generate a component manifest from a private componentnpx cni-component-manifest my-private-component --private
-
Legacy Method: Manifests for Prismatic-provided public components are available through Prismatic's component manifests repository. When you initialized your code-native integration, an
.npmrc
file was created that read:.npmrc@component-manifests:registry=https://app.prismatic.io/packages/npm
That instructs your package manager to look for packages that begin with
@component-manifests
in the Prismatic repository.To add a component's manifest package to your code-native project, take note of the component's key and run:
Add the Slack component's manifest to a code-native projectnpm install @component-manifests/slack
Update to new component reference syntaxIf you previously added a component manifest using the legacy method, see our Spectral 10.6 migration guide for instructions on how to use new component reference syntax.
Including components in your component registry
Once the component manifest is installed, add it to componentRegistry.ts
:
import { componentManifests } from "@prismatic-io/spectral";
import slack from "./manifests/slack";
// Or, if you installed the manifest as an npm dependency,
// import slack from "@component-manifests/slack";
export const componentRegistry = componentManifests({
slack,
});
Behind the scenes, .spectral/index.ts
will inspect your code-native project's exported componentRegistry
object and will provide type hinting to your TypeScript based on which components are included in your component registry.
Using existing connections in code-native
After adding an existing component's manifest to your code-native project, you can use a component's connection in your code-native integration's configPages
definition.
The component manifest includes a connection definition wrapper function that you can reference.
import { configPage } from "@prismatic-io/spectral";
import { slackOauth2 } from "./manifests/slack/connections/oauth2";
export const configPages = {
Connections: configPage({
tagline: "Authenticate with Slack",
elements: {
"Slack OAuth Connection": slackOauth2("my-slack-connection", {
clientId: {
value: "REPLACE_ME_WITH_YOUR_CLIENT_ID",
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
clientSecret: {
value: "REPLACE_ME_WITH_YOUR_CLIENT_SECRET",
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
signingSecret: {
value: "REPLACE_ME_WITH_YOUR_SIGNING_SECRET",
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
scopes: {
value: "chat:write chat:write.public channels:read",
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
authorizeUrl: {
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
isUser: {
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
tokenUrl: {
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
revokeUrl: {
permissionAndVisibilityType: "organization",
visibleToOrgDeployer: false,
},
}),
},
}),
};
Using existing data sources in code-native
After adding an existing component's manifest to your code-native project, you can use a component's data source in your code-native integration's configPages
definition.
At the top of your config pages file, import your data source wrapper function from the component's manifest:
import { configPage } from "@prismatic-io/spectral";
import { slackSelectChannels } from "./manifests/slack/dataSources/selectChannels";
export const configPages = {
// ...
"Slack Config": configPage({
tagline: "Select a Slack channel from a dropdown menu",
elements: {
"Select Slack Channel": slackSelectChannels("my-slack-channel-picklist", {
connection: { configVar: "Slack OAuth Connection" },
includePublicChannels: { value: true },
}),
},
}),
};
If the data source requires a connection, you can pass a connection to the data source using the appropriate input value by specifying a configVar
by name (connection: { configVar: "Slack OAuth Connection" }
in the example above).
Using existing triggers in code-native
After adding an existing component's manifest to your code-native project, you can use a component's trigger in your code-native integration's flow
definition.
export const existingComponentTriggerFlow = flow({
name: "Existing Component Trigger Flow",
stableKey: "6f58c32c-b29a-4f55-97e6-b86bf9e24551",
description: "This flow uses an existing component trigger",
onTrigger: {
component: "hash",
key: "hmacWebhookTrigger",
values: {
hmacHeaderName: { value: "X-Signature-256" },
secretKey: { configVar: "My Secret Key Config Var" },
hashFunction: { value: "sha256" },
},
},
onExecution: async (context, params) => {
const { logger } = context;
logger.info(`Action context: ${JSON.stringify(context)}`);
logger.info(`Action params: ${JSON.stringify(params)}`);
return Promise.resolve({ data: null });
},
});
If the trigger takes inputs, those inputs are passed to the trigger as values
, and values can be either static string value
or can reference config variables with configVar: "Config Variable Name"
.
Using existing actions in code-native
After importing an existing component's manifest and adding it to your componentManifests
export, you can call one of the component's actions from within your flow
by importing the action from your component manifest.
For example,
import slackActions from "../manifests/slack/actions";
export const existingComponentTriggerFlow = flow({
name: "Send a Slack Message",
stableKey: "send-a-slack-message",
description: "Send 'Hello World' to a Slack channel",
onExecution: async (context, params) => {
await slackActions.postMessage.perform({
channelName: util.types.toString(configVars["Select Slack Channel"]),
connection: configVars["Slack OAuth Connection"],
message: `Incomplete item: ${item.task}`,
});
return { data: null };
},
});