@prismatic-io/spectral 8.0.0-preview7 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -162,7 +162,7 @@ export declare const buildRawRequestAction: (baseUrl: string, label?: string, de
162
162
  type: "connection";
163
163
  required: true;
164
164
  };
165
- }, boolean, {
165
+ }, import("../..").ConfigVarResultCollection, boolean, {
166
166
  data: any;
167
167
  }>;
168
168
  export { inputs };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * authors create inputs, actions, and components that can
4
4
  * be processed by the Prismatic API.
5
5
  */
6
- import { ActionDefinition, InputFieldDefinition, ComponentDefinition, DefaultConnectionDefinition, OAuth2ConnectionDefinition, Inputs, TriggerDefinition, ActionPerformReturn, TriggerResult, DataSourceDefinition, IntegrationDefinition, Flow, ConfigPage } from "./types";
6
+ import { ActionDefinition, InputFieldDefinition, ComponentDefinition, DefaultConnectionDefinition, OAuth2ConnectionDefinition, Inputs, TriggerDefinition, ActionPerformReturn, TriggerResult, DataSourceDefinition, IntegrationDefinition, Flow, ConfigPage, StandardConfigVar, ConnectionConfigVar, ConfigVar, ConfigVarResultCollection, ConfigVarCollection, TriggerPayload } from "./types";
7
7
  import { convertComponent, convertIntegration } from "./serverTypes/convert";
8
8
  /**
9
9
  * This function creates a Integration object that can be
@@ -13,21 +13,35 @@ import { convertComponent, convertIntegration } from "./serverTypes/convert";
13
13
  * @param definition An IntegrationDefinition type object.
14
14
  * @returns This function returns an integration object that has the shape the Prismatic API expects.
15
15
  */
16
- export declare const integration: (definition: IntegrationDefinition) => ReturnType<typeof convertIntegration>;
16
+ export declare const integration: <TConfigVar extends Record<string, ConfigVar> = Record<string, ConfigVar>>(definition: IntegrationDefinition<TConfigVar>) => ReturnType<typeof convertIntegration>;
17
17
  /**
18
18
  * For information on writing Code Native Integrations, see
19
19
  * https://prismatic.io/docs/code-native-integrations/#adding-flows.
20
20
  * @param definition A Flow type object.
21
21
  * @returns This function returns a flow object that has the shape the Prismatic API expects.
22
22
  */
23
- export declare const flow: <T extends Flow>(definition: T) => T;
23
+ export declare const flow: <TConfigVars extends ConfigVarCollection = ConfigVarCollection, TTriggerPayload extends TriggerPayload = TriggerPayload, T extends Flow<TConfigVars, TTriggerPayload> = Flow<TConfigVars, TTriggerPayload>>(definition: T) => T;
24
24
  /**
25
25
  * For information on writing Code Native Integrations, see
26
26
  * https://prismatic.io/docs/code-native-integrations/#adding-config-pages.
27
27
  * @param definition A Config Page type object.
28
28
  * @returns This function returns a config page object that has the shape the Prismatic API expects.
29
29
  */
30
- export declare const configPage: <T extends ConfigPage>(definition: T) => T;
30
+ export declare const configPage: <T extends ConfigPage<ConfigVarCollection>>(definition: T) => T;
31
+ /**
32
+ * For information on writing Code Native Integrations, see
33
+ * https://prismatic.io/docs/code-native-integrations/#adding-config-vars.
34
+ * @param definition A Config Var type object.
35
+ * @returns This function returns a standard config var object that has the shape the Prismatic API expects.
36
+ */
37
+ export declare const configVar: <T extends StandardConfigVar>(definition: T) => T;
38
+ /**
39
+ * For information on writing Code Native Integrations, see
40
+ * https://prismatic.io/docs/code-native-integrations/#adding-config-vars.
41
+ * @param definition A Connection Config Var type object.
42
+ * @returns This function returns a connection config var object that has the shape the Prismatic API expects.
43
+ */
44
+ export declare const connectionConfigVar: <T extends ConnectionConfigVar>(definition: T) => T;
31
45
  /**
32
46
  * This function creates a component object that can be
33
47
  * imported into the Prismatic API. For information on using
@@ -46,7 +60,7 @@ export declare const component: <TPublic extends boolean, TKey extends string>(d
46
60
  * @param definition An ActionDefinition type object that includes UI display information, a function to perform when the action is invoked, and a an object containing inputs for the perform function.
47
61
  * @returns This function validates the shape of the `definition` object provided, and returns the same action object.
48
62
  */
49
- export declare const action: <TInputs extends Inputs, TAllowsBranching extends boolean, TReturn extends ActionPerformReturn<TAllowsBranching, unknown>>(definition: ActionDefinition<TInputs, TAllowsBranching, TReturn>) => ActionDefinition<TInputs, TAllowsBranching, TReturn>;
63
+ export declare const action: <TInputs extends Inputs, TConfigVar extends ConfigVarResultCollection, TAllowsBranching extends boolean, TReturn extends ActionPerformReturn<TAllowsBranching, unknown>>(definition: ActionDefinition<TInputs, TConfigVar, TAllowsBranching, TReturn>) => ActionDefinition<TInputs, TConfigVar, TAllowsBranching, TReturn>;
50
64
  /**
51
65
  * This function creates a trigger object that can be referenced
52
66
  * by a custom component. It helps ensure that the shape of the
@@ -56,7 +70,7 @@ export declare const action: <TInputs extends Inputs, TAllowsBranching extends b
56
70
  * @param definition A TriggerDefinition type object that includes UI display information, a function to perform when the trigger is invoked, and a an object containing inputs for the perform function.
57
71
  * @returns This function validates the shape of the `definition` object provided, and returns the same trigger object.
58
72
  */
59
- export declare const trigger: <TInputs extends Inputs, TAllowsBranching extends boolean, TResult extends TriggerResult<TAllowsBranching>>(definition: TriggerDefinition<TInputs, TAllowsBranching, TResult>) => TriggerDefinition<TInputs, TAllowsBranching, TResult>;
73
+ export declare const trigger: <TInputs extends Inputs, TConfigVar extends ConfigVarResultCollection, TAllowsBranching extends boolean, TResult extends TriggerResult<TAllowsBranching, TriggerPayload>>(definition: TriggerDefinition<TInputs, TConfigVar, TAllowsBranching, TResult>) => TriggerDefinition<TInputs, TConfigVar, TAllowsBranching, TResult>;
60
74
  /**
61
75
  * This function creates a data source object that can be referenced
62
76
  * by a custom component. It helps ensure that the shape of the
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.testing = exports.util = exports.oauth2Connection = exports.connection = exports.input = exports.dataSource = exports.trigger = exports.action = exports.component = exports.configPage = exports.flow = exports.integration = void 0;
25
+ exports.testing = exports.util = exports.oauth2Connection = exports.connection = exports.input = exports.dataSource = exports.trigger = exports.action = exports.component = exports.connectionConfigVar = exports.configVar = exports.configPage = exports.flow = exports.integration = void 0;
26
26
  const convert_1 = require("./serverTypes/convert");
27
27
  /**
28
28
  * This function creates a Integration object that can be
@@ -50,6 +50,22 @@ exports.flow = flow;
50
50
  */
51
51
  const configPage = (definition) => definition;
52
52
  exports.configPage = configPage;
53
+ /**
54
+ * For information on writing Code Native Integrations, see
55
+ * https://prismatic.io/docs/code-native-integrations/#adding-config-vars.
56
+ * @param definition A Config Var type object.
57
+ * @returns This function returns a standard config var object that has the shape the Prismatic API expects.
58
+ */
59
+ const configVar = (definition) => definition;
60
+ exports.configVar = configVar;
61
+ /**
62
+ * For information on writing Code Native Integrations, see
63
+ * https://prismatic.io/docs/code-native-integrations/#adding-config-vars.
64
+ * @param definition A Connection Config Var type object.
65
+ * @returns This function returns a connection config var object that has the shape the Prismatic API expects.
66
+ */
67
+ const connectionConfigVar = (definition) => definition;
68
+ exports.connectionConfigVar = connectionConfigVar;
53
69
  /**
54
70
  * This function creates a component object that can be
55
71
  * imported into the Prismatic API. For information on using
@@ -121,12 +121,12 @@ const codeNativeIntegrationYaml = ({ name, description, category, documentation,
121
121
  documentation,
122
122
  version,
123
123
  labels,
124
- requiredConfigVars: configVars === null || configVars === void 0 ? void 0 : configVars.map((configVar) => convertConfigVar(configVar, referenceKey)),
124
+ requiredConfigVars: Object.entries(configVars || {}).map(([key, configVar]) => convertConfigVar(Object.assign(Object.assign({}, configVar), { key }), referenceKey)),
125
125
  endpointType,
126
126
  preprocessFlowName: hasPreprocessFlow ? preprocessFlows[0].name : undefined,
127
- externalCustomerIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "action" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerIdField),
128
- externalCustomerUserIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "action" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerUserIdField),
129
- flowNameField: fieldNameToReferenceInput(hasPreprocessFlow ? "action" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.flowNameField),
127
+ externalCustomerIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerIdField),
128
+ externalCustomerUserIdField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.externalCustomerUserIdField),
129
+ flowNameField: fieldNameToReferenceInput(hasPreprocessFlow ? "onExecution" : "payload", preprocessFlowConfig === null || preprocessFlowConfig === void 0 ? void 0 : preprocessFlowConfig.flowNameField),
130
130
  flows: flows.map((flow) => convertFlow(flow, referenceKey)),
131
131
  configPages,
132
132
  };
@@ -135,30 +135,24 @@ const codeNativeIntegrationYaml = ({ name, description, category, documentation,
135
135
  /** Converts a Flow into the structure necessary for YAML generation. */
136
136
  const convertFlow = (flow, referenceKey) => {
137
137
  const result = Object.assign({}, flow);
138
+ delete result.onTrigger;
138
139
  delete result.trigger;
139
- delete result.action;
140
+ delete result.onInstanceDeploy;
141
+ delete result.onInstanceDelete;
142
+ delete result.onExecution;
140
143
  delete result.preprocessFlowConfig;
144
+ delete result.errorConfig;
141
145
  const triggerStep = {
142
- name: "trigger",
146
+ name: "On Trigger",
147
+ stableKey: `${flow.stableKey}-onTrigger`,
148
+ description: "The function that will be executed by the flow to return an HTTP response.",
143
149
  isTrigger: true,
144
- errorConfig: "errorConfig" in flow.trigger ? flow.trigger.errorConfig : undefined,
145
- };
146
- if ("perform" in flow.trigger) {
147
- triggerStep.action = {
148
- key: flowFunctionKey(flow.name, "trigger"),
150
+ errorConfig: "errorConfig" in flow ? Object.assign({}, flow.errorConfig) : undefined,
151
+ action: {
152
+ key: flowFunctionKey(flow.name, "onTrigger"),
149
153
  component: { key: referenceKey, version: "LATEST", isPublic: false },
150
- };
151
- }
152
- else {
153
- triggerStep.action = {
154
- key: flow.trigger.key,
155
- component: flow.trigger.component,
156
- };
157
- }
158
- if ("inputs" in flow.trigger) {
159
- triggerStep.inputs = flow.trigger.inputs;
160
- delete result.inputs;
161
- }
154
+ },
155
+ };
162
156
  if ("schedule" in flow && typeof flow.schedule === "object") {
163
157
  triggerStep.schedule = {
164
158
  type: "cronExpression" in flow.schedule
@@ -176,34 +170,72 @@ const convertFlow = (flow, referenceKey) => {
176
170
  }
177
171
  const actionStep = {
178
172
  action: {
179
- key: flowFunctionKey(flow.name, "action"),
173
+ key: flowFunctionKey(flow.name, "onExecution"),
180
174
  component: { key: referenceKey, version: "LATEST", isPublic: false },
181
175
  },
182
- name: "action",
183
- errorConfig: "errorConfig" in flow.action ? flow.action.errorConfig : undefined,
176
+ name: "On Execution",
177
+ stableKey: `${flow.stableKey}-onExecution`,
178
+ description: "The function that will be executed by the flow.",
179
+ errorConfig: "errorConfig" in flow ? Object.assign({}, flow.errorConfig) : undefined,
184
180
  };
185
181
  result.steps = [triggerStep, actionStep];
186
182
  return result;
187
183
  };
188
184
  /** Converts a Config Var into the structure necessary for YAML generation. */
189
185
  const convertConfigVar = (configVar, referenceKey) => {
190
- const result = Object.assign(Object.assign({}, configVar), { meta: {} });
186
+ // This is unfortunate but we need to strip out some fields that are not
187
+ // relevant to config vars.
188
+ const fields = [
189
+ "key",
190
+ "stableKey",
191
+ "description",
192
+ "orgOnly",
193
+ "inputs",
194
+ "defaultValue",
195
+ "dataType",
196
+ "pickList",
197
+ "scheduleType",
198
+ "timeZone",
199
+ "codeLanguage",
200
+ "collectionType",
201
+ "dataSource",
202
+ ];
203
+ const result = Object.entries(configVar).reduce((result, [key, value]) => {
204
+ if (!fields.includes(key)) {
205
+ return result;
206
+ }
207
+ return Object.assign(Object.assign({}, result), { [key]: value });
208
+ }, { meta: {} });
191
209
  // Handle some non-standard fields.
192
- if ("visibleToOrgDeployer" in result) {
193
- result.meta.visibleToOrgDeployer = result.visibleToOrgDeployer;
194
- delete result.visibleToOrgDeployer;
210
+ if ("visibleToOrgDeployer" in configVar) {
211
+ result.meta.visibleToOrgDeployer = configVar.visibleToOrgDeployer;
195
212
  }
196
- if ("visibleToCustomerDeployer" in result) {
197
- result.meta.visibleToCustomerDeployer = result.visibleToCustomerDeployer;
198
- delete result.visibleToCustomerDeployer;
213
+ if ("visibleToCustomerDeployer" in configVar) {
214
+ result.meta.visibleToCustomerDeployer = configVar.visibleToCustomerDeployer;
199
215
  }
200
- if ("connection" in result && typeof result.connection === "string") {
216
+ // Handle connections.
217
+ if ("label" in configVar) {
218
+ result.dataType = "connection";
219
+ // This refers to a connection we are creating.
201
220
  result.connection = {
202
- key: result.connection,
221
+ key: configVar.key,
203
222
  component: { key: referenceKey, version: "LATEST", isPublic: false },
204
223
  };
224
+ result.description = configVar.label;
225
+ // Convert connection inputs to the inputs expected in the YAML.
226
+ // FIXME: This is just a placeholder for now.
227
+ // TODO: It seems like using the default value as the value is probably correct?
228
+ result.inputs = Object.entries(configVar.inputs).reduce((result, [key, input]) => {
229
+ var _a;
230
+ return Object.assign(Object.assign({}, result), { [key]: {
231
+ type: types_1.SimpleInputValueType.Value,
232
+ value: (_a = input.default) !== null && _a !== void 0 ? _a : "",
233
+ } });
234
+ }, {});
205
235
  }
206
- if ("dataSource" in result && typeof result.dataSource === "string") {
236
+ // Handle data source references.
237
+ if ("dataSource" in result) {
238
+ // This is a reference to a data source we are creating.
207
239
  result.dataSource = {
208
240
  key: result.dataSource,
209
241
  component: { key: referenceKey, version: "LATEST", isPublic: false },
@@ -233,24 +265,54 @@ const flowFunctionKey = (flowName, functionName) => {
233
265
  ? w.toLowerCase()
234
266
  : w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
235
267
  .join("");
236
- // functionName is only going to be either 'action' or 'trigger'.
237
268
  return `${flowKey}_${functionName}`;
238
269
  };
239
270
  /** Creates the structure necessary to import a Component as part of a
240
271
  * Code Native integration. */
241
- const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [], dataSources = {}, connections = [], }, referenceKey) => {
242
- const convertedActions = flows.reduce((result, { name, action }) => {
243
- const actionKey = flowFunctionKey(name, "action");
244
- return Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, Object.assign(Object.assign({}, action), { display: { label: "action", description: "" }, inputs: {} })) });
272
+ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [], dataSources = {}, configVars = {}, }, referenceKey) => {
273
+ const convertedActions = flows.reduce((result, { name, onExecution }) => {
274
+ const actionKey = flowFunctionKey(name, "onExecution");
275
+ return Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, {
276
+ display: {
277
+ label: `${name} - onExecution`,
278
+ description: "The function that will be executed by the flow.",
279
+ },
280
+ perform: onExecution,
281
+ inputs: {},
282
+ }) });
245
283
  }, {});
246
- const convertedTriggers = flows.reduce((result, { name, trigger }) => {
284
+ const convertedTriggers = flows.reduce((result, flow) => {
247
285
  // Filter out TriggerReferences.
248
- if (typeof trigger !== "object" || !("perform" in trigger))
286
+ if ("trigger" in flow)
249
287
  return result;
250
- const triggerKey = flowFunctionKey(name, "trigger");
251
- return Object.assign(Object.assign({}, result), { [triggerKey]: convertTrigger(triggerKey, Object.assign(Object.assign({}, trigger), { display: { label: "trigger", description: "" }, inputs: {}, scheduleSupport: "valid", synchronousResponseSupport: "valid" })) });
288
+ const { name, onTrigger, onInstanceDeploy, onInstanceDelete } = flow;
289
+ const triggerKey = flowFunctionKey(name, "onTrigger");
290
+ return Object.assign(Object.assign({}, result), { [triggerKey]: convertTrigger(triggerKey, {
291
+ display: {
292
+ label: `${name} - onTrigger`,
293
+ description: "The function that will be executed by the flow to return an HTTP response.",
294
+ },
295
+ perform: onTrigger,
296
+ onInstanceDeploy: onInstanceDeploy,
297
+ onInstanceDelete: onInstanceDelete,
298
+ inputs: {},
299
+ scheduleSupport: "valid",
300
+ synchronousResponseSupport: "valid",
301
+ }) });
252
302
  }, {});
253
303
  const convertedDataSources = Object.entries(dataSources).reduce((result, [dataSourceKey, dataSource]) => (Object.assign(Object.assign({}, result), { [dataSourceKey]: convertDataSource(dataSourceKey, Object.assign(Object.assign({}, dataSource), { inputs: {} })) })), {});
304
+ const convertedConnections = Object.entries(configVars).reduce((result, [key, configVar]) => {
305
+ if (!("label" in configVar)) {
306
+ return result;
307
+ }
308
+ // Remove a few fields that are not relevant to connections.
309
+ const {
310
+ /* eslint-disable @typescript-eslint/no-unused-vars */
311
+ orgOnly, visibleToOrgDeployer, visibleToCustomerDeployer, stableKey } = configVar,
312
+ /* eslint-enable @typescript-eslint/no-unused-vars */
313
+ connection = __rest(configVar, ["orgOnly", "visibleToOrgDeployer", "visibleToCustomerDeployer", "stableKey"]);
314
+ return [...result, convertConnection(Object.assign(Object.assign({}, connection), { key }))];
315
+ }, []);
254
316
  return {
255
317
  key: referenceKey,
256
318
  display: {
@@ -258,7 +320,7 @@ const codeNativeIntegrationComponent = ({ name, iconPath, description, flows = [
258
320
  iconPath,
259
321
  description: description || name,
260
322
  },
261
- connections: connections.map(convertConnection),
323
+ connections: convertedConnections,
262
324
  actions: convertedActions,
263
325
  triggers: convertedTriggers,
264
326
  dataSources: convertedDataSources,
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { InstanceAttributes, CustomerAttributes, DataSourceType, DataSourceResultType, UserAttributes, TriggerEventFunctionReturn, IntegrationAttributes, FlowAttributes } from "../types";
2
+ import { InstanceAttributes, CustomerAttributes, DataSourceType, DataSourceResultType, UserAttributes, TriggerEventFunctionReturn, IntegrationAttributes, FlowAttributes, ConfigVarResultCollection } from "../types";
3
3
  interface DisplayDefinition {
4
4
  label: string;
5
5
  description: string;
@@ -48,9 +48,8 @@ export interface ActionLogger {
48
48
  warn: ActionLoggerFunction;
49
49
  error: ActionLoggerFunction;
50
50
  }
51
- export interface ActionContext {
51
+ export declare type ActionContext<TConfigVars extends ConfigVarResultCollection, THasConfigVars extends boolean = false> = {
52
52
  logger: ActionLogger;
53
- configVars?: Record<string, unknown>;
54
53
  instanceState: Record<string, unknown>;
55
54
  crossFlowState: Record<string, unknown>;
56
55
  executionState: Record<string, unknown>;
@@ -66,7 +65,9 @@ export interface ActionContext {
66
65
  integration: IntegrationAttributes;
67
66
  flow: FlowAttributes;
68
67
  startedAt: string;
69
- }
68
+ } & (THasConfigVars extends true ? {
69
+ configVars: TConfigVars;
70
+ } : Record<string, never>);
70
71
  declare type TriggerOptionChoice = "invalid" | "valid" | "required";
71
72
  export interface TriggerPayload {
72
73
  headers: Record<string, string>;
@@ -111,9 +112,9 @@ interface TriggerBranchingResult extends TriggerBaseResult {
111
112
  branch: string;
112
113
  }
113
114
  export declare type TriggerResult = TriggerBranchingResult | TriggerBaseResult | undefined;
114
- export declare type TriggerPerformFunction = (context: ActionContext, payload: TriggerPayload, params: Record<string, unknown>) => Promise<TriggerResult>;
115
+ export declare type TriggerPerformFunction = (context: ActionContext<any>, payload: TriggerPayload, params: Record<string, unknown>) => Promise<TriggerResult>;
115
116
  export declare type TriggerEventFunctionResult = TriggerEventFunctionReturn | void;
116
- export declare type TriggerEventFunction = (context: ActionContext, params: Record<string, unknown>) => Promise<TriggerEventFunctionResult>;
117
+ export declare type TriggerEventFunction = (context: ActionContext<any>, params: Record<string, unknown>) => Promise<TriggerEventFunctionResult>;
117
118
  export interface Trigger {
118
119
  key: string;
119
120
  display: DisplayDefinition & {
@@ -213,7 +214,7 @@ interface ServerPerformBranchingDataReturn extends ServerPerformDataReturn {
213
214
  branch: string;
214
215
  }
215
216
  export declare type ActionPerformReturn = ServerPerformDataStructureReturn | ServerPerformBranchingDataStructureReturn | ServerPerformDataReturn | ServerPerformBranchingDataReturn | undefined;
216
- export declare type ActionPerformFunction = (context: ActionContext, params: Record<string, unknown>) => Promise<ActionPerformReturn>;
217
+ export declare type ActionPerformFunction = (context: ActionContext<any>, params: Record<string, unknown>) => Promise<ActionPerformReturn>;
217
218
  interface InputFieldChoice {
218
219
  label: string;
219
220
  value: string;
package/dist/testing.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * https://prismatic.io/docs/custom-components/writing-custom-components/#testing-a-component
6
6
  */
7
7
  import { TriggerPayload, TriggerResult, ConnectionValue, ActionLogger, Component, ActionContext, ActionPerformReturn, DataSourceResult, DataSourceContext } from "./serverTypes";
8
- import { ConnectionDefinition, ActionDefinition, TriggerDefinition, Inputs, ActionInputParameters, DataSourceDefinition, ActionPerformReturn as InvokeActionPerformReturn, TriggerResult as InvokeTriggerResult, DataSourceResult as InvokeDataSourceResult, TriggerEventFunctionReturn, Flow } from "./types";
8
+ import { ConnectionDefinition, ActionDefinition, TriggerDefinition, Inputs, ActionInputParameters, DataSourceDefinition, ActionPerformReturn as InvokeActionPerformReturn, TriggerResult as InvokeTriggerResult, DataSourceResult as InvokeDataSourceResult, TriggerEventFunctionReturn, Flow, ConfigVarResultCollection, ConfigVarCollection, ConfigVarDefinitionsToResults } from "./types";
9
9
  export declare const createConnection: <T extends ConnectionDefinition>({ key }: T, values: Record<string, unknown>, tokenValues?: Record<string, unknown> | undefined) => ConnectionValue;
10
10
  /**
11
11
  * Pre-built mock of ActionLogger. Suitable for asserting logs are created as expected.
@@ -25,7 +25,7 @@ interface InvokeReturn<ReturnData> {
25
25
  * to avoid extra casting within test methods. Returns an InvokeResult containing both the
26
26
  * action result and a mock logger for asserting logging.
27
27
  */
28
- export declare const invoke: <TInputs extends Inputs, TAllowsBranching extends boolean, TReturn extends InvokeActionPerformReturn<TAllowsBranching, unknown>>({ perform }: ActionDefinition<TInputs, TAllowsBranching, TReturn>, params: ActionInputParameters<TInputs>, context?: Partial<ActionContext> | undefined) => Promise<InvokeReturn<TReturn>>;
28
+ export declare const invoke: <TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean, TReturn extends InvokeActionPerformReturn<TAllowsBranching, unknown>>({ perform, }: ActionDefinition<TInputs, TConfigVars, TAllowsBranching, TReturn>, params: ActionInputParameters<TInputs>, context?: Partial<ActionContext<TConfigVars, false>> | undefined) => Promise<InvokeReturn<TReturn>>;
29
29
  export declare const defaultTriggerPayload: () => TriggerPayload;
30
30
  /**
31
31
  * Invokes specified TriggerDefinition perform function using supplied params
@@ -33,7 +33,7 @@ export declare const defaultTriggerPayload: () => TriggerPayload;
33
33
  * to avoid extra casting within test methods. Returns an InvokeResult containing both the
34
34
  * trigger result and a mock logger for asserting logging.
35
35
  */
36
- export declare const invokeTrigger: <TInputs extends Inputs, TAllowsBranching extends boolean, TResult extends InvokeTriggerResult<TAllowsBranching>>({ perform }: TriggerDefinition<TInputs, TAllowsBranching, TResult>, context?: Partial<ActionContext> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<TInputs> | undefined) => Promise<InvokeReturn<TResult>>;
36
+ export declare const invokeTrigger: <TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean, TResult extends InvokeTriggerResult<TAllowsBranching, TriggerPayload>>({ perform, }: TriggerDefinition<TInputs, TConfigVars, TAllowsBranching, TResult>, context?: Partial<ActionContext<TConfigVars, false>> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<TInputs> | undefined) => Promise<InvokeReturn<TResult>>;
37
37
  /**
38
38
  * Invokes specified DataSourceDefinition perform function using supplied params.
39
39
  * Accepts a generic type matching DataSourceResult as a convenience to avoid extra
@@ -60,24 +60,24 @@ export declare const invokeDataSource: <TInputs extends Inputs, TDataSourceType
60
60
  * Invokes specified Flow of a Code Native Integration using supplied params.
61
61
  * Runs the Trigger and then the Action function and returns the result of the Action.
62
62
  */
63
- export declare const invokeFlow: ({ trigger, action }: Flow, context?: Partial<ActionContext> | undefined, payload?: TriggerPayload | undefined) => Promise<InvokeReturn<InvokeActionPerformReturn<false, unknown>>>;
63
+ export declare const invokeFlow: <TConfigVars extends ConfigVarCollection>(flow: Flow<TConfigVars, import("./types").TriggerPayload>, context?: Partial<ActionContext<ConfigVarDefinitionsToResults<TConfigVars>, true>> | undefined, payload?: TriggerPayload | undefined) => Promise<InvokeReturn<InvokeActionPerformReturn<false, unknown>>>;
64
64
  export declare class ComponentTestHarness<TComponent extends Component> {
65
65
  component: TComponent;
66
66
  constructor(component: TComponent);
67
67
  private buildContext;
68
68
  private buildParams;
69
69
  connectionValue({ key }: ConnectionDefinition): ConnectionValue;
70
- trigger(key: string, payload?: TriggerPayload, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<TriggerResult>;
71
- triggerOnInstanceDeploy(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<void | TriggerEventFunctionReturn>;
72
- triggerOnInstanceDelete(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<void | TriggerEventFunctionReturn>;
73
- action(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<ActionPerformReturn>;
70
+ trigger<TConfigVars extends ConfigVarResultCollection>(key: string, payload?: TriggerPayload, params?: Record<string, unknown>, context?: Partial<ActionContext<TConfigVars>>): Promise<TriggerResult>;
71
+ triggerOnInstanceDeploy<TConfigVars extends ConfigVarResultCollection>(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext<TConfigVars>>): Promise<void | TriggerEventFunctionReturn>;
72
+ triggerOnInstanceDelete<TConfigVars extends ConfigVarResultCollection>(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext<TConfigVars>>): Promise<void | TriggerEventFunctionReturn>;
73
+ action<TConfigVars extends ConfigVarResultCollection>(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext<TConfigVars>>): Promise<ActionPerformReturn>;
74
74
  dataSource(key: string, params?: Record<string, unknown>, context?: Partial<DataSourceContext>): Promise<DataSourceResult>;
75
75
  }
76
76
  export declare const createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
77
77
  declare const _default: {
78
78
  loggerMock: () => ActionLogger;
79
- invoke: <TInputs extends Inputs, TAllowsBranching extends boolean, TReturn extends InvokeActionPerformReturn<TAllowsBranching, unknown>>({ perform }: ActionDefinition<TInputs, TAllowsBranching, TReturn>, params: ActionInputParameters<TInputs>, context?: Partial<ActionContext> | undefined) => Promise<InvokeReturn<TReturn>>;
80
- invokeTrigger: <TInputs_1 extends Inputs, TAllowsBranching_1 extends boolean, TResult extends InvokeTriggerResult<TAllowsBranching_1>>({ perform }: TriggerDefinition<TInputs_1, TAllowsBranching_1, TResult>, context?: Partial<ActionContext> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<TInputs_1> | undefined) => Promise<InvokeReturn<TResult>>;
79
+ invoke: <TInputs extends Inputs, TConfigVars extends ConfigVarResultCollection, TAllowsBranching extends boolean, TReturn extends InvokeActionPerformReturn<TAllowsBranching, unknown>>({ perform, }: ActionDefinition<TInputs, TConfigVars, TAllowsBranching, TReturn>, params: ActionInputParameters<TInputs>, context?: Partial<ActionContext<TConfigVars, false>> | undefined) => Promise<InvokeReturn<TReturn>>;
80
+ invokeTrigger: <TInputs_1 extends Inputs, TConfigVars_1 extends ConfigVarResultCollection, TAllowsBranching_1 extends boolean, TResult extends InvokeTriggerResult<TAllowsBranching_1, TriggerPayload>>({ perform, }: TriggerDefinition<TInputs_1, TConfigVars_1, TAllowsBranching_1, TResult>, context?: Partial<ActionContext<TConfigVars_1, false>> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<TInputs_1> | undefined) => Promise<InvokeReturn<TResult>>;
81
81
  createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
82
82
  invokeDataSource: <TInputs_2 extends Inputs, TDataSourceType extends keyof {
83
83
  string: string;
package/dist/testing.js CHANGED
@@ -38,47 +38,32 @@ const loggerMock = () => ({
38
38
  error: (0, jest_mock_1.spyOn)(console, "error"),
39
39
  });
40
40
  exports.loggerMock = loggerMock;
41
- const baseActionContext = {
42
- logger: (0, exports.loggerMock)(),
43
- instanceState: {},
44
- crossFlowState: {},
45
- executionState: {},
46
- integrationState: {},
47
- stepId: "mockStepId",
48
- executionId: "mockExecutionId",
49
- webhookUrls: {
50
- "Flow 1": "https://example.com",
51
- },
52
- webhookApiKeys: {
53
- "Flow 1": ["example-123", "example-456"],
54
- },
55
- invokeUrl: "https://example.com",
56
- customer: {
57
- id: "customerId",
58
- name: "Customer 1",
59
- externalId: "1234",
60
- },
61
- instance: {
62
- id: "instanceId",
63
- name: "Instance 1",
64
- },
65
- user: {
66
- id: "userId",
67
- email: "user@example.com",
68
- name: "User 1",
69
- externalId: "1234",
70
- },
71
- integration: {
72
- id: "integrationId",
73
- name: "Integration 1",
74
- versionSequenceId: "1234",
75
- externalVersion: "1.0.0",
76
- },
77
- flow: {
78
- id: "flowId",
79
- name: "Flow 1",
80
- },
81
- startedAt: new Date().toISOString(),
41
+ const createActionContext = (context) => {
42
+ return Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, integrationState: {}, stepId: "mockStepId", executionId: "mockExecutionId", webhookUrls: {
43
+ "Flow 1": "https://example.com",
44
+ }, webhookApiKeys: {
45
+ "Flow 1": ["example-123", "example-456"],
46
+ }, invokeUrl: "https://example.com", customer: {
47
+ id: "customerId",
48
+ name: "Customer 1",
49
+ externalId: "1234",
50
+ }, instance: {
51
+ id: "instanceId",
52
+ name: "Instance 1",
53
+ }, user: {
54
+ id: "userId",
55
+ email: "user@example.com",
56
+ name: "User 1",
57
+ externalId: "1234",
58
+ }, integration: {
59
+ id: "integrationId",
60
+ name: "Integration 1",
61
+ versionSequenceId: "1234",
62
+ externalVersion: "1.0.0",
63
+ }, flow: {
64
+ id: "flowId",
65
+ name: "Flow 1",
66
+ }, startedAt: new Date().toISOString() }, context);
82
67
  };
83
68
  /**
84
69
  * Invokes specified ActionDefinition perform function using supplied params
@@ -86,8 +71,8 @@ const baseActionContext = {
86
71
  * to avoid extra casting within test methods. Returns an InvokeResult containing both the
87
72
  * action result and a mock logger for asserting logging.
88
73
  */
89
- const invoke = ({ perform }, params, context) => __awaiter(void 0, void 0, void 0, function* () {
90
- const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
74
+ const invoke = ({ perform, }, params, context) => __awaiter(void 0, void 0, void 0, function* () {
75
+ const realizedContext = createActionContext(context);
91
76
  const result = yield perform(realizedContext, params);
92
77
  return {
93
78
  result,
@@ -155,8 +140,8 @@ exports.defaultTriggerPayload = defaultTriggerPayload;
155
140
  * to avoid extra casting within test methods. Returns an InvokeResult containing both the
156
141
  * trigger result and a mock logger for asserting logging.
157
142
  */
158
- const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void 0, void 0, void 0, function* () {
159
- const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
143
+ const invokeTrigger = ({ perform, }, context, payload, params) => __awaiter(void 0, void 0, void 0, function* () {
144
+ const realizedContext = createActionContext(context);
160
145
  const realizedPayload = Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload);
161
146
  const realizedParams = params || {};
162
147
  const result = yield perform(realizedContext, realizedPayload, realizedParams);
@@ -199,15 +184,17 @@ exports.invokeDataSource = invokeDataSource;
199
184
  * Invokes specified Flow of a Code Native Integration using supplied params.
200
185
  * Runs the Trigger and then the Action function and returns the result of the Action.
201
186
  */
202
- const invokeFlow = ({ trigger, action }, context, payload) => __awaiter(void 0, void 0, void 0, function* () {
203
- const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
187
+ const invokeFlow = (flow, context, payload) => __awaiter(void 0, void 0, void 0, function* () {
188
+ const realizedContext = createActionContext(context);
204
189
  const realizedPayload = Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload);
205
- const params = {};
206
- if (typeof trigger === "object" && "perform" in trigger) {
207
- const triggerResult = yield trigger.perform(realizedContext, realizedPayload, params);
208
- params.trigger = triggerResult;
190
+ const params = {
191
+ onTrigger: { results: null },
192
+ };
193
+ if ("onTrigger" in flow) {
194
+ const triggerResult = yield flow.onTrigger(realizedContext, realizedPayload, params);
195
+ params.onTrigger = { results: triggerResult === null || triggerResult === void 0 ? void 0 : triggerResult.payload };
209
196
  }
210
- const result = yield action.perform(realizedContext, params);
197
+ const result = yield flow.onExecution(realizedContext, params);
211
198
  return {
212
199
  result,
213
200
  loggerMock: realizedContext.logger,
@@ -236,7 +223,7 @@ class ComponentTestHarness {
236
223
  trigger(key, payload, params, context) {
237
224
  return __awaiter(this, void 0, void 0, function* () {
238
225
  const trigger = this.component.triggers[key];
239
- return trigger.perform(this.buildContext(baseActionContext, context), Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), this.buildParams(trigger.inputs, params));
226
+ return trigger.perform(createActionContext(context), Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), this.buildParams(trigger.inputs, params));
240
227
  });
241
228
  }
242
229
  triggerOnInstanceDeploy(key, params, context) {
@@ -245,7 +232,7 @@ class ComponentTestHarness {
245
232
  if (!trigger.onInstanceDeploy) {
246
233
  throw new Error("Trigger does not support onInstanceDeploy");
247
234
  }
248
- return trigger.onInstanceDeploy(this.buildContext(baseActionContext, context), this.buildParams(trigger.inputs, params));
235
+ return trigger.onInstanceDeploy(createActionContext(context), this.buildParams(trigger.inputs, params));
249
236
  });
250
237
  }
251
238
  triggerOnInstanceDelete(key, params, context) {
@@ -254,13 +241,13 @@ class ComponentTestHarness {
254
241
  if (!trigger.onInstanceDelete) {
255
242
  throw new Error("Trigger does not support onInstanceDelete");
256
243
  }
257
- return trigger.onInstanceDelete(this.buildContext(baseActionContext, context), this.buildParams(trigger.inputs, params));
244
+ return trigger.onInstanceDelete(createActionContext(context), this.buildParams(trigger.inputs, params));
258
245
  });
259
246
  }
260
247
  action(key, params, context) {
261
248
  return __awaiter(this, void 0, void 0, function* () {
262
249
  const action = this.component.actions[key];
263
- return action.perform(this.buildContext(baseActionContext, context), this.buildParams(action.inputs, params));
250
+ return action.perform(createActionContext(context), this.buildParams(action.inputs, params));
264
251
  });
265
252
  }
266
253
  dataSource(key, params, context) {
@@ -1,13 +1,13 @@
1
- import { ActionDisplayDefinition, ActionPerformFunction, ActionPerformReturn, Inputs } from ".";
1
+ import { ActionDisplayDefinition, ActionPerformFunction, ActionPerformReturn, ConfigVarResultCollection, Inputs } from ".";
2
2
  /**
3
3
  * ActionDefinition is the type of the object that is passed in to `action` function to
4
4
  * define a component action.
5
5
  */
6
- export interface ActionDefinition<TInputs extends Inputs, TAllowsBranching extends boolean, TReturn extends ActionPerformReturn<TAllowsBranching, unknown>> {
6
+ export interface ActionDefinition<TInputs extends Inputs = Inputs, TConfigVars extends ConfigVarResultCollection = ConfigVarResultCollection, TAllowsBranching extends boolean = boolean, TReturn extends ActionPerformReturn<TAllowsBranching, unknown> = ActionPerformReturn<TAllowsBranching, unknown>> {
7
7
  /** Defines how the Action is displayed in the Prismatic interface. */
8
8
  display: ActionDisplayDefinition;
9
9
  /** Function to perform when this Action is invoked. */
10
- perform: ActionPerformFunction<TInputs, TAllowsBranching, TReturn>;
10
+ perform: ActionPerformFunction<TInputs, TConfigVars, false, TAllowsBranching, TReturn>;
11
11
  /** InputFields to present in the Prismatic interface for configuration of this Action. */
12
12
  inputs: TInputs;
13
13
  /** Optional attribute that specifies whether an Action will terminate execution.*/