UNPKG

infrastructure-components

Version:

Infrastructure-Components configure the infrastructure of your React-App as part of your React-Components.

310 lines (235 loc) • 9.17 kB
import React, {ReactNode} from 'react'; import Types from '../types'; import { IComponent} from "../types/component"; import { IInfrastructure } from "../types"; import {ENTRY_INSTANCE_TYPE, createEntryProps, IEntryArgs} from "../datalayer/entry-component"; import { IC_USER_ID} from "./auth-middleware"; import createMiddleware from '../middleware/middleware-component'; import ConnectSequence from 'connect-sequence'; import {getEntryListQuery, setEntryMutation, setEntry, ddbListEntries, deleteEntry} from '../datalayer/datalayer-libs'; import { graphql, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLList, GraphQLInputObjectType } from 'graphql'; export interface ISecuredEntryProps { /** * Functions that the Authentication-Component looks for */ setUserId: any, setMiddleware: any, externalMiddleware?: any, /** * the id of the authentication-provider */ userId?: any, } /** * an entry specifies a kind of data that can be stored in a line of the table */ export default (props: IEntryArgs | any) => { // the component must have the properties of IComponent const componentProps: IInfrastructure & IComponent = { infrastructureType: Types.INFRASTRUCTURE_TYPE_COMPONENT, instanceType: ENTRY_INSTANCE_TYPE, instanceId: props.id }; const mwProps = { middleware: createMiddleware({callback: (req, res, next) => { console.log("this is the default mw of the SecuredEntry: ", props.id) if (securedEntryProps.externalMiddleware) { console.log("now using the provided middleware") return new ConnectSequence(req, res, next) .append(securedEntryProps.externalMiddleware.callback) .run(); } return next(); }}) }; const securedEntryProps: ISecuredEntryProps = { //origRangeKey: props.rangeKey, setUserId: (userId) => { console.log(props.id, " received userId: ", userId) securedEntryProps.userId = userId; //props.rangeKey = IC_USER_ID }, /** * We MUST NOT OVERWRITE exisiting functions, only data. middleware is a function * because they get not called */ // the authentication-component replaces the middleware! setMiddleware: (mw) => { console.log(props.id, " received middleware: ", mw) securedEntryProps.externalMiddleware = mw; } }; const entryProps: any = createEntryProps(Object.assign({}, props, componentProps, securedEntryProps)); const setUserIdFromContext = (context) => { //console.log("check userId? ", entryProps, props, securedEntryProps) // when called through ssr, we do not get the userId through the ICs. But the DataLayer-Integration puts // it into the context for us if (securedEntryProps && securedEntryProps.userId) { console.log("SecuredEntry already has userId, not taking from context: ", securedEntryProps.userId); return; } if (context && context.userId) { if (securedEntryProps) { securedEntryProps["userId"] = context["userId"]; } else { console.error("no entryProps exist, cannot set userId") } return; } console.warn("no userId in context or in entryProps...") }; return Object.assign(entryProps, { // we need to adjust the writing into the table setEntry: (args, context, tableName, isOffline) => { setUserIdFromContext(context); return setEntry( tableName, //"code-architect-dev-data-layer", props.primaryKey, // schema.Entry.ENTITY, //pkEntity args[props.primaryKey], // pkId IC_USER_ID, //schema.Data.ENTITY, // skEntity `${securedEntryProps.userId}|${props.rangeKey}|${args[props.rangeKey]}`, // skId Object.keys(args).reduce((result, key) => { if (Object.keys(props.data).find(datakey => datakey === key) !== undefined) { result[key] = args[key]; } return result; },{}), // jsonData, isOffline ); }, deleteEntry: (args, context, tableName, isOffline) => { setUserIdFromContext(context); return deleteEntry( tableName, //"code-architect-dev-data-layer", props.primaryKey, // schema.Entry.ENTITY, //pkEntity args[props.primaryKey], // pkId IC_USER_ID, //schema.Data.ENTITY, // skEntity `${securedEntryProps.userId}|${props.rangeKey}|${args[props.rangeKey]}`, // skId isOffline ); }, listEntries: (args, context, tableName, key, isOffline) => { setUserIdFromContext(context); const entity = key === "pk" ? props.primaryKey : `${IC_USER_ID}|${securedEntryProps.userId}|${props.rangeKey}`; const range = key === "pk" ? `${IC_USER_ID}|${securedEntryProps.userId}|${props.rangeKey}` : props.primaryKey; return ddbListEntries( tableName, //tablename key, // key entity, //entity args[key === "pk" ? props.primaryKey : props.rangeKey], //value range, //rangeEntity isOffline ).then(results => { console.log("promised: ", results); return results.map(item => { const data = item.jsonData !== undefined ? JSON.parse(item.jsonData) : {}; data[props.primaryKey] = item.pk.substring(item.pk.lastIndexOf("|")+1); data[props.rangeKey] = item.sk.substring(item.sk.lastIndexOf("|")+1); return data; }); }); }, }, mwProps); // we provide the newly set middleware as last prop to overwrite the other values! }; export const isSecuredEntry = (component) => { return component !== undefined && component.instanceType === ENTRY_INSTANCE_TYPE; }; const complementedProps = { /* createEntryFields: () => { const fields = Object.keys(props.data).reduce((result, key)=> { if (key !== securedEntryProps.origRangeKey) { result[key] = {type: props.data[key]}; } return result; }, {}); fields[props.primaryKey] = {type: GraphQLString}; fields[IC_USER_ID] = {type: GraphQLString}; return fields; }, createEntryType: (prefix) => { return new GraphQLObjectType({ name: prefix+props.id, fields: () => complementedProps.createEntryFields() }) }, createKeyArgs: () => { const args = {}; args[props.primaryKey] = {name: props.primaryKey, type: GraphQLString}; args[IC_USER_ID] = {name: IC_USER_ID, type: GraphQLString}; return args; },* / getEntryListQuery: (dictKey) => { const fields = entryProps.createEntryFields(); //console.log("fields: ", fields); return getEntryListQuery( props.id, dictKey, fields, { userId: securedEntryProps.userId } //context ); }, setEntryMutation: (values) => { const fields = entryProps.createEntryFields(); //console.log("fields: ", fields); return setEntryMutation( props.id, values, fields, { userId: securedEntryProps.userId } //context ); }, /* // let's overwrite how the user can get the getEntryListQuery: (dictKey) => { const fields = complementedProps.createEntryFields(); //console.log("fields: ", fields); // TODO, complement dictKey or even change the whole query ... return getEntryListQuery( props.id, Object.keys(dictKey).reduce((res, key) => { // we replace the rangeKey with the if (key === securedEntryProps.origRangeKey) { res[props.rangeKey] = `${securedEntryProps.clientId}|${securedEntryProps.origRangeKey}|${dictKey[key]}` } else { res[key] = dictKey[key]; } return res; }, {}), fields ); }, // this creates the input for the gql-tag: how the query is sent to apollo setEntryMutation: (values) => { const fields = complementedProps.createEntryFields(); return setEntryMutation( props.id, Object.keys(values).reduce((res, key) => { // we replace the rangeKey with the if (key === securedEntryProps.origRangeKey) { res[props.rangeKey] = `${securedEntryProps.clientId}|${securedEntryProps.origRangeKey}|${values[key]}` } else { res[key] = values[key]; } return res; }, {}), fields, { // we need to pass the clientId into the context of the gql-query for we don't have the value there yet! clientId: securedEntryProps.clientId } //context ); }*/ };