Skip to main content

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

Tip: Leverage prism-mcp

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:

  1. 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 Slack
    npx 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 component
    npx cni-component-manifest my-private-component --private
  2. 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 project
    npm install @component-manifests/slack
    Update to new component reference syntax

    If 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:

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.

Using an existing connection in a code-native integration
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:

Using an existing data source in a code-native integration
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.

Using an existing trigger in a code-native integration
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,

Using an existing action in a code-native integration
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 };
},
});