@prismatic-io/spectral 6.6.1 → 7.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.
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 } from "./types";
6
+ import { ActionDefinition, InputFieldDefinition, ComponentDefinition, DefaultConnectionDefinition, OAuth2ConnectionDefinition, Inputs, TriggerDefinition, ActionPerformReturn, TriggerResult, DataSourceDefinition } from "./types";
7
7
  import { convertComponent } from "./serverTypes/convert";
8
8
  /**
9
9
  * This function creates a component object that can be
@@ -34,6 +34,32 @@ export declare const action: <TInputs extends Inputs, TAllowsBranching extends b
34
34
  * @returns This function validates the shape of the `definition` object provided, and returns the same trigger object.
35
35
  */
36
36
  export declare const trigger: <TInputs extends Inputs, TAllowsBranching extends boolean, TResult extends TriggerResult<TAllowsBranching>>(definition: TriggerDefinition<TInputs, TAllowsBranching, TResult>) => TriggerDefinition<TInputs, TAllowsBranching, TResult>;
37
+ /**
38
+ * This function creates a data source object that can be referenced
39
+ * by a custom component. It helps ensure that the shape of the
40
+ * data source object conforms to what the Prismatic API expects.
41
+ * For information on writing custom component data sources, see
42
+ * https://prismatic.io/docs/custom-components/writing-custom-components/#writing-data-sources.
43
+ * @param definition A DataSourceDefinition type object that includes UI display information, a function to perform when the data source is invoked, and a an object containing inputs for the perform function.
44
+ * @returns This function validates the shape of the `definition` object provided, and returns the same data source object.
45
+ */
46
+ export declare const dataSource: <TInputs extends Inputs, TDataSourceType extends keyof {
47
+ string: string;
48
+ date: string;
49
+ timestamp: string;
50
+ picklist: string[];
51
+ schedule: {
52
+ value: string;
53
+ };
54
+ code: string;
55
+ credential: unknown;
56
+ boolean: boolean;
57
+ number: number;
58
+ connection: import("./types").ConnectionDefinition;
59
+ objectSelection: import("./types").ObjectSelection;
60
+ objectFieldMap: import("./types").ObjectFieldMap;
61
+ jsonForm: import("./types").JSONForm;
62
+ }>(definition: DataSourceDefinition<TInputs, TDataSourceType>) => DataSourceDefinition<TInputs, TDataSourceType>;
37
63
  /**
38
64
  * For information and examples on how to write inputs
39
65
  * for custom component actions and triggers, see
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.trigger = exports.action = exports.component = void 0;
25
+ exports.testing = exports.util = exports.oauth2Connection = exports.connection = exports.input = exports.dataSource = exports.trigger = exports.action = exports.component = void 0;
26
26
  const convert_1 = require("./serverTypes/convert");
27
27
  /**
28
28
  * This function creates a component object that can be
@@ -56,6 +56,17 @@ exports.action = action;
56
56
  */
57
57
  const trigger = (definition) => definition;
58
58
  exports.trigger = trigger;
59
+ /**
60
+ * This function creates a data source object that can be referenced
61
+ * by a custom component. It helps ensure that the shape of the
62
+ * data source object conforms to what the Prismatic API expects.
63
+ * For information on writing custom component data sources, see
64
+ * https://prismatic.io/docs/custom-components/writing-custom-components/#writing-data-sources.
65
+ * @param definition A DataSourceDefinition type object that includes UI display information, a function to perform when the data source is invoked, and a an object containing inputs for the perform function.
66
+ * @returns This function validates the shape of the `definition` object provided, and returns the same data source object.
67
+ */
68
+ const dataSource = (definition) => definition;
69
+ exports.dataSource = dataSource;
59
70
  /**
60
71
  * For information and examples on how to write inputs
61
72
  * for custom component actions and triggers, see
@@ -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>({ connections, actions, triggers, hooks, ...definition }: ComponentDefinition<TPublic>) => ServerComponent;
3
+ export declare const convertComponent: <TPublic extends boolean>({ connections, actions, triggers, dataSources, hooks, ...definition }: ComponentDefinition<TPublic>) => ServerComponent;
@@ -34,8 +34,18 @@ const convertAction = (actionKey, _a, hooks) => {
34
34
  const convertTrigger = (triggerKey, _a, hooks) => {
35
35
  var { inputs = {}, perform } = _a, trigger = __rest(_a, ["inputs", "perform"]);
36
36
  const convertedInputs = Object.entries(inputs).map(([key, value]) => convertInput(key, value));
37
+ const inputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
37
38
  return Object.assign(Object.assign({}, trigger), { key: triggerKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
38
- inputCleaners: {},
39
+ inputCleaners,
40
+ errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
41
+ }) });
42
+ };
43
+ const convertDataSource = (dataSourceKey, _a, hooks) => {
44
+ var { inputs = {}, perform } = _a, dataSource = __rest(_a, ["inputs", "perform"]);
45
+ const convertedInputs = Object.entries(inputs).map(([key, value]) => convertInput(key, value));
46
+ const inputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
47
+ return Object.assign(Object.assign({}, dataSource), { key: dataSourceKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
48
+ inputCleaners,
39
49
  errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
40
50
  }) });
41
51
  };
@@ -45,9 +55,10 @@ const convertConnection = (_a) => {
45
55
  return Object.assign(Object.assign({}, connection), { inputs: convertedInputs });
46
56
  };
47
57
  const convertComponent = (_a) => {
48
- var { connections = [], actions = {}, triggers = {}, hooks } = _a, definition = __rest(_a, ["connections", "actions", "triggers", "hooks"]);
58
+ var { connections = [], actions = {}, triggers = {}, dataSources = {}, hooks } = _a, definition = __rest(_a, ["connections", "actions", "triggers", "dataSources", "hooks"]);
49
59
  const convertedActions = Object.entries(actions).reduce((result, [actionKey, action]) => (Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, action, hooks) })), {});
50
60
  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 });
61
+ const convertedDataSources = Object.entries(dataSources).reduce((result, [dataSourceKey, dataSource]) => (Object.assign(Object.assign({}, result), { [dataSourceKey]: convertDataSource(dataSourceKey, dataSource, hooks) })), {});
62
+ return Object.assign(Object.assign({}, definition), { connections: connections.map(convertConnection), actions: convertedActions, triggers: convertedTriggers, dataSources: convertedDataSources });
52
63
  };
53
64
  exports.convertComponent = convertComponent;
@@ -1,8 +1,11 @@
1
1
  /// <reference types="node" />
2
+ import { Instance, Customer, DataSourceType, DataSourceResultType } from "../types";
2
3
  interface DisplayDefinition {
3
4
  label: string;
4
5
  description: string;
5
6
  }
7
+ export { Instance } from "../types";
8
+ export { Customer } from "../types";
6
9
  export interface Component {
7
10
  key: string;
8
11
  public?: boolean;
@@ -13,6 +16,7 @@ export interface Component {
13
16
  };
14
17
  actions: Record<string, Action>;
15
18
  triggers: Record<string, Trigger>;
19
+ dataSources: Record<string, DataSource>;
16
20
  connections: Connection[];
17
21
  }
18
22
  export interface Action {
@@ -50,15 +54,8 @@ export interface ActionContext {
50
54
  webhookUrls: Record<string, string>;
51
55
  webhookApiKeys: Record<string, string[]>;
52
56
  invokeUrl: string;
53
- customer: {
54
- id: string | null;
55
- externalId: string | null;
56
- name: string | null;
57
- };
58
- instance: {
59
- id: string | null;
60
- name: string | null;
61
- };
57
+ customer: Customer;
58
+ instance: Instance;
62
59
  }
63
60
  declare type TriggerOptionChoice = "invalid" | "valid" | "required";
64
61
  export interface TriggerPayload {
@@ -77,15 +74,8 @@ export interface TriggerPayload {
77
74
  webhookApiKeys: Record<string, string[]>;
78
75
  invokeUrl: string;
79
76
  executionId: string;
80
- customer: {
81
- id: string | null;
82
- externalId: string | null;
83
- name: string | null;
84
- };
85
- instance: {
86
- id: string | null;
87
- name: string | null;
88
- };
77
+ customer: Customer;
78
+ instance: Instance;
89
79
  }
90
80
  interface HttpResponse {
91
81
  statusCode: number;
@@ -125,6 +115,30 @@ export interface Trigger {
125
115
  examplePayload?: unknown;
126
116
  isCommonTrigger?: boolean;
127
117
  }
118
+ export interface DataSourceContext {
119
+ logger: ActionLogger;
120
+ customer: Customer;
121
+ instance: Instance;
122
+ }
123
+ export declare type DataSourceResult = {
124
+ result: DataSourceResultType;
125
+ supplementalData?: {
126
+ data: unknown;
127
+ contentType: string;
128
+ };
129
+ };
130
+ export declare type DataSourcePerformFunction = (context: DataSourceContext, params: Record<string, unknown>) => Promise<DataSourceResult>;
131
+ export interface DataSource {
132
+ key: string;
133
+ display: DisplayDefinition & {
134
+ directions?: string;
135
+ important?: boolean;
136
+ };
137
+ inputs: Input[];
138
+ perform: DataSourcePerformFunction;
139
+ dataSourceType: DataSourceType;
140
+ examplePayload?: unknown;
141
+ }
128
142
  export declare enum OAuth2Type {
129
143
  ClientCredentials = "client_credentials",
130
144
  AuthorizationCode = "authorization_code"
@@ -194,4 +208,3 @@ export interface Input {
194
208
  model?: InputFieldChoice[];
195
209
  language?: string;
196
210
  }
197
- export {};
@@ -22,6 +22,10 @@ const cleanParams = (params, cleaners) => Object.entries(params).reduce((result,
22
22
  const createPerform = (performFn, { inputCleaners, errorHandler }) => {
23
23
  return (...args) => __awaiter(void 0, void 0, void 0, function* () {
24
24
  try {
25
+ if (args.length === 1) {
26
+ const [params] = args;
27
+ return yield performFn(cleanParams(params, inputCleaners));
28
+ }
25
29
  if (args.length === 2) {
26
30
  const [context, params] = args;
27
31
  return yield performFn(context, cleanParams(params, inputCleaners));
package/dist/testing.d.ts CHANGED
@@ -4,8 +4,8 @@
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
- import { TriggerPayload, TriggerResult, ConnectionValue, ActionLogger, Component, ActionContext, ActionPerformReturn } from "./serverTypes";
8
- import { ConnectionDefinition, ActionDefinition, TriggerDefinition, Inputs, ActionInputParameters, ActionPerformReturn as InvokeActionPerformReturn, TriggerResult as InvokeTriggerResult } from "./types";
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 } from "./types";
9
9
  export declare const createConnection: <T extends ConnectionDefinition>({ key }: T, values: Record<string, unknown>) => ConnectionValue;
10
10
  /**
11
11
  * Pre-built mock of ActionLogger. Suitable for asserting logs are created as expected.
@@ -13,7 +13,7 @@ export declare const createConnection: <T extends ConnectionDefinition>({ key }:
13
13
  */
14
14
  export declare const loggerMock: () => ActionLogger;
15
15
  /**
16
- * The type of data returned by an `invoke()` function used for unit testing component actions.
16
+ * The type of data returned by an `invoke()` function used for unit testing component actions and triggers.
17
17
  */
18
18
  interface InvokeReturn<ReturnData> {
19
19
  result: ReturnData;
@@ -34,12 +34,37 @@ export declare const defaultTriggerPayload: () => TriggerPayload;
34
34
  * trigger result and a mock logger for asserting logging.
35
35
  */
36
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>>;
37
+ /**
38
+ * Invokes specified DataSourceDefinition perform function using supplied params.
39
+ * Accepts a generic type matching DataSourceResult as a convenience to avoid extra
40
+ * casting within test methods. Returns a DataSourceResult.
41
+ */
42
+ export declare const invokeDataSource: <TInputs extends Inputs, TDataSourceType extends keyof {
43
+ string: string;
44
+ date: string;
45
+ timestamp: string;
46
+ picklist: string[];
47
+ schedule: {
48
+ value: string;
49
+ };
50
+ code: string;
51
+ credential: unknown;
52
+ boolean: boolean;
53
+ number: number;
54
+ connection: ConnectionDefinition;
55
+ objectSelection: import("./types").ObjectSelection;
56
+ objectFieldMap: import("./types").ObjectFieldMap;
57
+ jsonForm: import("./types").JSONForm;
58
+ }>({ perform }: DataSourceDefinition<TInputs, TDataSourceType>, params: ActionInputParameters<TInputs>, context?: Partial<DataSourceContext> | undefined) => Promise<InvokeDataSourceResult<TDataSourceType>>;
37
59
  export declare class ComponentTestHarness<TComponent extends Component> {
38
60
  component: TComponent;
39
61
  constructor(component: TComponent);
62
+ private buildContext;
63
+ private buildParams;
40
64
  connectionValue({ key }: ConnectionDefinition): ConnectionValue;
41
65
  trigger(key: string, payload?: TriggerPayload, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<TriggerResult>;
42
66
  action(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<ActionPerformReturn>;
67
+ dataSource(key: string, params?: Record<string, unknown>, context?: Partial<DataSourceContext>): Promise<DataSourceResult>;
43
68
  }
44
69
  export declare const createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
45
70
  declare const _default: {
@@ -47,5 +72,22 @@ declare const _default: {
47
72
  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>>;
48
73
  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>>;
49
74
  createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
75
+ invokeDataSource: <TInputs_2 extends Inputs, TDataSourceType extends keyof {
76
+ string: string;
77
+ date: string;
78
+ timestamp: string;
79
+ picklist: string[];
80
+ schedule: {
81
+ value: string;
82
+ };
83
+ code: string;
84
+ credential: unknown;
85
+ boolean: boolean;
86
+ number: number;
87
+ connection: ConnectionDefinition;
88
+ objectSelection: import("./types").ObjectSelection;
89
+ objectFieldMap: import("./types").ObjectFieldMap;
90
+ jsonForm: import("./types").JSONForm;
91
+ }>({ perform }: DataSourceDefinition<TInputs_2, TDataSourceType>, params: ActionInputParameters<TInputs_2>, context?: Partial<DataSourceContext> | undefined) => Promise<InvokeDataSourceResult<TDataSourceType>>;
50
92
  };
51
93
  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.createHarness = exports.ComponentTestHarness = exports.invokeTrigger = exports.defaultTriggerPayload = exports.invoke = exports.loggerMock = exports.createConnection = void 0;
18
+ exports.createHarness = exports.ComponentTestHarness = exports.invokeDataSource = 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: "",
@@ -37,6 +37,30 @@ const loggerMock = () => ({
37
37
  error: (0, jest_mock_1.spyOn)(console, "error"),
38
38
  });
39
39
  exports.loggerMock = loggerMock;
40
+ const baseActionContext = {
41
+ logger: (0, exports.loggerMock)(),
42
+ instanceState: {},
43
+ crossFlowState: {},
44
+ executionState: {},
45
+ stepId: "mockStepId",
46
+ executionId: "mockExecutionId",
47
+ webhookUrls: {
48
+ "Flow 1": "https://example.com",
49
+ },
50
+ webhookApiKeys: {
51
+ "Flow 1": ["example-123", "example-456"],
52
+ },
53
+ invokeUrl: "https://example.com",
54
+ customer: {
55
+ id: "customerId",
56
+ name: "Customer 1",
57
+ externalId: "1234",
58
+ },
59
+ instance: {
60
+ id: "instanceId",
61
+ name: "Instance 1",
62
+ },
63
+ };
40
64
  /**
41
65
  * Invokes specified ActionDefinition perform function using supplied params
42
66
  * and optional context. Accepts a generic type matching ActionPerformReturn as a convenience
@@ -44,18 +68,7 @@ exports.loggerMock = loggerMock;
44
68
  * action result and a mock logger for asserting logging.
45
69
  */
46
70
  const invoke = ({ perform }, params, context) => __awaiter(void 0, void 0, void 0, function* () {
47
- const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId", webhookUrls: {
48
- "Flow 1": "https://example.com",
49
- }, webhookApiKeys: {
50
- "Flow 1": ["example-123", "example-456"],
51
- }, invokeUrl: "https://example.com", customer: {
52
- id: "customerId",
53
- name: "Customer 1",
54
- externalId: "1234",
55
- }, instance: {
56
- id: "instanceId",
57
- name: "Instance 1",
58
- } }, context);
71
+ const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
59
72
  const result = yield perform(realizedContext, params);
60
73
  return {
61
74
  result,
@@ -107,18 +120,7 @@ exports.defaultTriggerPayload = defaultTriggerPayload;
107
120
  * trigger result and a mock logger for asserting logging.
108
121
  */
109
122
  const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void 0, void 0, void 0, function* () {
110
- const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId", webhookUrls: {
111
- "Flow 1": "https://example.com",
112
- }, webhookApiKeys: {
113
- "Flow 1": ["example-123", "example-456"],
114
- }, invokeUrl: "https://example.com", customer: {
115
- id: "customerId",
116
- name: "Customer 1",
117
- externalId: "1234",
118
- }, instance: {
119
- id: "instanceId",
120
- name: "Instance 1",
121
- } }, context);
123
+ const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
122
124
  const realizedPayload = Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload);
123
125
  const realizedParams = params || {};
124
126
  const result = yield perform(realizedContext, realizedPayload, realizedParams);
@@ -128,10 +130,40 @@ const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void
128
130
  };
129
131
  });
130
132
  exports.invokeTrigger = invokeTrigger;
133
+ const baseDataSourceContext = {
134
+ logger: (0, exports.loggerMock)(),
135
+ customer: {
136
+ id: "customerId",
137
+ name: "Customer 1",
138
+ externalId: "1234",
139
+ },
140
+ instance: {
141
+ id: "instanceId",
142
+ name: "Instance 1",
143
+ },
144
+ };
145
+ /**
146
+ * Invokes specified DataSourceDefinition perform function using supplied params.
147
+ * Accepts a generic type matching DataSourceResult as a convenience to avoid extra
148
+ * casting within test methods. Returns a DataSourceResult.
149
+ */
150
+ const invokeDataSource = ({ perform }, params, context) => __awaiter(void 0, void 0, void 0, function* () {
151
+ const realizedContext = Object.assign(Object.assign({}, baseDataSourceContext), context);
152
+ const result = yield perform(realizedContext, params);
153
+ return result;
154
+ });
155
+ exports.invokeDataSource = invokeDataSource;
131
156
  class ComponentTestHarness {
132
157
  constructor(component) {
133
158
  this.component = component;
134
159
  }
160
+ buildContext(baseContext, context) {
161
+ return Object.assign(Object.assign({}, baseContext), context);
162
+ }
163
+ buildParams(inputs, params) {
164
+ const defaults = inputs.reduce((result, { key, default: defaultValue }) => (Object.assign(Object.assign({}, result), { [key]: `${defaultValue !== null && defaultValue !== void 0 ? defaultValue : ""}` })), {});
165
+ return Object.assign(Object.assign({}, defaults), params);
166
+ }
135
167
  connectionValue({ key }) {
136
168
  const { PRISMATIC_CONNECTION_VALUE: value } = process.env;
137
169
  if (!value) {
@@ -142,38 +174,20 @@ class ComponentTestHarness {
142
174
  }
143
175
  trigger(key, payload, params, context) {
144
176
  return __awaiter(this, void 0, void 0, function* () {
145
- const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId", webhookUrls: {
146
- "Flow 1": "https://example.com",
147
- }, webhookApiKeys: {
148
- "Flow 1": ["example-123", "example-456"],
149
- }, invokeUrl: "https://example.com", customer: {
150
- id: "customerId",
151
- name: "Customer 1",
152
- externalId: "1234",
153
- }, instance: {
154
- id: "instanceId",
155
- name: "Instance 1",
156
- } }, context);
157
177
  const trigger = this.component.triggers[key];
158
- return trigger.perform(realizedContext, Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), Object.assign({}, params));
178
+ return trigger.perform(this.buildContext(baseActionContext, context), Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), this.buildParams(trigger.inputs, params));
159
179
  });
160
180
  }
161
181
  action(key, params, context) {
162
182
  return __awaiter(this, void 0, void 0, function* () {
163
- const realizedContext = Object.assign({ logger: (0, exports.loggerMock)(), instanceState: {}, crossFlowState: {}, executionState: {}, stepId: "mockStepId", executionId: "mockExecutionId", webhookUrls: {
164
- "Flow 1": "https://example.com",
165
- }, webhookApiKeys: {
166
- "Flow 1": ["example-123", "example-456"],
167
- }, invokeUrl: "https://example.com", customer: {
168
- id: "customerId",
169
- name: "Customer 1",
170
- externalId: "1234",
171
- }, instance: {
172
- id: "instanceId",
173
- name: "Instance 1",
174
- } }, context);
175
183
  const action = this.component.actions[key];
176
- return action.perform(realizedContext, Object.assign({}, params));
184
+ return action.perform(this.buildContext(baseActionContext, context), this.buildParams(action.inputs, params));
185
+ });
186
+ }
187
+ dataSource(key, params, context) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ const dataSource = this.component.dataSources[key];
190
+ return dataSource.perform(this.buildContext(baseDataSourceContext, context), this.buildParams(dataSource.inputs, params));
177
191
  });
178
192
  }
179
193
  }
@@ -187,4 +201,5 @@ exports.default = {
187
201
  invoke: exports.invoke,
188
202
  invokeTrigger: exports.invokeTrigger,
189
203
  createHarness: exports.createHarness,
204
+ invokeDataSource: exports.invokeDataSource,
190
205
  };
@@ -1,4 +1,4 @@
1
- import { Inputs, ActionPerformReturn, ActionInputParameters, ActionLogger } from ".";
1
+ import { Inputs, ActionPerformReturn, ActionInputParameters, ActionLogger, Instance, Customer } from ".";
2
2
  /** Definition of the function to perform when an Action is invoked. */
3
3
  export declare type ActionPerformFunction<TInputs extends Inputs, TAllowsBranching extends boolean | undefined, TReturn extends ActionPerformReturn<TAllowsBranching, unknown>> = (context: ActionContext, params: ActionInputParameters<TInputs>) => Promise<TReturn>;
4
4
  /** Context provided to perform method containing helpers and contextual data */
@@ -21,15 +21,8 @@ export interface ActionContext {
21
21
  webhookApiKeys: Record<string, string[]>;
22
22
  /** The URL used to invoke the current execution */
23
23
  invokeUrl: string;
24
- /** An object containing the ID, External ID and name of the customer the instance is deployed to */
25
- customer: {
26
- id: string | null;
27
- externalId: string | null;
28
- name: string | null;
29
- };
30
- /** An object containing the ID ad name of the currently running instance */
31
- instance: {
32
- id: string | null;
33
- name: string | null;
34
- };
24
+ /** Contains attributes of the Customer for whom an Instance is being executed. */
25
+ customer: Customer;
26
+ /** Contains attributes of the Instance that is being executed. */
27
+ instance: Instance;
35
28
  }
@@ -12,7 +12,7 @@ export interface ActionPerformDataReturn<ReturnData> {
12
12
  crossFlowState?: Record<string, unknown>;
13
13
  /** An optional object, the keys and values of which will be persisted in the executionState and available for the duration of the execution */
14
14
  executionState?: Record<string, unknown>;
15
- /** A field populated by the Prismatic platform which indicates whether the trigger failed with an error during execution. */
15
+ /** A field populated by the Prismatic platform which indicates whether the action failed with an error during execution. */
16
16
  failed?: boolean;
17
17
  /** A field populated by the Prismatic platform which may refer to an object that contains data about any error that resulted in failure. */
18
18
  error?: Record<string, unknown>;
@@ -1,4 +1,4 @@
1
- import { ActionDefinition, ConnectionDefinition, ComponentDisplayDefinition, TriggerDefinition } from ".";
1
+ import { ActionDefinition, ConnectionDefinition, ComponentDisplayDefinition, TriggerDefinition, DataSourceDefinition } from ".";
2
2
  export declare type ErrorHandler = (error: unknown) => unknown;
3
3
  export interface ComponentHooks {
4
4
  /** Defines a global error handler that automatically wraps the component's action/trigger perform functions. */
@@ -16,6 +16,8 @@ export declare type ComponentDefinition<TPublic extends boolean> = {
16
16
  actions?: Record<string, ActionDefinition<any, boolean, any>>;
17
17
  /** Specifies the supported Triggers of this Component. */
18
18
  triggers?: Record<string, TriggerDefinition<any, boolean, any>>;
19
+ /** Specifies the supported Data Sources of this Component. */
20
+ dataSources?: Record<string, DataSourceDefinition<any, any>>;
19
21
  /** Specifies the supported Connections of this Component. */
20
22
  connections?: ConnectionDefinition[];
21
23
  /** Hooks */
@@ -0,0 +1,6 @@
1
+ /** Contains attributes of the Customer for whom an Instance is being executed. */
2
+ export interface Customer {
3
+ id: string;
4
+ externalId: string;
5
+ name: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,19 @@
1
+ import { ActionDisplayDefinition, DataSourcePerformFunction, Inputs, DataSourceType } from ".";
2
+ /**
3
+ * DataSourceDefinition is the type of the object that is passed in to `dataSource` function to
4
+ * define a component Data Source.
5
+ */
6
+ export interface DataSourceDefinition<TInputs extends Inputs, TDataSourceType extends DataSourceType> {
7
+ /** Defines how the Data Source is displayed in the Prismatic interface. */
8
+ display: ActionDisplayDefinition;
9
+ /** Function to perform when this Data Source is invoked; fetches data from the data source. */
10
+ perform: DataSourcePerformFunction<TInputs, TDataSourceType>;
11
+ /** The type of data that this Data Source represents. */
12
+ dataSourceType: TDataSourceType;
13
+ /** InputFields to present in the Prismatic interface for configuration of this Data Source. */
14
+ inputs: TInputs;
15
+ /** An example of the payload outputted by this Data Source. */
16
+ examplePayload?: Awaited<ReturnType<this["perform"]>>;
17
+ /** Specifies the name of a Data Source in this Component which can provide additional details about the content for this Data Source, such as example values when selecting particular API object fields. */
18
+ detailDataSource?: string;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { Inputs, DataSourceResult, DataSourceType, ActionInputParameters, ActionLogger, Customer, Instance } from ".";
2
+ /** Context provided to perform method containing helpers and contextual data */
3
+ export interface DataSourceContext {
4
+ logger: ActionLogger;
5
+ customer: Customer;
6
+ instance: Instance;
7
+ }
8
+ /** Definition of the function to perform when a Data Source is invoked. */
9
+ export declare type DataSourcePerformFunction<TInputs extends Inputs, TDataSourceType extends DataSourceType> = (context: DataSourceContext, params: ActionInputParameters<TInputs>) => Promise<DataSourceResult<TDataSourceType>>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,35 @@
1
+ import { ConnectionDefinition } from "./ConnectionDefinition";
2
+ import { ObjectSelection, ObjectFieldMap, JSONForm } from "./Inputs";
3
+ /** The type of field that is appropriate for rendering the data that is the result of the data source perform function. */
4
+ declare type DataSourceTypeMap = {
5
+ string: string;
6
+ date: string;
7
+ timestamp: string;
8
+ picklist: string[];
9
+ schedule: {
10
+ value: string;
11
+ };
12
+ code: string;
13
+ credential: unknown;
14
+ boolean: boolean;
15
+ number: number;
16
+ connection: ConnectionDefinition;
17
+ objectSelection: ObjectSelection;
18
+ objectFieldMap: ObjectFieldMap;
19
+ jsonForm: JSONForm;
20
+ };
21
+ export declare type DataSourceType = keyof DataSourceTypeMap;
22
+ export declare type DataSourceResultType = DataSourceTypeMap[DataSourceType];
23
+ /** Represents the result of a Data Source action. */
24
+ export declare type DataSourceResult<TDataSourceType extends DataSourceType> = {
25
+ /** The resulting data that is returned from the data source. */
26
+ result: DataSourceTypeMap[TDataSourceType];
27
+ /** Additional data that may be useful for out-of-band processing at a later time.
28
+ * NOTE: This is only available when the Data Source is called as part of fetching
29
+ * contents for a Configuration Wizard Page. */
30
+ supplementalData?: {
31
+ data: unknown;
32
+ contentType: string;
33
+ };
34
+ };
35
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,33 @@
1
1
  import { ConditionalExpression } from "./conditional-logic";
2
+ export declare type Element = {
3
+ key: string;
4
+ label?: string;
5
+ };
6
+ export declare type ObjectSelection = {
7
+ object: Element;
8
+ fields?: Element[];
9
+ defaultSelected?: boolean;
10
+ }[];
11
+ export declare type ObjectFieldMap = {
12
+ fields: {
13
+ field: Element;
14
+ mappedObject?: Element;
15
+ mappedField?: Element;
16
+ defaultObject?: Element;
17
+ defaultField?: Element;
18
+ }[];
19
+ options?: {
20
+ object: Element;
21
+ fields: Element[];
22
+ }[];
23
+ };
24
+ export declare type JSONForm = {
25
+ schema: Record<string, unknown>;
26
+ uiSchema: Record<string, unknown>;
27
+ data: unknown;
28
+ };
29
+ export declare type DynamicObjectSelection = string;
30
+ export declare type DynamicFieldSelection = string;
2
31
  /** InputField type enumeration. */
3
32
  export declare type InputFieldType = InputFieldDefinition["type"];
4
33
  export declare const InputFieldDefaultMap: Record<InputFieldType, string | undefined>;
@@ -6,7 +35,7 @@ export declare type Inputs = Record<string, InputFieldDefinition>;
6
35
  export declare type ConnectionInput = (StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField) & {
7
36
  shown?: boolean;
8
37
  };
9
- export declare type InputFieldDefinition = StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField | CodeInputField | ConditionalInputField | ConnectionInputField;
38
+ export declare type InputFieldDefinition = StringInputField | DataInputField | TextInputField | PasswordInputField | BooleanInputField | CodeInputField | ConditionalInputField | ConnectionInputField | ObjectSelectionInputField | ObjectFieldMapInputField | JSONFormInputField | DynamicObjectSelectionInputField | DynamicFieldSelectionInputField;
10
39
  export declare type InputCleanFunction<TValue, TResult = TValue> = (value: TValue) => TResult;
11
40
  interface BaseInputField {
12
41
  /** Interface label of the InputField. */
@@ -132,6 +161,61 @@ export interface Connection {
132
161
  token?: Record<string, unknown>;
133
162
  context?: Record<string, unknown>;
134
163
  }
164
+ /** Defines attributes of an ObjectSelectionInputField. */
165
+ export interface ObjectSelectionInputField extends BaseInputField {
166
+ /** Data type the InputField will collect. */
167
+ type: "objectSelection";
168
+ /** Collection type of the InputField */
169
+ collection?: InputFieldCollection;
170
+ /** Default value for this field. */
171
+ default?: ObjectSelection;
172
+ /** Clean function */
173
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
174
+ }
175
+ /** Defines attributes of an ObjectFieldMapInputField. */
176
+ export interface ObjectFieldMapInputField extends BaseInputField {
177
+ /** Data type the InputField will collect. */
178
+ type: "objectFieldMap";
179
+ /** Collection type of the InputField */
180
+ collection?: InputFieldCollection;
181
+ /** Default value for this field. */
182
+ default?: ObjectFieldMap;
183
+ /** Clean function */
184
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
185
+ }
186
+ /** Defines attributes of a JSONFormInputField. */
187
+ export interface JSONFormInputField extends BaseInputField {
188
+ /** Data type the InputField will collect. */
189
+ type: "jsonForm";
190
+ /** Collection type of the InputField */
191
+ collection?: InputFieldCollection;
192
+ /** Default value for this field. */
193
+ default?: JSONForm;
194
+ /** Clean function */
195
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
196
+ }
197
+ /** Defines attributes of a DynamicObjectSelectionInputField */
198
+ export interface DynamicObjectSelectionInputField extends BaseInputField {
199
+ /** Data type the InputField will collect. */
200
+ type: "dynamicObjectSelection";
201
+ /** Collection type of the InputField */
202
+ collection?: InputFieldCollection;
203
+ /** Default value for this field. */
204
+ default?: unknown;
205
+ /** Clean function */
206
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
207
+ }
208
+ /** Defines attributes of a SelectedFieldInputField */
209
+ export interface DynamicFieldSelectionInputField extends BaseInputField {
210
+ /** Data type the InputField will collect. */
211
+ type: "dynamicFieldSelection";
212
+ /** Collection type of the InputField */
213
+ collection?: InputFieldCollection;
214
+ /** Default value for this field. */
215
+ default?: unknown;
216
+ /** Clean function */
217
+ clean?: InputCleanFunction<NonNullable<this["default"]>>;
218
+ }
135
219
  /** Defines a single Choice option for a InputField. */
136
220
  export interface InputFieldChoice {
137
221
  /** Label to display for this Choice. */
@@ -10,4 +10,9 @@ exports.InputFieldDefaultMap = {
10
10
  code: "",
11
11
  conditional: undefined,
12
12
  connection: undefined,
13
+ objectSelection: undefined,
14
+ objectFieldMap: undefined,
15
+ jsonForm: undefined,
16
+ dynamicObjectSelection: "",
17
+ dynamicFieldSelection: "",
13
18
  };
@@ -0,0 +1,5 @@
1
+ /** Contains attributes of the Instance that is being executed. */
2
+ export interface Instance {
3
+ id: string;
4
+ name: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
+ import { Instance, Customer } from ".";
1
2
  /** Represents a Trigger Payload, which is data passed into a Trigger to invoke an Integration execution. */
2
3
  export interface TriggerPayload {
3
4
  headers: {
@@ -27,13 +28,8 @@ export interface TriggerPayload {
27
28
  /** The URL that was used to invoke the execution. */
28
29
  invokeUrl: string;
29
30
  executionId: string;
30
- customer: {
31
- id: string | null;
32
- externalId: string | null;
33
- name: string | null;
34
- };
35
- instance: {
36
- id: string | null;
37
- name: string | null;
38
- };
31
+ /** Contains attributes of the Customer for whom an Instance is being executed. */
32
+ customer: Customer;
33
+ /** Contains attributes of the Instance that is being executed. */
34
+ instance: Instance;
39
35
  }
@@ -18,3 +18,9 @@ export * from "./TriggerPerformFunction";
18
18
  export * from "./TriggerDefinition";
19
19
  export * from "./HttpResponse";
20
20
  export * from "./TriggerPayload";
21
+ export * from "./DataSourceDefinition";
22
+ export * from "./DataSourcePerformFunction";
23
+ export * from "./DataSourceResult";
24
+ export * from "./Instance";
25
+ export * from "./Customer";
26
+ export * as serverTypes from "../serverTypes";
@@ -14,10 +14,23 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
14
14
  if (k2 === undefined) k2 = k;
15
15
  o[k2] = m[k];
16
16
  }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
17
22
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
23
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
24
  };
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
20
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.serverTypes = void 0;
21
34
  __exportStar(require("./ActionDefinition"), exports);
22
35
  __exportStar(require("./ComponentDefinition"), exports);
23
36
  __exportStar(require("./ConnectionDefinition"), exports);
@@ -34,3 +47,9 @@ __exportStar(require("./TriggerPerformFunction"), exports);
34
47
  __exportStar(require("./TriggerDefinition"), exports);
35
48
  __exportStar(require("./HttpResponse"), exports);
36
49
  __exportStar(require("./TriggerPayload"), exports);
50
+ __exportStar(require("./DataSourceDefinition"), exports);
51
+ __exportStar(require("./DataSourcePerformFunction"), exports);
52
+ __exportStar(require("./DataSourceResult"), exports);
53
+ __exportStar(require("./Instance"), exports);
54
+ __exportStar(require("./Customer"), exports);
55
+ exports.serverTypes = __importStar(require("../serverTypes"));
package/dist/util.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Many functions in the `util` module are used to coerce data into a particular type, and can be accessed through `util.types`.
4
4
  * For example, `util.types.toInt("5.5")` will return an integer, `5`.
5
5
  */
6
- import { KeyValuePair, DataPayload } from "./types";
6
+ import { KeyValuePair, DataPayload, ObjectSelection, ObjectFieldMap, JSONForm, ConnectionDefinition } from "./types";
7
7
  /**
8
8
  * This function returns a lower cased version of the headers passed to it.
9
9
  *
@@ -31,11 +31,21 @@ declare const _default: {
31
31
  toBufferDataPayload: (value: unknown) => DataPayload;
32
32
  isData: (value: unknown) => boolean;
33
33
  toData: (value: unknown) => DataPayload;
34
+ isString: (value: unknown) => value is string;
34
35
  toString: (value: unknown, defaultValue?: string) => string;
35
36
  keyValPairListToObject: <TValue = unknown>(kvpList: KeyValuePair<unknown>[], valueConverter?: ((value: unknown) => TValue) | undefined) => Record<string, TValue>;
36
37
  isJSON: (value: string) => boolean;
37
38
  toJSON: (value: unknown) => string;
38
39
  lowerCaseHeaders: (headers: Record<string, string>) => Record<string, string>;
40
+ isObjectSelection: (value: unknown) => value is ObjectSelection;
41
+ toObjectSelection: (value: unknown) => ObjectSelection;
42
+ isObjectFieldMap: (value: unknown) => value is ObjectFieldMap;
43
+ toObjectFieldMap: (value: unknown) => ObjectFieldMap;
44
+ isJSONForm: (value: unknown) => value is JSONForm;
45
+ toJSONForm: (value: unknown) => JSONForm;
46
+ isPicklist: (value: unknown) => boolean;
47
+ isSchedule: (value: unknown) => boolean;
48
+ isConnection: (value: unknown) => value is ConnectionDefinition;
39
49
  };
40
50
  docs: {
41
51
  formatJsonExample: (input: unknown) => string;
package/dist/util.js CHANGED
@@ -15,6 +15,92 @@ const isValid_1 = __importDefault(require("date-fns/isValid"));
15
15
  const isDate_1 = __importDefault(require("date-fns/isDate"));
16
16
  const safe_stable_stringify_1 = require("safe-stable-stringify");
17
17
  const valid_url_1 = require("valid-url");
18
+ const isObjectWithTruthyKeys = (value, keys) => {
19
+ return (value !== null &&
20
+ typeof value === "object" &&
21
+ keys.every((key) => key in value && Boolean(value === null || value === void 0 ? void 0 : value[key])));
22
+ };
23
+ /**
24
+ * @param value The value to test
25
+ * @returns This function returns true if the type of `value` is an ObjectSelection, or false otherwise.
26
+ */
27
+ const isObjectSelection = (value) => {
28
+ if (typeof value === "string" && isJSON(value)) {
29
+ return isObjectSelection(JSON.parse(value));
30
+ }
31
+ return (Array.isArray(value) &&
32
+ value.every((item) => isObjectWithTruthyKeys(item, ["object"])));
33
+ };
34
+ /**
35
+ * This function coerces a provided value into an ObjectSelection if possible.
36
+ * @param value The value to coerce to ObjectSelection.
37
+ * @returns This function returns the the value as an ObjectSelection if possible.
38
+ */
39
+ const toObjectSelection = (value) => {
40
+ if (typeof value === "string" && isJSON(value)) {
41
+ return toObjectSelection(JSON.parse(value));
42
+ }
43
+ if (isObjectSelection(value)) {
44
+ return value;
45
+ }
46
+ throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to ObjectSelection.`);
47
+ };
48
+ /**
49
+ * @param value The value to test
50
+ * @returns This function returns true if the type of `value` is an ObjectFieldMap, or false otherwise.
51
+ */
52
+ const isObjectFieldMap = (value) => {
53
+ if (typeof value === "string" && isJSON(value)) {
54
+ return isObjectFieldMap(JSON.parse(value));
55
+ }
56
+ if (Boolean(value) && typeof value === "object") {
57
+ const { fields } = value;
58
+ return (Array.isArray(fields) &&
59
+ fields.every((item) => isObjectWithTruthyKeys(item, ["field"]) &&
60
+ isObjectWithTruthyKeys(item === null || item === void 0 ? void 0 : item.field, [
61
+ "key",
62
+ ])));
63
+ }
64
+ return false;
65
+ };
66
+ /**
67
+ * This function coerces a provided value into an ObjectFieldMap if possible.
68
+ * @param value The value to coerce to ObjectFieldMap.
69
+ * @returns This function returns the the value as an ObjectFieldMap if possible.
70
+ */
71
+ const toObjectFieldMap = (value) => {
72
+ if (typeof value === "string" && isJSON(value)) {
73
+ return toObjectFieldMap(JSON.parse(value));
74
+ }
75
+ if (isObjectFieldMap(value)) {
76
+ return value;
77
+ }
78
+ throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to ObjectFieldMap.`);
79
+ };
80
+ /**
81
+ * @param value The value to test
82
+ * @returns This function returns true if the type of `value` is a JSONForm, or false otherwise.
83
+ */
84
+ const isJSONForm = (value) => {
85
+ if (typeof value === "string" && isJSON(value)) {
86
+ return isJSONForm(JSON.parse(value));
87
+ }
88
+ return isObjectWithTruthyKeys(value, ["schema", "uiSchema", "data"]);
89
+ };
90
+ /**
91
+ * This function coerces a provided value into a JSONForm if possible.
92
+ * @param value The value to coerce to JSONForm.
93
+ * @returns This function returns the the value as a JSONForm if possible.
94
+ */
95
+ const toJSONForm = (value) => {
96
+ if (typeof value === "string" && isJSON(value)) {
97
+ return toJSONForm(JSON.parse(value));
98
+ }
99
+ if (isJSONForm(value)) {
100
+ return value;
101
+ }
102
+ throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to JSONForm.`);
103
+ };
18
104
  /**
19
105
  * Determine if a variable is a boolean (true or false).
20
106
  *
@@ -187,6 +273,25 @@ const toDate = (value) => {
187
273
  * @returns This function returns true if `value` is a valid URL, and false otherwise.
188
274
  */
189
275
  const isUrl = (value) => (0, valid_url_1.isWebUri)(value) !== undefined;
276
+ /**
277
+ * This function checks if value is a valid picklist.
278
+ *
279
+ * - `util.types.isPicklist(["value", new String("value")])` will return `true`.
280
+ *
281
+ * @param value The variable to test.
282
+ * @returns This function returns true if `value` is a valid picklist.
283
+ */
284
+ const isPicklist = (value) => Array.isArray(value) && value.every(isString);
285
+ /**
286
+ * This function checks if value is a valid schedule.
287
+ *
288
+ * - `util.types.isSchedule({value: "00 00 * * 2,3"})` will return `true`.
289
+ * - `util.types.isSchedule({value: "00 00 * * 2,3", scheduleType: "week", timeZone: "America/Chicago"})` will return `true`.
290
+ *
291
+ * @param value The variable to test.
292
+ * @returns This function returns true if `value` is a valid schedule.
293
+ */
294
+ const isSchedule = (value) => isObjectWithTruthyKeys(value, ["value"]);
190
295
  /**
191
296
  * This function helps to transform key-value lists to objects.
192
297
  * This is useful for transforming inputs that are key-value collections into objects.
@@ -280,6 +385,13 @@ const toData = (value) => toBufferDataPayload(value);
280
385
  * @returns This function returns a code block that can be used for documentation.
281
386
  */
282
387
  const formatJsonExample = (input) => ["```json", JSON.stringify(input, undefined, 2), "```"].join("\n");
388
+ /**
389
+ * This function checks if value is a string.
390
+ * `util.types.isString("value")` and `util.types.isString(new String("value"))` return true.
391
+ * @param value The variable to test.
392
+ * @returns This function returns true or false, depending on if `value` is a string.
393
+ */
394
+ const isString = (value) => typeof value === "string" || value instanceof String;
283
395
  /**
284
396
  * This function converts a `value` to a string.
285
397
  * If `value` is undefined or an empty string, an optional `defaultValue` can be returned.
@@ -293,6 +405,31 @@ const formatJsonExample = (input) => ["```json", JSON.stringify(input, undefined
293
405
  * @returns This function returns the stringified version fo `value`, or `defaultValue` in the case that `value` is undefined or an empty string.
294
406
  */
295
407
  const toString = (value, defaultValue = "") => `${value !== null && value !== void 0 ? value : defaultValue}`;
408
+ /**
409
+ * This function checks if value is a valid connection.
410
+ * @param value The variable to test.
411
+ * @returns This function returns true or false, depending on if `value` is a valid connection.
412
+ */
413
+ const isConnection = (value) => {
414
+ if (typeof value === "string" && isJSON(value)) {
415
+ return isConnection(JSON.parse(value));
416
+ }
417
+ if (Boolean(value) && typeof value === "object") {
418
+ const { inputs } = value;
419
+ if (isObjectWithTruthyKeys(value, ["key", "label", "oauth2Type"])) {
420
+ return (isObjectWithTruthyKeys(inputs, [
421
+ "authorizeUrl",
422
+ "tokenUrl",
423
+ "clientId",
424
+ "clientSecret",
425
+ ]) ||
426
+ isObjectWithTruthyKeys(inputs, ["tokenUrl", "clientId", "clientSecret"]));
427
+ }
428
+ return (isObjectWithTruthyKeys(value, ["key", "label"]) &&
429
+ typeof inputs === "object");
430
+ }
431
+ return false;
432
+ };
296
433
  /**
297
434
  * This function returns true if `value` resembles the shape of JSON, and false otherwise.
298
435
  *
@@ -352,11 +489,21 @@ exports.default = {
352
489
  toBufferDataPayload,
353
490
  isData,
354
491
  toData,
492
+ isString,
355
493
  toString,
356
494
  keyValPairListToObject,
357
495
  isJSON,
358
496
  toJSON,
359
497
  lowerCaseHeaders: exports.lowerCaseHeaders,
498
+ isObjectSelection,
499
+ toObjectSelection,
500
+ isObjectFieldMap,
501
+ toObjectFieldMap,
502
+ isJSONForm,
503
+ toJSONForm,
504
+ isPicklist,
505
+ isSchedule,
506
+ isConnection,
360
507
  },
361
508
  docs: {
362
509
  formatJsonExample,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismatic-io/spectral",
3
- "version": "6.6.1",
3
+ "version": "7.0.0",
4
4
  "description": "Utility library for building Prismatic components",
5
5
  "keywords": [
6
6
  "prismatic"