import { AnyFunction, AwaitExpr, CallExpr, FunctionlessNode, ReferenceExpr } from "@functionless/ast"; import { ApiGatewayVtlIntegration } from "./api"; import { AppSyncVtlIntegration } from "./appsync"; import { ASL, ASLGraph } from "./asl"; import { EventBus, EventBusTargetIntegration } from "./event-bridge"; import { Function, NativeIntegration } from "./function"; import { VTL } from "./vtl"; export declare const isIntegration: >(i: any) => i is I; export interface IntegrationCallExpr extends CallExpr { } export declare function isIntegrationCallExpr(node: FunctionlessNode): node is IntegrationCallExpr; export declare type IntegrationCallPattern = CallExpr | (AwaitExpr & { expr: CallExpr; }); export declare function isIntegrationCallPattern(node: FunctionlessNode): node is IntegrationCallPattern; /** * Give the possible ways to define an integration, return just the call(ref) of the integration. */ export declare function getIntegrationExprFromIntegrationCallPattern(pattern: IntegrationCallPattern): IntegrationCallExpr | undefined; export declare const INTEGRATION_TYPE_KEYS: ("appSyncVtl" | "apiGWVtl" | "asl" | "eventBus" | "native")[]; /** * All integration methods supported by functionless. */ export interface IntegrationMethods { /** * Integrate with AppSync VTL applications. * @private */ appSyncVtl: AppSyncVtlIntegration; /** * Integrate with API Gateway VTL applications. * @private */ apiGWVtl: ApiGatewayVtlIntegration; /** * Integrate with ASL applications like StepFunctions. * * TODO: Update to use an interface https://github.com/functionless/functionless/issues/197 * * @private */ asl: (call: CallExpr, context: ASL) => ASLGraph.NodeResults; eventBus: EventBusTargetIntegration; /** * Native javascript code integrations that execute at runtime like Lambda. */ native: NativeIntegration; } /** * Integration types supported by Functionless. * * Add an integration by creating any object that has a property named "kind" and either implements the * {@link Integration} interface or has methods that implement it (or both). * * Example showing both strategies: * * ```ts * export class Function implements {@link Integration} { * readonly kind = "Function", * * // Integration Handler for ASL * public asl(call, context) { * // return Step Function task. * } * * // Example class method - some wrapper function that generates special ASL tasks when using a Function. * public specialPayload = makeIntegration<() => string>({ * kind: "Function.default", * asl: (call, context) => { * // return step function task * } * }); * } * * // an interface to provide the actual callable methods to users * export interface Function { * // call me to send a string payload * (payload: String) => string * } * * // use * * const func1 = new Function(...); * // uses the ASL * new StepFunction(..., async () => { * await func1("some string"); * // Calling our special method in a step function closure * await func1.specialPayload(); * }) * ``` * * If an integration does not support an integration type, leave the function undefined or throw an error. * * Implement the unhandledContext function to customize the error message for unsupported contexts. * Otherwise the error will be: `${this.name} is not supported by context ${context.kindStr}.` */ export interface Integration extends Partial> { /** * Brand the Function, F, into this type so that sub-typing rules apply to the function signature. */ __functionBrand: F; /** * Integration Handler kind - for example StepFunction.describeExecution */ readonly kind: K; /** * Optional method that allows overriding the {@link Error} thrown when a integration is not supported by a handler. * @param kind - The Kind of the integration. * @param contextKind - the Kind of the context attempting to use the integration. */ readonly unhandledContext?: (kind: string, contextKind: CallContext["kind"]) => Error; } /** * Alias that removes computed inputs from the integration interface */ export declare type IntegrationInput = Omit, "__functionBrand">; /** * Internal wrapper class for Integration handlers that provides default error handling for unsupported integrations. * * Functionless wraps Integration at runtime with this class. * @private */ export declare class IntegrationImpl implements IntegrationMethods { readonly integration: Integration; readonly kind: string; constructor(integration: Integration); private assertIntegrationDefined; get appSyncVtl(): AppSyncVtlIntegration; get apiGWVtl(): ApiGatewayVtlIntegration; asl(call: CallExpr, context: ASL): ASLGraph.NodeResults; get eventBus(): EventBusTargetIntegration; get native(): NativeIntegration; } export declare type IntegrationCall = { FunctionlessType: K; kind: K; __functionBrand: F; } & F; /** * Helper method which masks an {@link Integration} object as a function of any form. * * ```ts * export namespace MyIntegrations { * export const callMe = makeIntegration<(payload: string) => void>({ * asl: (call, context) => { ... } * }) * } * ``` * * Creates an integration object at callMe, which is callable by a user. * * ```ts * MyIntegrations.callMe("some string"); * ``` * * @private */ export declare function makeIntegration(integration: IntegrationInput): IntegrationCall; export declare type CallContext = ASL | VTL | Function | EventBus; export declare function findDeepIntegrations(ast: FunctionlessNode): CallExpr[]; /** * A bottom-up algorithm that determines the ONLY {@link Integration} value that the {@link node} * will resolve to at runtime. * * If the {@link node} resolves to 0 or more than 1 {@link Integration} then `undefined` is returned. * * **Note**: This function is an intermediate helper until we migrate the interpreters to be more general * (likely by migrating to top-down algorithms, see https://github.com/functionless/functionless/issues/374#issuecomment-1203313604) * * @param node the node to resolve the {@link Integration} of. * @returns the ONLY {@link Integration} that {@link node} can resolve to, otherwise `undefined`. */ export declare function tryFindIntegration(node: FunctionlessNode): Integration | undefined; /** * A bottom-up algorithm that determines all of the possible {@link Integration}s that a {@link node} * may resolve to at runtime. * * ```ts * declare const table1; * declare const table2; * * const tables = [table1, table2]; * * const a = table1; * // ^ [table1] * * for (const a of tables) { * const b = a; * // ^ [table1, table2] * * const { appsync: { getItem } } = a; * // ^ [ table1.appsync.getItem, table2.appsync.getItem ] * } * * const a = tables[0]; * // ^ [table1] * * const { appsync: { getItem } } = table[0]; * // ^ [ table1.appsync.getItem ] * * const { appsync: { getItem = table1.appsync.getItem } } = table[2]; * // ^ [ table1.appsync.getItem ] (because of initializer) * ``` * * @param node the node to resolve the possible {@link Integration}s of. * @returns a list of all the {@link Integration}s that the {@link node} could evaluate to. */ export declare function tryFindIntegrations(node: FunctionlessNode): Integration[]; /** * Resolve all of the possible values that {@link node} may resolve to at runtime. * * @param node * @param defaultValue default value to use if the value cannot be resolved (set by default initializers in BindingElement) * @returns an array of all the values the {@link node} resolves to. */ export declare function tryResolveReferences(node: FunctionlessNode | undefined, defaultValue?: FunctionlessNode): any[]; export declare const deploymentOnlyModule = true; //# sourceMappingURL=integration.d.ts.map