@prismatic-io/spectral 7.0.11-pre → 7.0.14-pre
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.
|
@@ -34,16 +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,
|
|
39
40
|
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
|
|
40
41
|
}) });
|
|
41
42
|
};
|
|
42
43
|
const convertDataSource = (dataSourceKey, _a, hooks) => {
|
|
43
44
|
var { inputs = {}, perform } = _a, dataSource = __rest(_a, ["inputs", "perform"]);
|
|
44
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 })), {});
|
|
45
47
|
return Object.assign(Object.assign({}, dataSource), { key: dataSourceKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
|
|
46
|
-
inputCleaners
|
|
48
|
+
inputCleaners,
|
|
47
49
|
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
|
|
48
50
|
}) });
|
|
49
51
|
};
|
|
@@ -115,6 +115,11 @@ export interface Trigger {
|
|
|
115
115
|
examplePayload?: unknown;
|
|
116
116
|
isCommonTrigger?: boolean;
|
|
117
117
|
}
|
|
118
|
+
export interface DataSourceContext {
|
|
119
|
+
logger: ActionLogger;
|
|
120
|
+
customer: Customer;
|
|
121
|
+
instance: Instance;
|
|
122
|
+
}
|
|
118
123
|
export declare type DataSourceResult = {
|
|
119
124
|
result: DataSourceResultType;
|
|
120
125
|
supplementalData?: {
|
|
@@ -122,7 +127,7 @@ export declare type DataSourceResult = {
|
|
|
122
127
|
contentType: string;
|
|
123
128
|
};
|
|
124
129
|
};
|
|
125
|
-
export declare type DataSourcePerformFunction = (params: Record<string, unknown>) => Promise<DataSourceResult>;
|
|
130
|
+
export declare type DataSourcePerformFunction = (context: DataSourceContext, params: Record<string, unknown>) => Promise<DataSourceResult>;
|
|
126
131
|
export interface DataSource {
|
|
127
132
|
key: string;
|
|
128
133
|
display: DisplayDefinition & {
|
package/dist/testing.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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, DataSourceResult } from "./serverTypes";
|
|
7
|
+
import { TriggerPayload, TriggerResult, ConnectionValue, ActionLogger, Component, ActionContext, ActionPerformReturn, DataSourceResult, DataSourceContext } from "./serverTypes";
|
|
8
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
|
/**
|
|
@@ -55,14 +55,16 @@ export declare const invokeDataSource: <TInputs extends Inputs, TDataSourceType
|
|
|
55
55
|
objectSelection: import("./types").ObjectSelection;
|
|
56
56
|
objectFieldMap: import("./types").ObjectFieldMap;
|
|
57
57
|
jsonForm: import("./types").JSONForm;
|
|
58
|
-
}>({ perform }: DataSourceDefinition<TInputs, TDataSourceType>, params: ActionInputParameters<TInputs>) => Promise<InvokeDataSourceResult<TDataSourceType>>;
|
|
58
|
+
}>({ perform }: DataSourceDefinition<TInputs, TDataSourceType>, params: ActionInputParameters<TInputs>, context?: Partial<DataSourceContext> | undefined) => Promise<InvokeDataSourceResult<TDataSourceType>>;
|
|
59
59
|
export declare class ComponentTestHarness<TComponent extends Component> {
|
|
60
60
|
component: TComponent;
|
|
61
61
|
constructor(component: TComponent);
|
|
62
|
+
private buildContext;
|
|
63
|
+
private buildParams;
|
|
62
64
|
connectionValue({ key }: ConnectionDefinition): ConnectionValue;
|
|
63
65
|
trigger(key: string, payload?: TriggerPayload, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<TriggerResult>;
|
|
64
66
|
action(key: string, params?: Record<string, unknown>, context?: Partial<ActionContext>): Promise<ActionPerformReturn>;
|
|
65
|
-
dataSource(key: string, params?: Record<string, unknown>): Promise<DataSourceResult>;
|
|
67
|
+
dataSource(key: string, params?: Record<string, unknown>, context?: Partial<DataSourceContext>): Promise<DataSourceResult>;
|
|
66
68
|
}
|
|
67
69
|
export declare const createHarness: <TComponent extends Component>(component: TComponent) => ComponentTestHarness<TComponent>;
|
|
68
70
|
declare const _default: {
|
|
@@ -86,6 +88,6 @@ declare const _default: {
|
|
|
86
88
|
objectSelection: import("./types").ObjectSelection;
|
|
87
89
|
objectFieldMap: import("./types").ObjectFieldMap;
|
|
88
90
|
jsonForm: import("./types").JSONForm;
|
|
89
|
-
}>({ perform }: DataSourceDefinition<TInputs_2, TDataSourceType>, params: ActionInputParameters<TInputs_2>) => Promise<InvokeDataSourceResult<TDataSourceType>>;
|
|
91
|
+
}>({ perform }: DataSourceDefinition<TInputs_2, TDataSourceType>, params: ActionInputParameters<TInputs_2>, context?: Partial<DataSourceContext> | undefined) => Promise<InvokeDataSourceResult<TDataSourceType>>;
|
|
90
92
|
};
|
|
91
93
|
export default _default;
|
package/dist/testing.js
CHANGED
|
@@ -37,7 +37,7 @@ const loggerMock = () => ({
|
|
|
37
37
|
error: (0, jest_mock_1.spyOn)(console, "error"),
|
|
38
38
|
});
|
|
39
39
|
exports.loggerMock = loggerMock;
|
|
40
|
-
const
|
|
40
|
+
const baseActionContext = {
|
|
41
41
|
logger: (0, exports.loggerMock)(),
|
|
42
42
|
instanceState: {},
|
|
43
43
|
crossFlowState: {},
|
|
@@ -68,7 +68,7 @@ const baseContext = {
|
|
|
68
68
|
* action result and a mock logger for asserting logging.
|
|
69
69
|
*/
|
|
70
70
|
const invoke = ({ perform }, params, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
-
const realizedContext = Object.assign(Object.assign({},
|
|
71
|
+
const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
|
|
72
72
|
const result = yield perform(realizedContext, params);
|
|
73
73
|
return {
|
|
74
74
|
result,
|
|
@@ -120,7 +120,7 @@ exports.defaultTriggerPayload = defaultTriggerPayload;
|
|
|
120
120
|
* trigger result and a mock logger for asserting logging.
|
|
121
121
|
*/
|
|
122
122
|
const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
123
|
-
const realizedContext = Object.assign(Object.assign({},
|
|
123
|
+
const realizedContext = Object.assign(Object.assign({}, baseActionContext), context);
|
|
124
124
|
const realizedPayload = Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload);
|
|
125
125
|
const realizedParams = params || {};
|
|
126
126
|
const result = yield perform(realizedContext, realizedPayload, realizedParams);
|
|
@@ -130,13 +130,26 @@ const invokeTrigger = ({ perform }, context, payload, params) => __awaiter(void
|
|
|
130
130
|
};
|
|
131
131
|
});
|
|
132
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
|
+
};
|
|
133
145
|
/**
|
|
134
146
|
* Invokes specified DataSourceDefinition perform function using supplied params.
|
|
135
147
|
* Accepts a generic type matching DataSourceResult as a convenience to avoid extra
|
|
136
148
|
* casting within test methods. Returns a DataSourceResult.
|
|
137
149
|
*/
|
|
138
|
-
const invokeDataSource = ({ perform }, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
139
|
-
const
|
|
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);
|
|
140
153
|
return result;
|
|
141
154
|
});
|
|
142
155
|
exports.invokeDataSource = invokeDataSource;
|
|
@@ -144,6 +157,13 @@ class ComponentTestHarness {
|
|
|
144
157
|
constructor(component) {
|
|
145
158
|
this.component = component;
|
|
146
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
|
+
}
|
|
147
167
|
connectionValue({ key }) {
|
|
148
168
|
const { PRISMATIC_CONNECTION_VALUE: value } = process.env;
|
|
149
169
|
if (!value) {
|
|
@@ -154,22 +174,20 @@ class ComponentTestHarness {
|
|
|
154
174
|
}
|
|
155
175
|
trigger(key, payload, params, context) {
|
|
156
176
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
const realizedContext = Object.assign(Object.assign({}, baseContext), context);
|
|
158
177
|
const trigger = this.component.triggers[key];
|
|
159
|
-
return trigger.perform(
|
|
178
|
+
return trigger.perform(this.buildContext(baseActionContext, context), Object.assign(Object.assign({}, (0, exports.defaultTriggerPayload)()), payload), this.buildParams(trigger.inputs, params));
|
|
160
179
|
});
|
|
161
180
|
}
|
|
162
181
|
action(key, params, context) {
|
|
163
182
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
-
const realizedContext = Object.assign(Object.assign({}, baseContext), context);
|
|
165
183
|
const action = this.component.actions[key];
|
|
166
|
-
return action.perform(
|
|
184
|
+
return action.perform(this.buildContext(baseActionContext, context), this.buildParams(action.inputs, params));
|
|
167
185
|
});
|
|
168
186
|
}
|
|
169
|
-
dataSource(key, params) {
|
|
187
|
+
dataSource(key, params, context) {
|
|
170
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
171
189
|
const dataSource = this.component.dataSources[key];
|
|
172
|
-
return dataSource.perform(
|
|
190
|
+
return dataSource.perform(this.buildContext(baseDataSourceContext, context), this.buildParams(dataSource.inputs, params));
|
|
173
191
|
});
|
|
174
192
|
}
|
|
175
193
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import { Inputs, DataSourceResult, DataSourceType, ActionInputParameters } from ".";
|
|
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
|
+
}
|
|
2
8
|
/** Definition of the function to perform when a Data Source is invoked. */
|
|
3
|
-
export declare type DataSourcePerformFunction<TInputs extends Inputs, TDataSourceType extends DataSourceType> = (params: ActionInputParameters<TInputs>) => Promise<DataSourceResult<TDataSourceType>>;
|
|
9
|
+
export declare type DataSourcePerformFunction<TInputs extends Inputs, TDataSourceType extends DataSourceType> = (context: DataSourceContext, params: ActionInputParameters<TInputs>) => Promise<DataSourceResult<TDataSourceType>>;
|
package/dist/types/Inputs.d.ts
CHANGED
package/dist/util.js
CHANGED
|
@@ -25,25 +25,11 @@ const isObjectWithTruthyKeys = (value, keys) => {
|
|
|
25
25
|
* @returns This function returns true if the type of `value` is an ObjectSelection, or false otherwise.
|
|
26
26
|
*/
|
|
27
27
|
const isObjectSelection = (value) => {
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
if (isObjectWithTruthyKeys(selection, ["key"])) {
|
|
31
|
-
const { fields } = selection;
|
|
32
|
-
if (Array.isArray(fields) &&
|
|
33
|
-
fields.length > 0 &&
|
|
34
|
-
!fields.every((field) => isObjectWithTruthyKeys(field, ["key"]))) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
return false;
|
|
28
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
29
|
+
return isObjectSelection(JSON.parse(value));
|
|
45
30
|
}
|
|
46
|
-
return
|
|
31
|
+
return (Array.isArray(value) &&
|
|
32
|
+
value.every((item) => isObjectWithTruthyKeys(item, ["object"])));
|
|
47
33
|
};
|
|
48
34
|
/**
|
|
49
35
|
* This function coerces a provided value into an ObjectSelection if possible.
|
|
@@ -51,33 +37,31 @@ const isObjectSelection = (value) => {
|
|
|
51
37
|
* @returns This function returns the the value as an ObjectSelection if possible.
|
|
52
38
|
*/
|
|
53
39
|
const toObjectSelection = (value) => {
|
|
40
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
41
|
+
return toObjectSelection(JSON.parse(value));
|
|
42
|
+
}
|
|
54
43
|
if (isObjectSelection(value)) {
|
|
55
44
|
return value;
|
|
56
45
|
}
|
|
57
|
-
throw new Error(`Value '${value}' cannot be coerced to ObjectSelection.`);
|
|
46
|
+
throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to ObjectSelection.`);
|
|
58
47
|
};
|
|
59
48
|
/**
|
|
60
49
|
* @param value The value to test
|
|
61
50
|
* @returns This function returns true if the type of `value` is an ObjectFieldMap, or false otherwise.
|
|
62
51
|
*/
|
|
63
52
|
const isObjectFieldMap = (value) => {
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
if (isObjectWithTruthyKeys(fieldMap, ["key", "value"])) {
|
|
67
|
-
const { value: val } = fieldMap;
|
|
68
|
-
if (!isObjectWithTruthyKeys(val, ["objectKey", "fieldKey"])) {
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
53
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
54
|
+
return isObjectFieldMap(JSON.parse(value));
|
|
76
55
|
}
|
|
77
|
-
|
|
78
|
-
|
|
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
|
+
])));
|
|
79
63
|
}
|
|
80
|
-
return
|
|
64
|
+
return false;
|
|
81
65
|
};
|
|
82
66
|
/**
|
|
83
67
|
* This function coerces a provided value into an ObjectFieldMap if possible.
|
|
@@ -85,16 +69,22 @@ const isObjectFieldMap = (value) => {
|
|
|
85
69
|
* @returns This function returns the the value as an ObjectFieldMap if possible.
|
|
86
70
|
*/
|
|
87
71
|
const toObjectFieldMap = (value) => {
|
|
72
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
73
|
+
return toObjectFieldMap(JSON.parse(value));
|
|
74
|
+
}
|
|
88
75
|
if (isObjectFieldMap(value)) {
|
|
89
76
|
return value;
|
|
90
77
|
}
|
|
91
|
-
throw new Error(`Value '${value}' cannot be coerced to ObjectFieldMap.`);
|
|
78
|
+
throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to ObjectFieldMap.`);
|
|
92
79
|
};
|
|
93
80
|
/**
|
|
94
81
|
* @param value The value to test
|
|
95
82
|
* @returns This function returns true if the type of `value` is a JSONForm, or false otherwise.
|
|
96
83
|
*/
|
|
97
84
|
const isJSONForm = (value) => {
|
|
85
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
86
|
+
return isJSONForm(JSON.parse(value));
|
|
87
|
+
}
|
|
98
88
|
return isObjectWithTruthyKeys(value, ["schema", "uiSchema", "data"]);
|
|
99
89
|
};
|
|
100
90
|
/**
|
|
@@ -103,10 +93,13 @@ const isJSONForm = (value) => {
|
|
|
103
93
|
* @returns This function returns the the value as a JSONForm if possible.
|
|
104
94
|
*/
|
|
105
95
|
const toJSONForm = (value) => {
|
|
96
|
+
if (typeof value === "string" && isJSON(value)) {
|
|
97
|
+
return toJSONForm(JSON.parse(value));
|
|
98
|
+
}
|
|
106
99
|
if (isJSONForm(value)) {
|
|
107
100
|
return value;
|
|
108
101
|
}
|
|
109
|
-
throw new Error(`Value '${value}' cannot be coerced to JSONForm.`);
|
|
102
|
+
throw new Error(`Value '${typeof value === "string" ? value : JSON.stringify(value)}' cannot be coerced to JSONForm.`);
|
|
110
103
|
};
|
|
111
104
|
/**
|
|
112
105
|
* Determine if a variable is a boolean (true or false).
|