UNPKG

@talend/react-containers

Version:

Provide connected components aka containers for @talend/react-cmf based on @talend/react-components.

224 lines (219 loc) 6.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCacheKey = createCacheKey; exports.default = createTriggers; exports.extractParameters = extractParameters; exports.getPathWithArrayIndex = getPathWithArrayIndex; exports.toJSON = toJSON; exports.toQueryParam = toQueryParam; var _reactCmf = _interopRequireDefault(require("@talend/react-cmf")); var _flatten = _interopRequireDefault(require("./flatten")); var _defaultRegistry = _interopRequireDefault(require("./defaultRegistry")); var _lodash = require("lodash"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Copyright (C) 2006-2018 Talend Inc. - www.talend.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* eslint-disable no-param-reassign */ const mergeCSRFToken = _reactCmf.default.middlewares.http.csrf.mergeCSRFToken; const DEFAULT_HEADERS = { 'Content-Type': 'application/json', Accept: 'application/json' }; function passthroughTrigger({ error, trigger, body }) { // eslint-disable-next-line no-console console.error(`${JSON.stringify(trigger)} doesnt exists or fails with error ${error || '-'}`); return body; } /** * array are describe without their index * use the schema to guess the path to use * to get the value in the properties * @param {string} specPath the path provided by the trigger * @param {Object} schema the schema of the current field * @return {string} path to get the value in properties */ function getPathWithArrayIndex(specPath, schema) { if (!schema) { return specPath; } const contextualPathItems = schema.key; if (!specPath || !contextualPathItems) { return specPath; } let keyIndex = 0; const schemaKey = schema.key; return specPath.split('.').reduce((acc, current) => { if (acc) { acc += '.'; } if (current.endsWith('[]')) { acc += `${current.substring(0, current.length - 1)}${schemaKey[keyIndex + 1]}]`; keyIndex += 2; } else { acc += current; keyIndex += 1; } return acc; }, ''); } /** * extract parameters from properties * @param {Array} parameters required * @param {Object} properties source of the data * @param {Object} schema of the current field the trigger is executed * @return {Object} payload of the trigger */ function extractParameters(parameters, properties, schema) { if (!parameters || !Array.isArray(parameters)) { return {}; } const flattenProps = (0, _flatten.default)(properties, { includeObjects: true }); return parameters.reduce((acc, param) => { const path = getPathWithArrayIndex(param.path, schema); const value = flattenProps[path]; if (typeof value === 'object') { Object.keys(value).filter(key => typeof value[key] !== 'object').forEach(key => { acc[`${param.key}${key}`] = value[key]; }); } else { acc[param.key] = value; } return acc; }, {}); } function createCacheKey(trigger) { if (trigger.type !== 'suggestions' || (trigger.parameters || []).length === 0) { return undefined; } return `${trigger.type}:${trigger.family}:${trigger.action}:${(trigger.parameters || []).map(it => it.path).join(':')}`; } function toJSON(resp) { if (!resp.ok || resp.status >= 300) { return resp.text().then(error => { let json; try { json = JSON.parse(error); } catch (e) { json = { error }; } throw json; }); } return resp.json(); } function toQueryParam(obj) { return Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&'); } // customRegistry can be used to add extensions or custom trigger // (not portable accross integrations) function createTriggers({ url, customRegistry, lang = 'en', headers, fetchConfig, security = {} }) { if (!url) { throw new Error('url params is required to createTriggers'); } const cache = {}; const actualHeaders = (0, _lodash.merge)({}, DEFAULT_HEADERS, headers); return function onDefaultTrigger(event, { trigger, schema, properties, errors }) { const services = { ..._defaultRegistry.default, ...customRegistry }; const parameters = extractParameters(trigger.parameters, properties, schema); const cacheKey = createCacheKey(trigger); if (cacheKey) { if (cache[cacheKey] && cache[cacheKey].result && (0, _lodash.isEqual)(cache[cacheKey].parameters, parameters)) { return Promise.resolve(cache[cacheKey].result); } else if (cache[cacheKey]) { delete cache[cacheKey]; } } function onSuccess(body) { const result = (services[trigger.type] || passthroughTrigger)({ body, errors, event, properties, schema, trigger }); if (body.cacheable) { cache[cacheKey] = { parameters, result }; } return result; } function onError(error) { return services.error({ error, errors, properties, schema, trigger }); } if (trigger.remote === false) { const result = onSuccess({}); if (result && result.then) { return result.catch(onError); } return new Promise(resolve => resolve(result)); } const config = _reactCmf.default.sagas.http.getDefaultConfig() || {}; let httpSecurity = config.security || {}; if (security.CSRFTokenCookieKey || security.CSRFTokenHeaderKey) { httpSecurity = security; } const fetchUrl = `${url}?${toQueryParam({ lang, action: trigger.action, family: trigger.family, type: trigger.type })}`; return fetch(fetchUrl, mergeCSRFToken({ security: httpSecurity })({ method: 'POST', headers: actualHeaders, body: JSON.stringify(parameters), credentials: 'include', ...fetchConfig })).then(toJSON).then(onSuccess).catch(onError); }; } //# sourceMappingURL=createTriggers.js.map