@prismatic-io/spectral
Version:
Utility library for building Prismatic connectors and code-native integrations
175 lines (174 loc) • 10.5 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.convertComponent = exports.convertConnection = exports.convertTrigger = exports.convertTemplateInput = exports._isValidTemplateValue = exports.convertInput = void 0;
const types_1 = require("../types");
const perform_1 = require("./perform");
const omit_1 = __importDefault(require("lodash/omit"));
const PollingTriggerDefinition_1 = require("../types/PollingTriggerDefinition");
const convertInput = (key, _a) => {
var { default: defaultValue, type, label, collection } = _a, rest = __rest(_a, ["default", "type", "label", "collection"]);
const keyLabel = collection === "keyvaluelist" && typeof label === "object" ? label.key : undefined;
return Object.assign(Object.assign({}, (0, omit_1.default)(rest, [
"onPremControlled",
"permissionAndVisibilityType",
"visibleToOrgDeployer",
"writeOnly",
])), { key,
type, default: defaultValue !== null && defaultValue !== void 0 ? defaultValue : types_1.InputFieldDefaultMap[type], collection, label: typeof label === "string" ? label : label.value, keyLabel, onPremiseControlled: ("onPremControlled" in rest && rest.onPremControlled) || undefined });
};
exports.convertInput = convertInput;
const TEMPLATE_VALUE_REGEX = /{{#(\w+)}}/g;
const TEMPLATE_VALUE_ERRORS = {
NO_SLOTS: "No template slots were found. Declare a template slot with this notation: {{#someInputKey}}",
INVALID_KEYS: "Invalid keys were found in the template string. All referenced keys must be non-template inputs declared in the first argument:",
};
const _isValidTemplateValue = (template, inputs) => {
const matches = [...template.matchAll(TEMPLATE_VALUE_REGEX)];
if (matches.length === 0) {
return {
isValid: false,
error: TEMPLATE_VALUE_ERRORS.NO_SLOTS,
};
}
const invalidKeys = [];
for (const [_substr, key] of matches) {
if (!inputs[key] || inputs[key].type === "template") {
invalidKeys.push(key);
}
}
if (invalidKeys.length > 0) {
return {
isValid: false,
error: `${TEMPLATE_VALUE_ERRORS.INVALID_KEYS} ${invalidKeys}`,
};
}
return {
isValid: true,
};
};
exports._isValidTemplateValue = _isValidTemplateValue;
const convertTemplateInput = (key, _a, inputs) => {
var { templateValue, label } = _a, rest = __rest(_a, ["templateValue", "label"]);
const validation = (0, exports._isValidTemplateValue)(templateValue, inputs);
if (!validation.isValid) {
throw `Template input "${key}": ${validation.error}`;
}
return Object.assign(Object.assign({}, (0, omit_1.default)(rest, ["permissionAndVisibilityType", "visibleToOrgDeployer", "writeOnly"])), { key, type: "template", default: templateValue !== null && templateValue !== void 0 ? templateValue : "", label: typeof label === "string" ? label : label.value, shown: false });
};
exports.convertTemplateInput = convertTemplateInput;
const convertAction = (actionKey, _a, hooks) => {
var { inputs = {}, perform } = _a, action = __rest(_a, ["inputs", "perform"]);
const convertedInputs = Object.entries(inputs).map(([key, value]) => (0, exports.convertInput)(key, value));
const inputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
return Object.assign(Object.assign({}, action), { key: actionKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
inputCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
}) });
};
const convertTrigger = (triggerKey, trigger, hooks) => {
var _a;
const { onInstanceDeploy, onInstanceDelete } = trigger;
const inputs = (_a = trigger.inputs) !== null && _a !== void 0 ? _a : {};
const isPollingTrigger = (0, PollingTriggerDefinition_1.isPollingTriggerDefinition)(trigger);
const triggerInputKeys = Object.keys(inputs);
const convertedTriggerInputs = Object.entries(inputs).map(([key, value]) => {
return (0, exports.convertInput)(key, value);
});
const triggerInputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
let scheduleSupport = "scheduleSupport" in trigger ? trigger.scheduleSupport : "invalid";
let convertedActionInputs = [];
let performToUse;
if (isPollingTrigger) {
// Pull inputs up from the action and make them available on the trigger
const { pollAction: action } = trigger;
let actionInputCleaners = {};
scheduleSupport = "required";
if (action) {
convertedActionInputs = Object.entries(action.inputs).reduce((accum, [key, value]) => {
if (triggerInputKeys.includes(key)) {
throw new Error(`The pollingTrigger "${trigger.display.label}" was defined with an input with the key: ${key}. This key duplicates an input on the associated "${action.display.label}" action. Please assign the trigger input a different key.`);
}
accum.push((0, exports.convertInput)(key, value));
return accum;
}, []);
actionInputCleaners = Object.entries(action.inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
}
const combinedCleaners = Object.assign({}, actionInputCleaners, triggerInputCleaners);
performToUse = (0, perform_1.createPollingPerform)(trigger, {
inputCleaners: combinedCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
});
}
else {
performToUse = (0, perform_1.createPerform)(trigger.perform, {
inputCleaners: triggerInputCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
});
}
const result = Object.assign(Object.assign({}, trigger), { key: triggerKey, inputs: convertedTriggerInputs.concat(convertedActionInputs), perform: performToUse, scheduleSupport, synchronousResponseSupport: "synchronousResponseSupport" in trigger
? trigger.synchronousResponseSupport
: scheduleSupport === "invalid"
? "valid"
: "invalid" });
if (onInstanceDeploy) {
result.onInstanceDeploy = (0, perform_1.createPerform)(onInstanceDeploy, {
inputCleaners: triggerInputCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
});
result.hasOnInstanceDeploy = true;
}
if (onInstanceDelete) {
result.onInstanceDelete = (0, perform_1.createPerform)(onInstanceDelete, {
inputCleaners: triggerInputCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
});
result.hasOnInstanceDelete = true;
}
const { pollAction, triggerType } = result, resultTrigger = __rest(result, ["pollAction", "triggerType"]);
return resultTrigger;
};
exports.convertTrigger = convertTrigger;
const convertDataSource = (dataSourceKey, _a, hooks) => {
var { inputs = {}, perform } = _a, dataSource = __rest(_a, ["inputs", "perform"]);
const convertedInputs = Object.entries(inputs).map(([key, value]) => (0, exports.convertInput)(key, value));
const inputCleaners = Object.entries(inputs).reduce((result, [key, { clean }]) => (Object.assign(Object.assign({}, result), { [key]: clean })), {});
return Object.assign(Object.assign({}, dataSource), { key: dataSourceKey, inputs: convertedInputs, perform: (0, perform_1.createPerform)(perform, {
inputCleaners,
errorHandler: hooks === null || hooks === void 0 ? void 0 : hooks.error,
}) });
};
const convertConnection = (_a) => {
var { inputs = {} } = _a, connection = __rest(_a, ["inputs"]);
const { display: { label, icons, description: comments } } = connection, remaining = __rest(connection, ["display"]);
const convertedInputs = Object.entries(inputs).map(([key, value]) => {
if ("templateValue" in value) {
return (0, exports.convertTemplateInput)(key, value, inputs);
}
return (0, exports.convertInput)(key, value);
});
return Object.assign(Object.assign({}, remaining), { label,
comments, iconPath: icons === null || icons === void 0 ? void 0 : icons.oauth2ConnectionIconPath, avatarIconPath: icons === null || icons === void 0 ? void 0 : icons.avatarPath, inputs: convertedInputs });
};
exports.convertConnection = convertConnection;
const convertComponent = (_a) => {
var { connections = [], actions = {}, triggers = {}, dataSources = {}, hooks } = _a, definition = __rest(_a, ["connections", "actions", "triggers", "dataSources", "hooks"]);
const convertedActions = Object.entries(actions).reduce((result, [actionKey, action]) => (Object.assign(Object.assign({}, result), { [actionKey]: convertAction(actionKey, action, hooks) })), {});
const convertedTriggers = Object.entries(triggers).reduce((result, [triggerKey, trigger]) => (Object.assign(Object.assign({}, result), { [triggerKey]: (0, exports.convertTrigger)(triggerKey, trigger, hooks) })), {});
const convertedDataSources = Object.entries(dataSources).reduce((result, [dataSourceKey, dataSource]) => (Object.assign(Object.assign({}, result), { [dataSourceKey]: convertDataSource(dataSourceKey, dataSource, hooks) })), {});
return Object.assign(Object.assign({}, definition), { connections: connections.map(exports.convertConnection), actions: convertedActions, triggers: convertedTriggers, dataSources: convertedDataSources });
};
exports.convertComponent = convertComponent;