### GET Request Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Demonstrates how to make a GET request using the raw request action. ```APIDOC ## GET Request ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "GET", url: "/items", queryParams: [ { key: "limit", value: "10" }, { key: "offset", value: "0" }, ], }); ``` ``` -------------------------------- ### Basic HTTP Request Examples with createClient() Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Illustrates various basic HTTP requests (GET, POST, PATCH, DELETE) using an Axios client created with createClient(). Shows how to set the base URL and make requests to different endpoints. ```typescript const client = createClient({ baseUrl: "https://api.example.com/v1", }); // GET request const { data: items } = await client.get("/items"); // GET with query parameters const { data: filtered } = await client.get("/items", { params: { limit: 10, offset: 0 }, }); // POST request const { data: created } = await client.post("/items", { name: "New Item", description: "Item description", }); // PATCH request const { data: updated } = await client.patch("/items/123", { status: "active", }); // DELETE request await client.delete("/items/123"); ``` -------------------------------- ### Raw Request Action - GET Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Example of making a GET request using the raw request action. It includes setting the HTTP method, URL, and query parameters. ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "GET", url: "/items", queryParams: [ { key: "limit", value: "10" }, { key: "offset", value: "0" }, ], }); ``` -------------------------------- ### Basic HTTP Request Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Demonstrates making basic GET, POST, PATCH, and DELETE requests using the client created by `createClient`. ```APIDOC ## Basic HTTP Request Example ```typescript const client = createClient({ baseUrl: "https://api.example.com/v1", }); // GET request const { data: items } = await client.get("/items"); // GET with query parameters const { data: filtered } = await client.get("/items", { params: { limit: 10, offset: 0 }, }); // POST request const { data: created } = await client.post("/items", { name: "New Item", description: "Item description", }); // PATCH request const { data: updated } = await client.patch("/items/123", { status: "active", }); // DELETE request await client.delete("/items/123"); ``` ``` -------------------------------- ### Install Spectral Library Source: https://github.com/prismatic-io/spectral/blob/main/packages/spectral/README.md Install the spectral library using npm. This is the first step to begin building custom Prismatic connectors. ```bash npm install @prismatic-io/spectral ``` -------------------------------- ### Install ESLint Config Source: https://github.com/prismatic-io/spectral/blob/main/packages/eslint-config-spectral/README.md Install the ESLint configuration package as a development dependency. ```bash npm install @prismatic-io/eslint-config-spectral --save-dev ``` -------------------------------- ### POST with File Upload Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Provides an example of uploading a file using a POST request with the raw request action. ```APIDOC ## POST with File Upload ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/files/upload", fileData: [{ key: "file", value: fileBuffer }], fileDataFileNames: { file: "document.pdf" }, }); ``` ``` -------------------------------- ### Usage Example: List Items Action Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/action.md Demonstrates how to create a 'List Items' action using the action() function. This example includes defining inputs, a perform function with API call, and an example payload. ```typescript import { action, input, util } from "@prismatic-io/spectral"; const listItems = action({ display: { label: "List Items", description: "Retrieve a list of items from Acme", }, inputs: { connection: input({ label: "Connection", type: "connection", required: true, }), limit: input({ label: "Limit", type: "string", required: false, default: "100", comments: "Maximum number of items to return", }), }, perform: async (context, { connection, limit }) => { const maxItems = util.types.toInt(limit, 100); context.logger.info(`Fetching up to ${maxItems} items`); // Call API with the connection credentials const response = await fetch("https://api.acme.com/items", { headers: { Authorization: `Bearer ${connection.fields?.apiKey}`, }, }); const data = await response.json(); return { data }; }, examplePayload: { data: { items: [{ id: "1", name: "Item 1" }], }, }, }); export { listItems }; ``` -------------------------------- ### Full Integration Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/integration.md Demonstrates how to define flows, configuration pages, and a component registry to create a complete integration using the `integration()` function. ```typescript import { integration, flow, configPage, configVar, componentManifests } from "@prismatic-io/spectral"; // Define flows const syncFlow = flow({ name: "Sync Data", stableKey: "sync-data", description: "Syncs data from Acme to your system", schedule: { value: "0 0 * * *", // Daily at midnight timezone: "America/Chicago", }, onExecution: async (context, params) => { context.logger.info("Starting sync"); return Promise.resolve({ data: null }); }, }); const webhookFlow = flow({ name: "Handle Webhook", stableKey: "handle-webhook", description: "Receives and processes incoming webhooks", synchronousResponseSupport: "valid", onExecution: async (context, params) => { const { logger } = context; const payload = params.onTrigger.results; logger.info("Processing webhook"); return Promise.resolve({ data: payload }); }, }); // Define config pages const configPages = { Connections: configPage({ tagline: "Set up your API connections", elements: { "Acme Connection": connectionConfigVar({ stableKey: "acme-connection", inputs: { apiKey: { label: "API Key", type: "password", required: true, }, }, }), }, }), Configuration: configPage({ tagline: "Configure sync settings", elements: { "Sync Interval": configVar({ stableKey: "sync-interval", dataType: "picklist", pickList: ["hourly", "daily", "weekly"], defaultValue: "daily", }), }, }), }; // Define component registry const componentRegistry = componentManifests({ slack: { key: "slack", public: true, actions: { postMessage: { inputs: { message: { label: "Message" }, channelName: { label: "Channel Name" }, }, }, }, }, stripe: { key: "stripe", public: true, actions: { createPaymentIntent: { inputs: { amount: { label: "Amount" }, currency: { label: "Currency" }, }, }, }, }, }); // Export the integration export default integration({ name: "Acme Integration", description: "Syncs data between Acme and your system", category: "Data Sync", labels: ["data-sync", "production"], iconPath: "icon.png", version: "1.0.0", flows: [syncFlow, webhookFlow], configPages, componentRegistry, }); ``` -------------------------------- ### Branching Action Example: Route Order Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/action.md Example of creating an action that supports branching. It sets `allowsBranching: true` and defines `staticBranchNames` to route based on a 'priority' input. ```typescript const routeOrder = action({ display: { label: "Route Order", description: "Routes orders based on priority level", }, inputs: { priority: input({ label: "Priority", type: "string", required: true }), }, allowsBranching: true, staticBranchNames: ["high", "medium", "low"], perform: async (context, { priority }) => { return { data: { orderId: "12345" }, branchName: priority.toLowerCase(), }; }, }); ``` -------------------------------- ### Required Config Variable Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines a configuration variable that must be provided by the user during integration setup, such as an API key. ```typescript const apiKey = configVar({ stableKey: "api-key", dataType: "string", required: true, description: "API key for authentication", }); ``` -------------------------------- ### Default Import Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/module-exports.md Demonstrates how to perform a default import of the spectral package. Access functions and modules using the 'spectral.' prefix. ```typescript import spectral from "@prismatic-io/spectral"; // Access as: // spectral.util.types.toInt() ``` -------------------------------- ### Binary File Download Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Example of downloading a binary file (e.g., PDF) by setting the `responseType` to `'arraybuffer'`. ```APIDOC ## Binary File Download ```typescript const client = createClient({ baseUrl: "https://api.example.com", responseType: "arraybuffer", }); const { data: buffer } = await client.get("/files/document.pdf"); // Convert buffer to DataPayload for use in Spectral const payload = util.types.toBufferDataPayload(buffer); ``` ``` -------------------------------- ### POST with Form Data Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Shows how to perform a POST request with form data using the raw request action. ```APIDOC ## POST with Form Data ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/upload", formData: [ { key: "field1", value: "value1" }, { key: "field2", value: "value2" }, ], }); ``` ``` -------------------------------- ### Define Action Example Payload Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/configuration.md Provide an 'examplePayload' for an action to demonstrate its output structure in the UI. This helps users understand what to expect from the action. ```typescript examplePayload: { data: { items: [{ id: "1", name: "Item 1" }], total: 1, }, } ``` -------------------------------- ### Structured Object Input Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/structuredObjectInput.md A simple example defining a 'Name' structured object input with 'first' and 'last' name fields. ```typescript const nameInput = structuredObjectInput({ label: "Name", inputs: { first: input({ label: "First Name", type: "string", required: true }), last: input({ label: "Last Name", type: "string", required: true }), }, }); ``` -------------------------------- ### POST with JSON Body Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Illustrates how to send a POST request with a JSON body using the raw request action. ```APIDOC ## POST with JSON Body ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/items", headers: [{ key: "Content-Type", value: "application/json" }], data: JSON.stringify({ name: "New Item", description: "..." }), }); ``` ``` -------------------------------- ### Create a Picklist Data Source (TypeScript) Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/dataSource.md Example of creating a picklist data source to fetch a list of channels from Slack. Requires a Slack connection and uses the 'picklist' dataSourceType. ```typescript import { dataSource, input } from "@prismatic-io/spectral"; const selectChannel = dataSource({ display: { label: "Select Channel", description: "Fetches a list of channels from Slack", }, dataSourceType: "picklist", inputs: { connection: input({ label: "Connection", type: "connection", required: true, }), }, perform: async (context, { connection }) => { // Call Slack API to fetch channels const response = await fetch("https://slack.com/api/conversations.list", { headers: { Authorization: `Bearer ${connection.token?.access_token}`, }, }); const data = await response.json(); if (!data.ok) { throw new Error(`Slack API error: ${data.error}`); } // Return as picklist options const result = data.channels.map(channel => ({ label: channel.name, value: channel.id, })); return { result }; }, examplePayload: { result: [ { label: "general", value: "C1234567" }, { label: "engineering", value: "C7654321" }, { label: "marketing", value: "C4567890" }, ], }, }); export { selectChannel }; ``` -------------------------------- ### Example Webhook Trigger Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/trigger.md An example of creating a webhook trigger using the trigger() function. This includes defining display information, inputs, and the perform function for handling incoming webhooks and validating signatures. ```typescript import { trigger, input } from "@prismatic-io/spectral"; import type { HttpResponse } from "@prismatic-io/spectral"; const webhookTrigger = trigger({ display: { label: "Acme Webhook", description: "Receives webhooks from Acme", }, inputs: { secret: input({ label: "Signing Secret", type: "password", required: true, comments: "Used to verify webhook signatures", }), }, scheduleSupport: "invalid", synchronousResponseSupport: "valid", perform: async (context, payload, { secret }) => { // Validate webhook signature const signature = payload.headers["x-acme-signature"]; if (!signature) { const response: HttpResponse = { statusCode: 401, contentType: "application/json", body: JSON.stringify({ error: "Missing signature" }), }; return Promise.resolve({ payload, response }); } context.logger.info("Webhook received from Acme"); // Return success response const response: HttpResponse = { statusCode: 200, contentType: "application/json", body: JSON.stringify({ received: true }), }; return Promise.resolve({ payload, response, }); }, examplePayload: { headers: { "content-type": "application/json", "x-acme-signature": "sha256=...", }, body: { eventType: "order.created", orderId: "12345" }, rawBody: { data: Buffer.from("..."), contentType: "application/json", }, }, }); export { webhookTrigger }; ``` -------------------------------- ### Retry Configuration Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/flow.md Sets up retry logic for a flow, defining the maximum number of attempts, initial delay, and backoff multiplier for exponential retries. ```typescript export const retryFlow = flow({ name: "With Retries", stableKey: "with-retries", retryConfig: { maxAttempts: 3, initialDelayMS: 1000, backoffMultiplier: 2, }, onExecution: async (context, params) => { // Will retry up to 3 times with exponential backoff return Promise.resolve({ data: null }); }, }); ``` -------------------------------- ### Create a Searchable Picklist Data Source (TypeScript) Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/dataSource.md Example of creating a searchable picklist data source that allows users to search for users by name. It includes a connection input and an optional searchTerm input. ```typescript const searchUsers = dataSource({ display: { label: "Search Users", description: "Search for users by name", }, dataSourceType: "picklist", inputs: { connection: input({ label: "Connection", type: "connection", required: true, }), searchTerm: input({ label: "Search Term", type: "string", required: false, comments: "Name to search for", }), }, perform: async (context, { connection, searchTerm }) => { const query = searchTerm ? `?search=${searchTerm}` : ""; const response = await fetch( `https://api.example.com/users${query}`, { headers: { Authorization: `Bearer ${connection.fields?.apiKey}`, }, } ); const users = await response.json(); const result = users.map(user => ({ label: user.name, value: user.id, })); return { result }; }, }); ``` -------------------------------- ### Named Imports Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/module-exports.md Shows how to import specific functions and types directly using named imports. This allows for cleaner access to individual exports. ```typescript import { component, action, trigger, input, connection, integration, flow, configVar, util, testing, SpectralError, isSpectralError, } from "@prismatic-io/spectral"; ``` -------------------------------- ### String Config Variable Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines a string configuration variable with a default value and description. This is useful for API endpoints or other text-based settings. ```typescript import { configVar, configPage } from "@prismatic-io/spectral"; const endpoint = configVar({ stableKey: "api-endpoint", dataType: "string", defaultValue: "https://api.example.com", description: "The base URL of the API", }); const configPages = { Configuration: configPage({ tagline: "Configure API settings", elements: { "API Endpoint": endpoint, }, }), }; ``` -------------------------------- ### Integer Config Variable Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines an integer configuration variable, suitable for numerical inputs like retry counts or limits. ```typescript const maxRetries = configVar({ stableKey: "max-retries", dataType: "integer", defaultValue: 3, description: "Maximum number of retry attempts", }); ``` -------------------------------- ### Raw Request Action - POST with File Upload Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Shows how to perform a POST request with file uploads. This example includes setting the 'fileData' and 'fileDataFileNames' parameters. ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/files/upload", fileData: [{ key: "file", value: fileBuffer }], fileDataFileNames: { file: "document.pdf" }, }); ``` -------------------------------- ### Structured Object Input Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/dynamicObjectInput.md Use structured object input when all fields are known ahead of time and the structure is always the same. This is simpler and more straightforward. ```typescript const name = structuredObjectInput({ label: "Name", inputs: { first: input({ label: "First Name", type: "string", required: true }), last: input({ label: "Last Name", type: "string", required: true }), }, }); ``` -------------------------------- ### Creating a Prismatic Component Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/component.md Example of how to define and export a Prismatic component using the component() function. This includes defining connections, actions, and the overall component metadata. ```typescript import { component, action, input, connection } from "@prismatic-io/spectral"; const myConnection = connection({ key: "apiKey", display: { label: "Acme API Key", description: "Authenticate with Acme using an API key", }, inputs: { apiKey: { label: "API Key", type: "password", required: true }, }, }); const listItems = action({ display: { label: "List Items", description: "Retrieve a list of items from Acme", }, inputs: { connection: { label: "Connection", type: "connection", required: true }, }, perform: async (context, { connection }) => { return { data: { items: [] } }; }, }); export default component({ key: "acme-connector", display: { label: "Acme", description: "Interact with Acme's API", iconPath: "icon.png", }, actions: { listItems, }, connections: { apiKey: myConnection, }, }); ``` -------------------------------- ### Define Multiple Connection Types Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/connectionConfigVar.md Illustrates how to define multiple distinct connection configuration variables within the same `configPage` element. This allows for configuring different types of connections, such as source and destination systems, in a single setup. ```typescript const configPages = { Connections: configPage({ tagline: "Configure your integrations", elements: { "Source System": connectionConfigVar({ stableKey: "source-connection", dataType: "connection", inputs: { host: { label: "Host", type: "string", required: true, }, port: { label: "Port", type: "string", required: true, default: "5432", }, username: { label: "Username", type: "string", required: true, }, password: { label: "Password", type: "password", required: true, }, }, }), "Destination System": connectionConfigVar({ stableKey: "dest-connection", dataType: "connection", inputs: { apiKey: { label: "API Key", type: "password", required: true, }, baseUrl: { label: "Base URL", type: "string", required: true, }, }, }), }, }), }; ``` -------------------------------- ### Making HTTP Requests with Spectral Client Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/README.md Illustrates how to create and use an HTTP client provided by `@prismatic-io/spectral/dist/clients/http`. This snippet configures a client with a base URL, authorization headers, and retry settings for making GET requests. ```typescript import { createClient } from "@prismatic-io/spectral/dist/clients/http"; const client = createClient({ baseUrl: "https://api.example.com", headers: { Authorization: `Bearer ${token}` }, retryConfig: { retries: 3, useExponentialBackoff: true }, }); const { data } = await client.get("/items"); ``` -------------------------------- ### Picklist Config Variable Examples Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines a picklist configuration variable, allowing users to select from a predefined list of options. This can be a simple array of strings or an array of Element objects for more control over keys and labels. ```typescript const region = configVar({ stableKey: "region", dataType: "picklist", pickList: ["us-east-1", "us-west-2", "eu-west-1"], defaultValue: "us-east-1", description: "AWS region to use", }); // Or with Element objects for more control const environment = configVar({ stableKey: "environment", dataType: "picklist", pickList: [ { key: "dev", label: "Development" }, { key: "staging", label: "Staging" }, { key: "prod", label: "Production" }, ], defaultValue: "dev", description: "Target environment", }); ``` -------------------------------- ### Binary File Download with ArrayBuffer Response Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Example of downloading a binary file (e.g., PDF) by setting the responseType to 'arraybuffer'. The downloaded data is received as a buffer, which can then be converted for use in Spectral. ```typescript const client = createClient({ baseUrl: "https://api.example.com", responseType: "arraybuffer", }); const { data: buffer } = await client.get("/files/document.pdf"); // Convert buffer to DataPayload for use in Spectral const payload = util.types.toBufferDataPayload(buffer); ``` -------------------------------- ### Instance Deploy and Delete Hooks Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/flow.md Defines hooks that execute when an instance is deployed or deleted, useful for setup and cleanup tasks like configuring webhooks. ```typescript export const hooksFlow = flow({ name: "With Hooks", stableKey: "with-hooks", onInstanceDeploy: async (context) => { context.logger.info("Instance deployed"); // Setup webhooks, initialize resources, etc. }, onInstanceDelete: async (context) => { context.logger.info("Instance deleted"); // Clean up webhooks, delete resources, etc. }, onExecution: async (context, params) => { return Promise.resolve({ data: null }); }, }); ``` -------------------------------- ### Usage Example for Polling Trigger Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/pollingTrigger.md Demonstrates how to create a polling trigger that fetches new records based on a cursor and stores the latest cursor for the next poll. ```typescript import { pollingTrigger, input } from "@prismatic-io/spectral"; const newRecordsTrigger = pollingTrigger({ display: { label: "New Records", description: "Triggers when new records are detected", }, inputs: { connection: input({ label: "Connection", type: "connection", required: true, }), limit: input({ label: "Records Per Poll", type: "string", required: false, default: "100", }), }, perform: async (context, payload, params) => { // Get the cursor from the last poll const lastCursor = context.polling.getState()["cursor"] ?? ""; context.logger.info(`Polling from cursor: ${lastCursor}`); // Fetch records from the API const records = await fetchRecordsFromAPI( params.connection, lastCursor, params.limit, ); // Store the new cursor for the next poll context.polling.setState({ cursor: records.nextCursor }); // Return the records as the trigger payload return Promise.resolve({ payload: { ...payload, body: { data: records.items }, }, }); }, }); export { newRecordsTrigger }; ``` -------------------------------- ### Error Handling Flow Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/flow.md Configures a flow with error handling, specifying notification preferences and an error handler flow. It includes a try-catch block for robust execution. ```typescript export const errorHandlingFlow = flow({ name: "With Error Handling", stableKey: "with-errors", errorConfig: { notifyUsers: true, executeErrorFlow: "error-handler-flow", }, onExecution: async (context, params) => { try { const data = await fetchData(); return Promise.resolve({ data }); } catch (error) { context.logger.error("Failed to fetch data", error); throw error; } }, }); ``` -------------------------------- ### Define Dynamic Object Input with Nested Structured Objects Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/dynamicObjectInput.md Demonstrates defining dynamic object input with nested structured objects for contact and lead configurations. This example showcases the use of `structuredObjectInput` within `dynamicObjectInput` to create complex, reusable input structures. ```typescript import { input, structuredObjectInput, dynamicObjectInput } from "@prismatic-io/spectral"; const contactName = structuredObjectInput({ label: "Name", inputs: { first: input({ label: "First Name", type: "string", required: true }), last: input({ label: "Last Name", type: "string", required: true }), }, }); const contactAddress = structuredObjectInput({ label: "Address", inputs: { street: input({ label: "Street", type: "string", required: true }), city: input({ label: "City", type: "string", required: true }), state: input({ label: "State", type: "string", required: true }), zip: input({ label: "ZIP", type: "string", required: true }), }, }); const objectData = dynamicObjectInput({ label: "Object Data", required: true, configurations: { contact: { label: "Contact", comments: "Create or update a contact record", inputs: { name: contactName, email: input({ label: "Email", type: "string", required: true }), phone: input({ label: "Phone", type: "string", required: false }), address: contactAddress, }, }, lead: { label: "Lead", comments: "Create or update a lead", inputs: { name: contactName, email: input({ label: "Email", type: "string", required: true }), source: input({ label: "Lead Source", type: "string", required: true, model: [ { key: "web", label: "Web" }, { key: "referral", label: "Referral" }, { key: "advertisement", label: "Advertisement" }, ], }), notes: input({ label: "Notes", type: "text", required: false }), }, }, }, }); ``` -------------------------------- ### Reuse Existing Connection Definition Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/connectionConfigVar.md This example demonstrates how to reuse an existing connection definition (created with the `connection` function) when defining a connection config variable using `connectionConfigVar`. This promotes code reusability. ```typescript import { connection, connectionConfigVar, configPage } from "@prismatic-io/spectral"; const apiConnection = connection({ key: "apiKey", display: { label: "API Key Authentication", description: "Authenticate using an API key", }, inputs: { apiKey: { label: "API Key", type: "password", required: true, comments: "Generate from your account settings", }, baseUrl: { label: "Base URL", type: "string", required: true, default: "https://api.example.com", }, }, }); const configPages = { Connections: configPage({ tagline: "Set up your connections", elements: { "API Connection": connectionConfigVar({ stableKey: "api-connection", ...apiConnection, }), }, }), }; ``` -------------------------------- ### Dynamic Object Input Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/dynamicObjectInput.md Use dynamic object input for variable structures based on selection, where different configurations provide different fields. This offers more flexibility but requires runtime type checking. ```typescript const record = dynamicObjectInput({ label: "Record", configurations: { contact: { label: "Contact", inputs: { /* ... */ } }, account: { label: "Account", inputs: { /* ... */ } }, }, }); ``` -------------------------------- ### Configure HTTP Client Retries Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Customize retry behavior using `retryConfig`. This example sets the number of retries, delay between retries, and enables exponential backoff. It also specifies that only network or idempotent errors should be retried by default. ```typescript const client = createClient({ baseUrl: "https://api.example.com", retryConfig: { retries: 3, retryDelay: 1000, useExponentialBackoff: true, retryAllErrors: false, // Only retry network/idempotent errors retryCondition: (error) => { // Custom retry condition return error.response?.status === 429; // Retry on rate limit }, }, }); ``` -------------------------------- ### Create and Use HTTP Client in Spectral Action Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Demonstrates how to create an HTTP client using createClient() within a Spectral action and then use it to make requests. Includes setting base URL, authorization headers, timeout, and response type. ```typescript import { createClient } from "@prismatic-io/spectral/dist/clients/http"; import { action, input } from "@prismatic-io/spectral"; const listItems = action({ display: { label: "List Items", description: "Get a list of items from Acme", }, inputs: { connection: input({ label: "Connection", type: "connection", required: true, }), }, perform: async (context, { connection }) => { // Create HTTP client with base configuration const client = createClient({ baseUrl: "https://api.acme.com/v2", headers: { Authorization: `Bearer ${connection.fields?.apiKey}`, "User-Agent": "Acme Connector/1.0", }, timeout: 30000, responseType: "json", }); // Make requests using the client const { data } = await client.get("/items"); return { data }; }, }); ``` -------------------------------- ### Define Date Range Input Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/structuredObjectInput.md Create a structured input for a date range, specifying start and end dates. ```typescript const dateRange = structuredObjectInput({ label: "Date Range", inputs: { startDate: input({ label: "Start Date", type: "date", required: true, }), endDate: input({ label: "End Date", type: "date", required: true, }), }, }); ``` -------------------------------- ### Schedule Config Variable Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines a schedule configuration variable, used to specify a time or interval for automated tasks. ```typescript const syncSchedule = configVar({ stableKey: "sync-schedule", dataType: "schedule", description: "When to run the sync", }); ``` -------------------------------- ### Build Raw Request Action with Custom Options Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Demonstrates creating a 'Raw Request' action with a custom label and description. This is useful for providing more context to integration builders. ```typescript import { integration, flow, configPage, configVar } from "@prismatic-io/spectral"; import { buildRawRequestAction } from "@prismatic-io/spectral/dist/clients/http"; const rawRequest = buildRawRequestAction( "https://api.acme.com/v2", "Call Acme API", "Make a custom HTTP request to Acme" ); export default integration({ name: "Acme Integration", flows: [ flow({ name: "Test Raw Request", stableKey: "test-raw-request", onExecution: async (context, params) => { // Call the raw request action const result = await context.components.acme.rawRequest({ method: "GET", url: "/items", headers: [], queryParams: [{ key: "limit", value: "10" }], }); return { data: result.data }; }, }), ], componentRegistry: { acme: { key: "acme-connector", public: true, actions: { rawRequest: { inputs: { /* ... */ } }, }, }, }, }); ``` -------------------------------- ### Build Raw Request Action Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Initializes a raw request action with a base URL and custom display information. ```APIDOC ## buildRawRequestAction(baseUrl, label, description) ### Description Builds a raw request action that can be used to send HTTP requests to a specified base URL. ### Parameters - **baseUrl** (string) - Required - The base URL for all requests made with this action. - **label** (string) - Optional - A display label for the action. - **description** (string) - Optional - A description for the action. ``` -------------------------------- ### Raw Request Action - POST with Form Data Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Example of a POST request using form data. This is suitable for submitting data as 'application/x-www-form-urlencoded'. ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/upload", formData: [ { key: "field1", value: "value1" }, { key: "field2", value: "value2" }, ], }); ``` -------------------------------- ### Create a Scheduled Flow Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/flow.md Defines a flow that runs on a schedule using a cron expression. This example demonstrates a nightly data sync process. ```typescript import { flow } from "@prismatic-io/spectral"; export const scheduledSyncFlow = flow({ name: "Nightly Sync", stableKey: "nightly-sync", description: "Syncs data every night at midnight", schedule: { value: "0 0 * * *", // Cron expression: midnight every day timezone: "America/Chicago", }, onExecution: async (context, params) => { const { logger, configVars } = context; logger.info("Starting nightly sync"); // Fetch data from source const sourceData = await fetchFromSource(configVars); // Transform data const transformed = transformData(sourceData); // Send to destination await sendToDestination(transformed, configVars); logger.info("Nightly sync completed"); return Promise.resolve({ data: { itemCount: transformed.length } }); }, }); ``` -------------------------------- ### Boolean Config Variable Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/configVar.md Defines a boolean configuration variable, typically used for enabling or disabling features like debug logging. ```typescript const enableDebug = configVar({ stableKey: "enable-debug", dataType: "boolean", defaultValue: false, description: "Enable debug logging", }); ``` -------------------------------- ### Basic String Input Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/input.md Defines a required string input field with a label, comments, and an example value. Use this for simple text entries. ```typescript import { input } from "@prismatic-io/spectral"; const itemName = input({ label: "Item Name", type: "string", required: true, comments: "The name of the item to create", example: "My New Item", }); ``` -------------------------------- ### Define a Trigger Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/types.md The `TriggerDefinition` interface defines a trigger that starts a flow, specifying its inputs, the function to perform, and support for scheduling and synchronous responses. ```typescript interface TriggerDefinition = TriggerResult> { display: { label: string; description: string }; inputs: TInputs; perform: TriggerPerformFunction; scheduleSupport: "valid" | "invalid"; synchronousResponseSupport: "valid" | "invalid"; allowsBranching?: TAllowsBranching; staticBranchNames?: string[]; dynamicBranchInput?: string; examplePayload?: object; } ``` -------------------------------- ### trigger() Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/trigger.md Creates a trigger object that can be referenced by a custom component. Triggers define the events that start a flow (webhooks, scheduled events, or app events). ```APIDOC ## trigger() ### Description Creates a trigger object that can be referenced by a custom component. Triggers define the events that start a flow (webhooks, scheduled events, or app events). ### Signature ```typescript export const trigger = < TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean, TResult extends TriggerResult, >( definition: TriggerDefinition, ): TriggerDefinition ``` ### Parameters #### Path Parameters - **definition** (TriggerDefinition) - Required - A TriggerDefinition object including display information, inputs, and a perform function ### Return Type Returns the same `TriggerDefinition` object, validated and ready for use in a component. ### TriggerDefinition Interface ```typescript interface TriggerDefinition< TInputs extends Inputs = Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TAllowsBranching extends boolean = boolean, TResult extends TriggerResult = TriggerResult< TAllowsBranching, TriggerPayload >, > { /** Display information for the trigger in the Prismatic UI */ display: { label: string; description: string; }; /** Inputs to present when configuring the trigger */ inputs: TInputs; /** Function to execute when the trigger is invoked */ perform: TriggerPerformFunction; /** Whether this trigger can be scheduled */ scheduleSupport: "valid" | "invalid"; /** Whether this trigger supports synchronous HTTP responses */ synchronousResponseSupport: "valid" | "invalid"; /** Whether this trigger allows branching on dynamic values */ allowsBranching?: TAllowsBranching; /** Static branch names for triggers that support branching */ staticBranchNames?: string[]; /** Input field name for dynamic branching */ dynamicBranchInput?: string; /** Example output payload from this trigger */ examplePayload?: object; } ``` ### Usage Example ```typescript import { trigger, input } from "@prismatic-io/spectral"; import type { HttpResponse } from "@prismatic-io/spectral"; const webhookTrigger = trigger({ display: { label: "Acme Webhook", description: "Receives webhooks from Acme", }, inputs: { secret: input({ label: "Signing Secret", type: "password", required: true, comments: "Used to verify webhook signatures", }), }, scheduleSupport: "invalid", synchronousResponseSupport: "valid", perform: async (context, payload, { secret }) => { // Validate webhook signature const signature = payload.headers["x-acme-signature"]; if (!signature) { const response: HttpResponse = { statusCode: 401, contentType: "application/json", body: JSON.stringify({ error: "Missing signature" }), }; return Promise.resolve({ payload, response }); } context.logger.info("Webhook received from Acme"); // Return success response const response: HttpResponse = { statusCode: 200, contentType: "application/json", body: JSON.stringify({ received: true }), }; return Promise.resolve({ payload, response, }); }, examplePayload: { headers: { "content-type": "application/json", "x-acme-signature": "sha256=...", }, body: { eventType: "order.created", orderId: "12345" }, rawBody: { data: Buffer.from("..."), contentType: "application/json", }, }, }); export { webhookTrigger }; ``` ### TriggerPayload Type ```typescript interface TriggerPayload { headers: Record; queryParameters: Record; body: unknown; rawBody: { data: Buffer; contentType: string; }; webhookUrls: Record; webhookApiKeys: Record; } ``` ### TriggerResult Type ```typescript type TriggerResult = TAllowsBranching extends true ? { payload: TPayload; response?: HttpResponse; branchName: string; } : { payload: TPayload; response?: HttpResponse; }; ``` ### HttpResponse Type For synchronous triggers, you can return an HTTP response: ```typescript interface HttpResponse { statusCode: number; contentType: string; body: string; } ``` ### Trigger Scheduling If `scheduleSupport` is `"valid"`, the trigger can be scheduled using a cron expression in the integration definition. ### Source File `src/index.ts:503` ### See Also - [[pollingTrigger]] - [[input]] - [[component]] ``` -------------------------------- ### Define Instance Deployment Handler Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/configuration.md Implement logic to run when an integration instance is deployed. Useful for initializing resources or setting up external services. ```typescript onInstanceDeploy: async (context) => { context.logger.info("Instance deployed"); // Initialize resources, create webhooks, etc. } ``` -------------------------------- ### Define Complex Nested Structured Object Inputs Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/structuredObjectInput.md This example shows how to create deeply nested structured object inputs for contact information, including an address. ```typescript import { input, structuredObjectInput } from "@prismatic-io/spectral"; const address = structuredObjectInput({ label: "Address", inputs: { street: input({ label: "Street", type: "string", required: true, }), city: input({ label: "City", type: "string", required: true, }), state: input({ label: "State", type: "string", required: true, }), zip: input({ label: "ZIP Code", type: "string", required: true, }), }, }); const contact = structuredObjectInput({ label: "Contact Information", inputs: { email: input({ label: "Email", type: "string", required: true, }), phone: input({ label: "Phone", type: "string", required: false, }), address: address, // Nested structured object }, }); const person = structuredObjectInput({ label: "Person", inputs: { name: structuredObjectInput({ label: "Name", inputs: { first: input({ label: "First Name", type: "string", required: true, }), last: input({ label: "Last Name", type: "string", required: true, }), }, }), contact: contact, }, }); // In action: // person.name.first, person.name.last // person.contact.email, person.contact.phone // person.contact.address.street, etc. ``` -------------------------------- ### Raw Request Action - POST with JSON Body Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/buildRawRequestAction.md Demonstrates making a POST request with a JSON body. It shows how to set the method, URL, Content-Type header, and the JSON data. ```typescript const response = await actions.rawRequest({ connection: myConnection, method: "POST", url: "/items", headers: [{ key: "Content-Type", value: "application/json" }], data: JSON.stringify({ name: "New Item", description: "..." }), }); ``` -------------------------------- ### HTTP Client with Authorization Header Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/api-reference/createClient.md Shows how to configure the HTTP client with an Authorization header for authenticated requests. The client is created with a base URL and a Bearer token in the headers. ```typescript const client = createClient({ baseUrl: "https://api.example.com", headers: { Authorization: `Bearer ${accessToken}`, }, }); const { data } = await client.get("/profile"); ``` -------------------------------- ### Type Imports Example Source: https://github.com/prismatic-io/spectral/blob/main/_autodocs/module-exports.md Imports type definitions using the 'import type' syntax. This is used for type checking and defining variable types without affecting runtime. ```typescript import type { ActionDefinition, TriggerDefinition, ComponentDefinition, IntegrationDefinition, Flow, InputFieldDefinition, Connection, Inputs, } from "@prismatic-io/spectral"; ```