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. Both public and your private components can be used in your code-native integrations.
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.
Importing types from existing components
To use an existing trigger, connection, data source or action you need to import TypeScript types from the existing component.
Importing types from public components
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 which read:
@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.
NPM and Yarn "Classic" (1.x) both respect a .npmrc
file.
If you are using a more recent version of yarn
, please replace the .npmrc
file with a .yarnrc.yml
file that reads:
npmScopes:
"component-manifests":
npmRegistryServer: "https://app.prismatic.io/packages/npm"
To add a component's manifest package to your code-native project, take note of the component's key and run:
npm install @component-manifests/slack
Importing types from private components
If you've developed your own custom component(s), you can do one of two things to share the component logic with the code-native integration:
-
You can abstract the logic from the custom component into a distinct package, and reference that logic in both the custom component and code-native integration. In this case, your code-native integration won't depend on a custom component - it'll run utility and helper functions from your abstracted library.
-
You can generate a component manifest, like those created for Prismatic-provided public components. To create your own component manifest, build and publish your component and then run:
Generate a component manifest from a private componentnpx @prismatic-io/spectral@latest component-manifest
This will generate a manifest project alongside your component project. You can save this project alongside your code-native project, or publish it to a package repository that you control.
Adding components to a code-native component manifest
Once the component manifest is installed, add it to componentRegistry.ts
import { componentManifests } from "@prismatic-io/spectral";
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.
At the top of your config pages file, import the connectionConfigVar
function from @prismatic-io/spectral
.
Within a config page, include a connectionConfigVar()
that includes a connection
property:
import { configPage, connectionConfigVar } from "@prismatic-io/spectral";
export const configPages = {
Connections: configPage({
tagline: "Authenticate with Slack",
elements: {
"Slack OAuth Connection": connectionConfigVar({
stableKey: "my-slack-connection",
dataType: "connection",
connection: {
component: "slack",
key: "oauth2",
values: {
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,
},
},
},
}),
},
}),
};
You can reference an connection template in a referenced connection if you provide a template
name value to your connection definition.
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 the dataSourceConfigVar
function from @prismatic-io/spectral
.
Within a config page, include a dataSourceConfigVar()
that includes a dataSource
property:
import { configPage, dataSourceConfigVar } from "@prismatic-io/spectral";
export const configPages = {
// ...
"Slack Config": configPage({
tagline: "Select a Slack channel from a dropdown menu",
elements: {
"Select Slack Channel": dataSourceConfigVar({
stableKey: "my-slack-channel-picklist",
dataSource: {
component: "slack",
key: "selectChannels",
values: {
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
.
Components are accessible through the context.components
object.
For example,
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 context.components.slack.postMessage({
channelName: util.types.toString(configVars["Select Slack Channel"]),
connection: configVars["Slack OAuth Connection"],
message: `Incomplete item: ${item.task}`,
});
return { data: null };
},
});