@prismatic-io/spectral 6.1.1 → 6.4.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.
@@ -6,6 +6,7 @@ export declare const url: {
6
6
  required: true;
7
7
  comments: string;
8
8
  example: string;
9
+ clean: (value: unknown) => string;
9
10
  };
10
11
  export declare const data: {
11
12
  label: string;
@@ -14,6 +15,7 @@ export declare const data: {
14
15
  required: false;
15
16
  comments: string;
16
17
  example: string;
18
+ clean: (value: unknown) => string;
17
19
  };
18
20
  export declare const timeout: {
19
21
  label: string;
@@ -21,6 +23,7 @@ export declare const timeout: {
21
23
  required: false;
22
24
  comments: string;
23
25
  example: string;
26
+ clean: (value: unknown) => number;
24
27
  };
25
28
  export declare const method: {
26
29
  label: string;
@@ -30,6 +33,7 @@ export declare const method: {
30
33
  value: Method;
31
34
  }[];
32
35
  comments: string;
36
+ clean: (value: unknown) => string;
33
37
  };
34
38
  export declare const responseType: {
35
39
  label: string;
@@ -42,6 +46,7 @@ export declare const responseType: {
42
46
  label: ResponseType;
43
47
  value: ResponseType;
44
48
  }[];
49
+ clean: (value: unknown) => string;
45
50
  };
46
51
  export declare const headers: {
47
52
  label: string;
@@ -67,6 +72,7 @@ export declare const maxRetries: {
67
72
  required: false;
68
73
  comments: string;
69
74
  default: string;
75
+ clean: (value: unknown) => number;
70
76
  };
71
77
  export declare const retryDelayMS: {
72
78
  label: string;
@@ -82,6 +88,7 @@ export declare const useExponentialBackoff: {
82
88
  default: string;
83
89
  required: false;
84
90
  comments: string;
91
+ clean: (value: unknown) => boolean;
85
92
  };
86
93
  export declare const retryOnAllErrors: {
87
94
  label: string;
@@ -89,6 +96,7 @@ export declare const retryOnAllErrors: {
89
96
  default: string;
90
97
  required: false;
91
98
  comments: string;
99
+ clean: (value: unknown) => boolean;
92
100
  };
93
101
  export declare const formData: {
94
102
  label: string;
@@ -113,4 +121,5 @@ export declare const debugRequest: {
113
121
  type: "boolean";
114
122
  required: false;
115
123
  comments: string;
124
+ clean: (value: unknown) => boolean;
116
125
  };
@@ -27,6 +27,7 @@ exports.url = (0, __1.input)({
27
27
  required: true,
28
28
  comments: "This is the URL to call.",
29
29
  example: "/sobjects/Account",
30
+ clean: (value) => __1.util.types.toString(value),
30
31
  });
31
32
  exports.data = (0, __1.input)({
32
33
  label: "Data",
@@ -35,6 +36,7 @@ exports.data = (0, __1.input)({
35
36
  required: false,
36
37
  comments: "The HTTP body payload to send to the URL. Must be a string or a reference to output from a previous step.",
37
38
  example: '{"exampleKey": "Example Data"}',
39
+ clean: (value) => __1.util.types.toString(value),
38
40
  });
39
41
  exports.timeout = (0, __1.input)({
40
42
  label: "Timeout",
@@ -42,12 +44,14 @@ exports.timeout = (0, __1.input)({
42
44
  required: false,
43
45
  comments: "The maximum time that a client will await a response to its request",
44
46
  example: "2000",
47
+ clean: (value) => __1.util.types.toNumber(value),
45
48
  });
46
49
  exports.method = (0, __1.input)({
47
50
  label: "Method",
48
51
  type: "string",
49
52
  model: supportedMethods.map((method) => ({ label: method, value: method })),
50
53
  comments: "The HTTP method to use.",
54
+ clean: (value) => __1.util.types.toString(value),
51
55
  });
52
56
  exports.responseType = (0, __1.input)({
53
57
  label: "Response Type",
@@ -60,6 +64,7 @@ exports.responseType = (0, __1.input)({
60
64
  label: responseType,
61
65
  value: responseType,
62
66
  })),
67
+ clean: (value) => __1.util.types.toString(value),
63
68
  });
64
69
  exports.headers = (0, __1.input)({
65
70
  label: "Header",
@@ -85,6 +90,7 @@ exports.maxRetries = (0, __1.input)({
85
90
  required: false,
86
91
  comments: "The maximum number of retries to attempt.",
87
92
  default: "0",
93
+ clean: (value) => __1.util.types.toNumber(value),
88
94
  });
89
95
  exports.retryDelayMS = (0, __1.input)({
90
96
  label: "Retry Delay (ms)",
@@ -100,6 +106,7 @@ exports.useExponentialBackoff = (0, __1.input)({
100
106
  default: "false",
101
107
  required: false,
102
108
  comments: "Specifies whether to use a pre-defined exponential backoff strategy for retries.",
109
+ clean: (value) => __1.util.types.toBool(value),
103
110
  });
104
111
  exports.retryOnAllErrors = (0, __1.input)({
105
112
  label: "Retry On All Errors",
@@ -107,6 +114,7 @@ exports.retryOnAllErrors = (0, __1.input)({
107
114
  default: "false",
108
115
  required: false,
109
116
  comments: "If true, retries on all erroneous responses regardless of type.",
117
+ clean: (value) => __1.util.types.toBool(value),
110
118
  });
111
119
  exports.formData = (0, __1.input)({
112
120
  label: "Form Data",
@@ -131,4 +139,5 @@ exports.debugRequest = (0, __1.input)({
131
139
  type: "boolean",
132
140
  required: false,
133
141
  comments: "Enabling this flag will log out the current request.",
142
+ clean: (value) => __1.util.types.toBool(value),
134
143
  });
@@ -1,3 +1,3 @@
1
1
  import { ComponentDefinition } from "../types";
2
2
  import { Component as ServerComponent } from ".";
3
- export declare const convertComponent: <TPublic extends boolean = false>({ connections, actions, triggers, hooks, ...definition }: ComponentDefinition<TPublic>) => ServerComponent;
3
+ export declare const convertComponent: <TPublic extends boolean>({ connections, actions, triggers, hooks, ...definition }: ComponentDefinition<TPublic>) => ServerComponent;
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __rest = (this && this.__rest) || function (s, e) {
12
3
  var t = {};
13
4
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -21,40 +12,42 @@ var __rest = (this && this.__rest) || function (s, e) {
21
12
  };
22
13
  Object.defineProperty(exports, "__esModule", { value: true });
23
14
  exports.convertComponent = void 0;
24
- const serialize_error_1 = require("serialize-error");
25
- const util_1 = require("../util");
26
15
  const types_1 = require("../types");
27
- const wrapPerform = (fn, errorHandler) => {
28
- return (...args) => __awaiter(void 0, void 0, void 0, function* () {
29
- try {
30
- return yield fn(...args);
31
- }
32
- catch (error) {
33
- throw new Error((0, util_1.toJSON)((0, serialize_error_1.serializeError)(errorHandler(error))));
34
- }
35
- });
36
- };
16
+ const perform_1 = require("./perform");
37
17
  const convertInput = (key, _a) => {
38
18
  var { default: defaultValue, type, label, collection } = _a, rest = __rest(_a, ["default", "type", "label", "collection"]);
39
- return (Object.assign(Object.assign({}, rest), { key,
40
- type, default: defaultValue !== null && defaultValue !== void 0 ? defaultValue : types_1.InputFieldDefaultMap[type], collection, label: typeof label === "string" ? label : label.value, keyLabel: collection === "keyvaluelist" && typeof label === "object"
41
- ? label.key
42
- : undefined }));
19
+ const keyLabel = collection === "keyvaluelist" && typeof label === "object"
20
+ ? label.key
21
+ : undefined;
22
+ return Object.assign(Object.assign({}, rest), { key,
23
+ type, default: defaultValue !== null && defaultValue !== void 0 ? defaultValue : types_1.InputFieldDefaultMap[type], collection, label: typeof label === "string" ? label : label.value, keyLabel });
43
24
  };
44
25
  const convertAction = (actionKey, _a, hooks) => {
45
26
  var { inputs = {}, perform } = _a, action = __rest(_a, ["inputs", "perform"]);
46
- return (Object.assign(Object.assign({}, action), { key: actionKey, perform: (hooks === null || hooks === void 0 ? void 0 : hooks.error) ? wrapPerform(perform, hooks.error) : perform, inputs: Object.entries(inputs).map(([key, value]) => convertInput(key, value)) }));
27
+ const convertedInputs = Object.entries(inputs).map(([key, value]) => convertInput(key, value));
28
+ const inputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
29
+ return Object.assign(Object.assign({}, action), { key: actionKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
30
+ inputCleaners,
31
+ errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
32
+ }) });
47
33
  };
48
34
  const convertTrigger = (triggerKey, _a, hooks) => {
49
35
  var { inputs = {}, perform } = _a, trigger = __rest(_a, ["inputs", "perform"]);
50
- return (Object.assign(Object.assign({}, trigger), { key: triggerKey, perform: (hooks === null || hooks === void 0 ? void 0 : hooks.error) ? wrapPerform(perform, hooks.error) : perform, inputs: Object.entries(inputs).map(([key, value]) => convertInput(key, value)) }));
36
+ const convertedInputs = Object.entries(inputs).map(([key, value]) => convertInput(key, value));
37
+ return Object.assign(Object.assign({}, trigger), { key: triggerKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
38
+ inputCleaners: {},
39
+ errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
40
+ }) });
51
41
  };
52
- const convertConnection = (connection) => {
53
- var _a;
54
- return (Object.assign(Object.assign({}, connection), { inputs: Object.entries((_a = connection.inputs) !== null && _a !== void 0 ? _a : {}).map(([key, value]) => convertInput(key, value)) }));
42
+ const convertConnection = (_a) => {
43
+ var { inputs = {} } = _a, connection = __rest(_a, ["inputs"]);
44
+ const convertedInputs = Object.entries(inputs).map(([key, value]) => convertInput(key, value));
45
+ return Object.assign(Object.assign({}, connection), { inputs: convertedInputs });
55
46
  };
56
47
  const convertComponent = (_a) => {
57
48
  var { connections = [], actions = {}, triggers = {}, hooks } = _a, definition = __rest(_a, ["connections", "actions", "triggers", "hooks"]);
58
- return (Object.assign(Object.assign({}, definition), { connections: connections.map(convertConnection), actions: Object.entries(actions).reduce((result, [actionKey, action]) => (Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, action, hooks) })), {}), triggers: Object.entries(triggers).reduce((result, [triggerKey, trigger]) => (Object.assign(Object.assign({}, result), { [triggerKey]: convertTrigger(triggerKey, trigger, hooks) })), {}) }));
49
+ const convertedActions = Object.entries(actions).reduce((result, [actionKey, action]) => (Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, action, hooks) })), {});
50
+ const convertedTriggers = Object.entries(triggers).reduce((result, [triggerKey, trigger]) => (Object.assign(Object.assign({}, result), { [triggerKey]: convertTrigger(triggerKey, trigger, hooks) })), {});
51
+ return Object.assign(Object.assign({}, definition), { connections: connections.map(convertConnection), actions: convertedActions, triggers: convertedTriggers });
59
52
  };
60
53
  exports.convertComponent = convertComponent;
@@ -3,7 +3,7 @@ interface DisplayDefinition {
3
3
  label: string;
4
4
  description: string;
5
5
  }
6
- interface Component {
6
+ export interface Component {
7
7
  key: string;
8
8
  public?: boolean;
9
9
  documentationUrl?: string;
@@ -15,7 +15,7 @@ interface Component {
15
15
  triggers: Record<string, Trigger>;
16
16
  connections: Connection[];
17
17
  }
18
- interface Action {
18
+ export interface Action {
19
19
  key: string;
20
20
  display: DisplayDefinition & {
21
21
  directions?: string;
@@ -30,8 +30,8 @@ interface Action {
30
30
  perform: ActionPerformFunction;
31
31
  examplePayload?: unknown;
32
32
  }
33
- declare type ActionLoggerFunction = (...args: unknown[]) => void;
34
- interface ActionLogger {
33
+ export declare type ActionLoggerFunction = (...args: unknown[]) => void;
34
+ export interface ActionLogger {
35
35
  metric: ActionLoggerFunction;
36
36
  trace: ActionLoggerFunction;
37
37
  debug: ActionLoggerFunction;
@@ -40,7 +40,7 @@ interface ActionLogger {
40
40
  warn: ActionLoggerFunction;
41
41
  error: ActionLoggerFunction;
42
42
  }
43
- interface ActionContext {
43
+ export interface ActionContext {
44
44
  logger: ActionLogger;
45
45
  instanceState: Record<string, unknown>;
46
46
  crossFlowState: Record<string, unknown>;
@@ -49,7 +49,7 @@ interface ActionContext {
49
49
  executionId: string;
50
50
  }
51
51
  declare type TriggerOptionChoice = "invalid" | "valid" | "required";
52
- interface TriggerPayload {
52
+ export interface TriggerPayload {
53
53
  headers: Record<string, string>;
54
54
  queryParameters: Record<string, string>;
55
55
  rawBody: {
@@ -60,6 +60,7 @@ interface TriggerPayload {
60
60
  data: unknown;
61
61
  contentType?: string;
62
62
  };
63
+ pathFragment: string;
63
64
  webhookUrls: Record<string, string>;
64
65
  webhookApiKeys: Record<string, string[]>;
65
66
  invokeUrl: string;
@@ -90,9 +91,9 @@ interface TriggerBaseResult {
90
91
  interface TriggerBranchingResult extends TriggerBaseResult {
91
92
  branch: string;
92
93
  }
93
- declare type TriggerResult = TriggerBranchingResult | TriggerBaseResult | undefined;
94
- declare type TriggerPerformFunction = (context: ActionContext, payload: TriggerPayload, params: Record<string, unknown>) => Promise<TriggerResult>;
95
- interface Trigger {
94
+ export declare type TriggerResult = TriggerBranchingResult | TriggerBaseResult | undefined;
95
+ export declare type TriggerPerformFunction = (context: ActionContext, payload: TriggerPayload, params: Record<string, unknown>) => Promise<TriggerResult>;
96
+ export interface Trigger {
96
97
  key: string;
97
98
  display: DisplayDefinition & {
98
99
  directions?: string;
@@ -110,11 +111,11 @@ interface Trigger {
110
111
  examplePayload?: unknown;
111
112
  isCommonTrigger?: boolean;
112
113
  }
113
- declare enum OAuth2Type {
114
+ export declare enum OAuth2Type {
114
115
  ClientCredentials = "client_credentials",
115
116
  AuthorizationCode = "authorization_code"
116
117
  }
117
- interface Connection {
118
+ export interface Connection {
118
119
  key: string;
119
120
  label: string;
120
121
  comments?: string;
@@ -124,6 +125,15 @@ interface Connection {
124
125
  shown?: boolean;
125
126
  })[];
126
127
  }
128
+ export interface ConnectionValue {
129
+ key: string;
130
+ configVarKey: string;
131
+ fields: {
132
+ [key: string]: unknown;
133
+ };
134
+ token?: Record<string, unknown>;
135
+ context?: Record<string, unknown>;
136
+ }
127
137
  interface ServerPerformDataStructureReturn {
128
138
  data: boolean | number | string | Record<string, unknown> | unknown[] | unknown;
129
139
  contentType?: string;
@@ -146,13 +156,13 @@ interface ServerPerformBranchingDataStructureReturn extends ServerPerformDataStr
146
156
  interface ServerPerformBranchingDataReturn extends ServerPerformDataReturn {
147
157
  branch: string;
148
158
  }
149
- declare type ActionPerformReturn = ServerPerformDataStructureReturn | ServerPerformBranchingDataStructureReturn | ServerPerformDataReturn | ServerPerformBranchingDataReturn | undefined;
150
- declare type ActionPerformFunction = (context: ActionContext, params: Record<string, unknown>) => Promise<ActionPerformReturn>;
159
+ export declare type ActionPerformReturn = ServerPerformDataStructureReturn | ServerPerformBranchingDataStructureReturn | ServerPerformDataReturn | ServerPerformBranchingDataReturn | undefined;
160
+ export declare type ActionPerformFunction = (context: ActionContext, params: Record<string, unknown>) => Promise<ActionPerformReturn>;
151
161
  interface InputFieldChoice {
152
162
  label: string;
153
163
  value: string;
154
164
  }
155
- interface Input {
165
+ export interface Input {
156
166
  key: string;
157
167
  label: string;
158
168
  keyLabel?: string;
@@ -166,4 +176,4 @@ interface Input {
166
176
  model?: InputFieldChoice[];
167
177
  language?: string;
168
178
  }
169
- export type { Component, Trigger, Action, Connection, Input };
179
+ export {};
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OAuth2Type = void 0;
3
4
  var OAuth2Type;
4
5
  (function (OAuth2Type) {
5
6
  OAuth2Type["ClientCredentials"] = "client_credentials";
6
7
  OAuth2Type["AuthorizationCode"] = "authorization_code";
7
- })(OAuth2Type || (OAuth2Type = {}));
8
+ })(OAuth2Type = exports.OAuth2Type || (exports.OAuth2Type = {}));
@@ -0,0 +1,10 @@
1
+ import { ErrorHandler } from "../types";
2
+ declare type PerformFn = (...args: any[]) => Promise<any>;
3
+ export declare type CleanFn = (...args: any[]) => any;
4
+ export declare type InputCleaners = Record<string, CleanFn | undefined>;
5
+ interface CreatePerformProps {
6
+ inputCleaners: InputCleaners;
7
+ errorHandler?: ErrorHandler;
8
+ }
9
+ export declare const createPerform: (performFn: PerformFn, { inputCleaners, errorHandler }: CreatePerformProps) => PerformFn;
10
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.createPerform = void 0;
13
+ const serialize_error_1 = require("serialize-error");
14
+ const util_1 = require("../util");
15
+ const cleanParams = (params, cleaners) => Object.entries(params).reduce((result, [key, value]) => {
16
+ const cleanFn = cleaners[key];
17
+ return Object.assign(Object.assign({}, result), { [key]: cleanFn ? cleanFn(value) : value });
18
+ }, {});
19
+ const createPerform = (performFn, { inputCleaners, errorHandler }) => {
20
+ return (...args) => __awaiter(void 0, void 0, void 0, function* () {
21
+ try {
22
+ if (args.length === 2) {
23
+ const [context, params] = args;
24
+ return yield performFn(context, cleanParams(params, inputCleaners));
25
+ }
26
+ const [context, payload, params] = args;
27
+ return yield performFn(context, payload, cleanParams(params, inputCleaners));
28
+ }
29
+ catch (error) {
30
+ if (!errorHandler) {
31
+ throw error;
32
+ }
33
+ const handled = errorHandler(error);
34
+ const serialized = (0, util_1.toJSON)((0, serialize_error_1.serializeError)(handled));
35
+ throw new Error(serialized);
36
+ }
37
+ });
38
+ };
39
+ exports.createPerform = createPerform;
package/dist/testing.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * information on unit testing, check out our docs:
5
5
  * https://prismatic.io/docs/custom-components/writing-custom-components/#testing-a-component
6
6
  */
7
- /** */
8
- import { ActionContext, ActionLogger, ActionDefinition, ActionInputParameters, ConnectionDefinition, Connection, Inputs, TriggerDefinition, TriggerPayload } from "./types";
9
- export declare const createConnection: <T extends ConnectionDefinition>({ key }: T, values: Record<string, unknown>) => Connection;
7
+ import { TriggerPayload, TriggerResult, Connection, ConnectionValue, ActionLogger, Component, ActionContext, ActionPerformReturn } from "./serverTypes";
8
+ import { ConnectionDefinition, ActionDefinition, TriggerDefinition, Inputs, ActionInputParameters } from "./types";
9
+ export declare const createConnection: <T extends Connection>({ key }: T, values: Record<string, unknown>) => ConnectionValue;
10
10
  /**
11
11
  * Pre-built mock of ActionLogger. Suitable for asserting logs are created as expected.
12
12
  * See https://prismatic.io/docs/custom-components/writing-custom-components/#verifying-correct-logging-in-action-tests for information on testing correct logging behavior in your custom component.
@@ -34,9 +34,18 @@ export declare const defaultTriggerPayload: () => TriggerPayload;
34
34
  * trigger result and a mock logger for asserting logging.
35
35
  */
36
36
  export declare const invokeTrigger: <T extends Inputs>({ perform }: TriggerDefinition<T>, context?: Partial<ActionContext> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<T> | undefined) => Promise<InvokeReturn<import("./types").TriggerResult<boolean | undefined>>>;
37
+ export declare class ComponentTestHarness<TComponent extends Component> {
38
+ component: TComponent;
39
+ constructor(component: TComponent);
40
+ connectionValue({ key }: ConnectionDefinition): ConnectionValue;
41
+ trigger(key: string, payload?: TriggerPayload, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<TriggerResult>;
42
+ action(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<ActionPerformReturn>;
43
+ }
44
+ export declare const createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
37
45
  declare const _default: {
46
+ loggerMock: () => ActionLogger;
38
47
  invoke: <T extends Inputs>({ perform }: ActionDefinition<T>, params: ActionInputParameters<T>, context?: Partial<ActionContext> | undefined) => Promise<InvokeReturn<import("./types").ActionPerformReturn<boolean | undefined, unknown>>>;
39
48
  invokeTrigger: <T_1 extends Inputs>({ perform }: TriggerDefinition<T_1>, context?: Partial<ActionContext> | undefined, payload?: TriggerPayload | undefined, params?: ActionInputParameters<T_1> | undefined) => Promise<InvokeReturn<import("./types").TriggerResult<boolean | undefined>>>;
40
- loggerMock: () => ActionLogger;
49
+ createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
41
50
  };
42
51
  export default _default;
package/dist/testing.js CHANGED
@@ -15,7 +15,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
15
15
  });
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.invokeTrigger = exports.defaultTriggerPayload = exports.invoke = exports.loggerMock = exports.createConnection = void 0;
18
+ exports.createHarness = exports.ComponentTestHarness = exports.invokeTrigger = exports.defaultTriggerPayload = exports.invoke = exports.loggerMock = exports.createConnection = void 0;
19
19
  const jest_mock_1 = require("jest-mock");
20
20
  const createConnection = ({ key }, values) => ({
21
21
  configVarKey: "",
@@ -68,6 +68,7 @@ const defaultTriggerPayload = () => {
68
68
  data: JSON.stringify(payloadData),
69
69
  contentType,
70
70
  },
71
+ pathFragment: "",
71
72
  webhookUrls: {
72
73
  "Flow 1": "https://example.com",
73
74
  },
@@ -105,8 +106,41 @@ const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void
105
106
  };
106
107
  });
107
108
  exports.invokeTrigger = invokeTrigger;
109
+ class ComponentTestHarness {
110
+ constructor(component) {
111
+ this.component = component;
112
+ }
113
+ connectionValue({ key }) {
114
+ const { PRISMATIC_CONNECTION_VALUE: value } = process.env;
115
+ if (!value) {
116
+ throw new Error("Unable to find connection value.");
117
+ }
118
+ const result = Object.assign(Object.assign({}, JSON.parse(value)), { key });
119
+ return result;
120
+ }
121
+ trigger(key, payload, params, context) {
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
124
+ const trigger = this.component.triggers[key];
125
+ return trigger.perform(realizedContext, Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), Object.assign({}, params));
126
+ });
127
+ }
128
+ action(key, params, context) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId" }, context);
131
+ const action = this.component.actions[key];
132
+ return action.perform(realizedContext, Object.assign({}, params));
133
+ });
134
+ }
135
+ }
136
+ exports.ComponentTestHarness = ComponentTestHarness;
137
+ const createHarness = (component) => {
138
+ return new ComponentTestHarness(component);
139
+ };
140
+ exports.createHarness = createHarness;
108
141
  exports.default = {
142
+ loggerMock: exports.loggerMock,
109
143
  invoke: exports.invoke,
110
144
  invokeTrigger: exports.invokeTrigger,
111
- loggerMock: exports.loggerMock,
145
+ createHarness: exports.createHarness,
112
146
  };
@@ -1,14 +1,15 @@
1
- import { InputFieldDefinition, Inputs, InputFieldTypeMap } from ".";
1
+ import { Inputs } from ".";
2
+ import { ConditionalExpression } from "./conditional-logic";
3
+ import { InputFieldCollection, InputCleanFunction, Connection } from "./Inputs";
2
4
  /**
3
5
  * Collection of input parameters.
4
6
  * Inputs can be static values, references to config variables, or
5
7
  * references to previous steps' outputs.
6
8
  */
7
9
  export declare type ActionInputParameters<TInputs extends Inputs> = {
8
- [Property in keyof TInputs]: ExtractValue<TInputs[Property]>;
10
+ [Property in keyof TInputs]: TInputs[Property]["clean"] extends InputCleanFunction<any> ? ReturnType<TInputs[Property]["clean"]> : TInputs[Property]["type"] extends "connection" ? ExtractValue<Connection, TInputs[Property]["collection"]> : TInputs[Property]["type"] extends "conditional" ? ExtractValue<ConditionalExpression, TInputs[Property]["collection"]> : ExtractValue<TInputs[Property]["default"], TInputs[Property]["collection"]>;
9
11
  };
10
- export declare type ExtractValue<TValue extends InputFieldDefinition> = MapCollectionValues<InputFieldTypeMap[TValue["type"]], TValue["collection"]>;
11
- export declare type MapCollectionValues<TType, TCollection extends InputFieldDefinition["collection"]> = TCollection extends "keyvaluelist" ? KeyValuePair<TType>[] : TCollection extends "valuelist" ? TType[] : TType;
12
+ export declare type ExtractValue<TType, TCollection extends InputFieldCollection | undefined> = TCollection extends "keyvaluelist" ? KeyValuePair<TType>[] : TCollection extends "valuelist" ? TType[] : TType;
12
13
  /**
13
14
  * KeyValuePair input parameter type.
14
15
  * This allows users to input multiple keys / values as an input.
@@ -4,13 +4,12 @@ export interface ComponentHooks {
4
4
  /** Defines a global error handler that automatically wraps the component's action/trigger perform functions. */
5
5
  error?: ErrorHandler;
6
6
  }
7
- interface BaseComponentDefinition<TPublic extends boolean = false> {
7
+ /** Defines attributes of a Component. */
8
+ export declare type ComponentDefinition<TPublic extends boolean> = {
8
9
  /** Specifies unique key for this Component. */
9
10
  key: string;
10
11
  /** Specifies if this Component is available for all Organizations or only your own @default false */
11
12
  public?: TPublic;
12
- /** Specified the URL for the Component Documentation. */
13
- documentationUrl?: string;
14
13
  /** Defines how the Component is displayed in the Prismatic interface. */
15
14
  display: ComponentDisplayDefinition<TPublic>;
16
15
  /** Specifies the supported Actions of this Component. */
@@ -21,9 +20,7 @@ interface BaseComponentDefinition<TPublic extends boolean = false> {
21
20
  connections?: ConnectionDefinition[];
22
21
  /** Hooks */
23
22
  hooks?: ComponentHooks;
24
- }
25
- /** Defines attributes of a Component. */
26
- export declare type ComponentDefinition<TPublic extends boolean = false> = BaseComponentDefinition<TPublic> & (TPublic extends true ? {
23
+ } & (TPublic extends true ? {
24
+ /** Specified the URL for the Component Documentation. */
27
25
  documentationUrl: string;
28
26
  } : unknown);
29
- export {};
@@ -1,23 +1,21 @@
1
- import { InputFieldDefaultMap, InputFieldType } from ".";
1
+ import { ConditionalExpression } from "./conditional-logic";
2
+ /** InputField type enumeration. */
3
+ export declare type InputFieldType = InputFieldDefinition["type"];
4
+ export declare const InputFieldDefaultMap: Record<InputFieldType, string | undefined>;
2
5
  export declare type Inputs = Record<string, InputFieldDefinition>;
3
- export declare type ConnectionInput = DefaultInputFieldDefinition & {
6
+ export declare type ConnectionInput = (StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField) & {
4
7
  shown?: boolean;
5
8
  };
6
- export declare type InputFieldDefinition = DefaultInputFieldDefinition | CodeInputFieldDefinition | ConditionalInputField | ConnectionInputField;
7
- interface BaseInputFieldDefinition {
8
- /** Data type the InputField will collect. */
9
- type: InputFieldType;
9
+ export declare type InputFieldDefinition = StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField | CodeInputField | ConditionalInputField | ConnectionInputField;
10
+ export declare type InputCleanFunction<TValue, TResult = TValue> = (value: TValue) => TResult;
11
+ interface BaseInputField {
10
12
  /** Interface label of the InputField. */
11
13
  label: {
12
14
  key: string;
13
15
  value: string;
14
16
  } | string;
15
- /** Collection type of the InputField */
16
- collection?: InputFieldCollection;
17
17
  /** Text to show as the InputField placeholder. */
18
18
  placeholder?: string;
19
- /** Default value for this field. */
20
- default?: typeof InputFieldDefaultMap[this["type"]];
21
19
  /** Additional text to give guidance to the user configuring the InputField. */
22
20
  comments?: string;
23
21
  /** Example valid input for this InputField. */
@@ -25,27 +23,102 @@ interface BaseInputFieldDefinition {
25
23
  /** Indicate if this InputField is required. */
26
24
  required?: boolean;
27
25
  }
28
- /** Defines attributes of a InputField. */
29
- export interface DefaultInputFieldDefinition extends BaseInputFieldDefinition {
30
- type: Exclude<InputFieldType, "code" | "conditional" | "connection">;
26
+ export interface StringInputField extends BaseInputField {
27
+ /** Data type the InputField will collect. */
28
+ type: "string";
29
+ /** Collection type of the InputField */
30
+ collection?: InputFieldCollection;
31
+ /** Default value for this field. */
32
+ default?: unknown;
33
+ /** Dictates possible choices for the input. */
34
+ model?: InputFieldChoice[];
35
+ /** Clean function */
36
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
37
+ }
38
+ export interface DataInputField extends BaseInputField {
39
+ /** Data type the InputField will collect. */
40
+ type: "data";
41
+ /** Collection type of the InputField */
42
+ collection?: InputFieldCollection;
43
+ /** Default value for this field. */
44
+ default?: unknown;
45
+ /** Dictates possible choices for the input. */
46
+ model?: InputFieldChoice[];
47
+ /** Clean function */
48
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
49
+ }
50
+ export interface TextInputField extends BaseInputField {
51
+ /** Data type the InputField will collect. */
52
+ type: "text";
53
+ /** Collection type of the InputField */
54
+ collection?: InputFieldCollection;
55
+ /** Default value for this field. */
56
+ default?: unknown;
31
57
  /** Dictates possible choices for the input. */
32
58
  model?: InputFieldChoice[];
59
+ /** Clean function */
60
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
61
+ }
62
+ export interface PasswordInputField extends BaseInputField {
63
+ /** Data type the InputField will collect. */
64
+ type: "password";
65
+ /** Collection type of the InputField */
66
+ collection?: InputFieldCollection;
67
+ /** Default value for this field. */
68
+ default?: unknown;
69
+ /** Dictates possible choices for the input. */
70
+ model?: InputFieldChoice[];
71
+ /** Clean function */
72
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
73
+ }
74
+ export interface BooleanInputField extends BaseInputField {
75
+ /** Data type the InputField will collect. */
76
+ type: "boolean";
77
+ /** Collection type of the InputField */
78
+ collection?: InputFieldCollection;
79
+ /** Default value for this field. */
80
+ default?: unknown;
81
+ /** Dictates possible choices for the input. */
82
+ model?: InputFieldChoice[];
83
+ /** Clean function */
84
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
33
85
  }
34
86
  /** Defines attributes of a CodeInputField. */
35
- export interface CodeInputFieldDefinition extends BaseInputFieldDefinition {
36
- type: Extract<InputFieldType, "code">;
87
+ export interface CodeInputField extends BaseInputField {
88
+ /** Data type the InputField will collect. */
89
+ type: "code";
90
+ /** Collection type of the InputField */
91
+ collection?: InputFieldCollection;
92
+ /** Default value for this field. */
93
+ default?: unknown;
37
94
  /** Code language of this field. */
38
95
  language?: string;
39
96
  /** Dictates possible choices for the input. */
40
97
  model?: InputFieldChoice[];
98
+ /** Clean function */
99
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
41
100
  }
42
101
  /** Defines attributes of a ConditionalInputField. */
43
- export interface ConditionalInputField extends BaseInputFieldDefinition {
44
- type: Extract<InputFieldType, "conditional">;
102
+ export interface ConditionalInputField extends BaseInputField {
103
+ /** Data type the InputField will collect. */
104
+ type: "conditional";
105
+ /** Collection type of the InputField */
106
+ collection: Extract<InputFieldCollection, "valuelist">;
107
+ /** Default value for this field. */
108
+ default?: ConditionalExpression;
109
+ /** Clean function */
110
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
45
111
  }
46
112
  /** Defines attributes of a ConnectionInputField. */
47
- export interface ConnectionInputField extends BaseInputFieldDefinition {
48
- type: Extract<InputFieldType, "connection">;
113
+ export interface ConnectionInputField extends BaseInputField {
114
+ /** Data type the InputField will collect. */
115
+ type: "connection";
116
+ /** Collection type of the InputField */
117
+ collection?: InputFieldCollection;
118
+ /** Default value for this field. */
119
+ default?: Connection;
120
+ /** Clean function */
121
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
49
122
  }
50
123
  export interface Connection {
51
124
  /** Key of the Connection type. */
@@ -1,2 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InputFieldDefaultMap = void 0;
4
+ exports.InputFieldDefaultMap = {
5
+ string: "",
6
+ data: "",
7
+ text: "",
8
+ password: "",
9
+ boolean: "false",
10
+ code: "",
11
+ conditional: undefined,
12
+ connection: undefined,
13
+ };
@@ -14,6 +14,8 @@ export interface TriggerPayload {
14
14
  data: unknown;
15
15
  contentType?: string;
16
16
  };
17
+ /** Extended path information from the webhook trigger */
18
+ pathFragment: string;
17
19
  /** The webhook URLs assigned to this integration's flows upon instance deploy */
18
20
  webhookUrls: {
19
21
  [key: string]: string;
@@ -12,7 +12,6 @@ export * from "./DisplayDefinition";
12
12
  export * from "./ActionInputParameters";
13
13
  export * from "./ActionLogger";
14
14
  export * from "./ActionPerformFunction";
15
- export * from "./InputFieldType";
16
15
  export * from "./conditional-logic";
17
16
  export * from "./TriggerResult";
18
17
  export * from "./TriggerPerformFunction";
@@ -28,7 +28,6 @@ __exportStar(require("./DisplayDefinition"), exports);
28
28
  __exportStar(require("./ActionInputParameters"), exports);
29
29
  __exportStar(require("./ActionLogger"), exports);
30
30
  __exportStar(require("./ActionPerformFunction"), exports);
31
- __exportStar(require("./InputFieldType"), exports);
32
31
  __exportStar(require("./conditional-logic"), exports);
33
32
  __exportStar(require("./TriggerResult"), exports);
34
33
  __exportStar(require("./TriggerPerformFunction"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismatic-io/spectral",
3
- "version": "6.1.1",
3
+ "version": "6.4.0",
4
4
  "description": "Utility library for building Prismatic components",
5
5
  "keywords": [
6
6
  "prismatic"
@@ -1,15 +0,0 @@
1
- import { Connection } from ".";
2
- import { ConditionalExpression } from "./conditional-logic";
3
- /** InputField type enumeration. */
4
- export declare type InputFieldType = keyof InputFieldTypeMap;
5
- export declare type InputFieldTypeMap = {
6
- string: unknown;
7
- data: unknown;
8
- text: unknown;
9
- password: unknown;
10
- boolean: unknown;
11
- code: unknown;
12
- conditional: ConditionalExpression;
13
- connection: Connection;
14
- };
15
- export declare const InputFieldDefaultMap: Record<InputFieldType, string | undefined>;
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InputFieldDefaultMap = void 0;
4
- exports.InputFieldDefaultMap = {
5
- string: "",
6
- data: "",
7
- text: "",
8
- password: "",
9
- boolean: "false",
10
- code: "",
11
- conditional: undefined,
12
- connection: undefined,
13
- };