UNPKG

infrastructure-components

Version:

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

213 lines (212 loc) • 10.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const React = __importStar(require("react")); const apollo_cache_inmemory_1 = require("apollo-cache-inmemory"); const apollo_link_http_1 = require("apollo-link-http"); const react_apollo_1 = require("react-apollo"); const apollo_client_1 = __importDefault(require("apollo-client")); //import { ApolloLink } from 'apollo-link'; const apollo_link_schema_1 = require("apollo-link-schema"); //import fetch from 'node-fetch'; require('es6-promise').polyfill(); require("isomorphic-fetch"); /** * we MUST NOT IMPORT CONTEXTs directly, but require them at time of use generally from Infrastructure-Components * because this then resolves to node_modules */ //import AttachDataLayer from './attach-data-layer'; const types_1 = __importDefault(require("../types")); const loader_1 = require("../libs/loader"); /** * */ exports.createServerSideClient = (link) => new apollo_client_1.default({ //ssrMode: true, // Remember that this is the interface the SSR server will use to connect to the // API server, so we need to ensure it isn't firewalled, etc link: link, cache: new apollo_cache_inmemory_1.InMemoryCache(), }); /** * Puts the preloaded state in a string that can be put into a <script>-tag * Also puts the path to the GraphQL-Endpoint there * * @param preloadedState the state */ // here, we can also add stringified (json) data about the dataLayer, e.g. Schema // it works without ... window.__SCHEMA__ = \`${schema}\` exports.importEnvironmentVariables = (preloadedState, url) => { //console.log("graphql-url: ", url); return `window.__APOLLO_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\\u003c')}; window.__GRAPHQL__ = "${url}"`; }; /** * Function to be used on the client side to connect the client app with the dehydrated state from the server * to be rehydrated on the client * * Note: Queries and Mutations work with POST-requests, if you want query requests to work with GET, * set `useGETForQueries` to true. Mutations always use POST * * @param app the ReactApp to connect with the DataLayer */ exports.hydrateFromDataLayer = (app, dataLayer) => { const AttachDataLayer = require("infrastructure-components").AttachDataLayer; //console.log("hydration, dataLayer: ", dataLayer); var preloadedState = {}; if (typeof window != 'undefined' && window.__APOLLO_STATE__) { preloadedState = window.__APOLLO_STATE__; delete window.__APOLLO_STATE__; } //console.log("uri: ", window.__GRAPHQL__); const client = new apollo_client_1.default({ cache: new apollo_cache_inmemory_1.InMemoryCache().restore(preloadedState), link: apollo_link_http_1.createHttpLink({ uri: window.__GRAPHQL__, credentials: 'include', }) }); //console.log("local client: ", client); return React.createElement(react_apollo_1.ApolloProvider, { client: client }, React.createElement(react_apollo_1.ApolloConsumer, null, client => React.createElement(AttachDataLayer, { apolloClient: client, dataLayer: dataLayer }, app))); }; /** * function to be used to provide the data-layer to a single-page-app-client (esp. SOA!) */ exports.renderFromDataLayer = (app, dataLayer) => { const AttachDataLayer = require("infrastructure-components").AttachDataLayer; //console.log("connect, dataLayer: ", dataLayer); //console.log("uri: ", window.__GRAPHQL__); const client = new apollo_client_1.default({ cache: new apollo_cache_inmemory_1.InMemoryCache(), link: apollo_link_http_1.createHttpLink(Object.assign({ uri: window.__GRAPHQL__, })) }); //console.log("local client: ", client); return React.createElement(react_apollo_1.ApolloProvider, { client: client }, React.createElement(react_apollo_1.ApolloConsumer, null, client => React.createElement(AttachDataLayer, { apolloClient: client, dataLayer: dataLayer }, app))); }; exports.createApolloClient = (dataLayer, graphqlUrl, request) => { //console.log("STAGE_PATH: ", process.env.STAGE_PATH); //console.log("DOMAIN_ENABLED: ", process.env.DOMAIN_ENABLED); // TODO take these variables, esp. GraphQl-Path from the component rather than from the env-variables, // because, there might be more than one DataLayers! // when we have a valid stage_path or a domain, e.g. https://xxxxxxxxxxx.execute-api.eu-west-1.amazonaws.com/dev/query', /*const graphqlUrl = ( process.env.STAGE_PATH !== undefined && process.env.STAGE_PATH !== "undefined" && process.env.STAGE_PATH.length > 0 ) || process.env.DOMAIN_ENABLED === "true" ? // then use the path (process.env.DOMAIN_ENABLED !== undefined && process.env.DOMAIN_ENABLED === "true" && process.env.DOMAIN_NAME !== undefined && process.env.DOMAIN_NAME !== undefined ? "https://"+process.env.DOMAIN_NAME : process.env.DOMAIN_URL) + "/"+process.env.GRAPHQL_PATH : // else mock the endpoint - use the dev-endpoint "https://yfse1b9v0m.execute-api.eu-west-1.amazonaws.com/dev/query"; // undefined; // // // TODO set undefined or a Mock or the Dev-Address here */ //console.log("graphqlUrl: ", graphqlUrl); //console.log("schema: ", schema); const client = new apollo_client_1.default({ ssrMode: true, //ssrForceFetchDelay: 100, cache: new apollo_cache_inmemory_1.InMemoryCache(), /* instead of the createHttpLink, we use SchemaLink({ schema }) to void network traffic, for both endpoints * implements [[UseSchemaLinkSpec]] * */ link: new apollo_link_schema_1.SchemaLink({ schema: dataLayer.getSchema(true), context: { // when we have a userId, put it into the context so thatwe have it through ssr, too. userId: require("infrastructure-components").getUserId(request) } }) /*link: createHttpLink({ uri: graphqlUrl, fetch: awsGraphqlFetch, credentials: 'include', }),*/ }); //console.log("client: ", client); return client; }; exports.getGraphqlUrl = (isOffline) => { // does not work offline, but does not need to! //console.log("Domain: ", process.env.DOMAIN_URL) // TODO this should not be hard-coded - see SOA plugin! return isOffline ? "http://localhost:3000/query" : process.env.DOMAIN_URL + "/" + process.env.GRAPHQL_PATH; }; /** * Function to be used on server side that connects a ReactApp (jsx) with a GraphQL-Layer hosted on AWS Lambda/DynamoDb * Creates the server side store * * Fetch-library is required , see [this](https://github.com/apollographql/apollo-client/issues/3578) * see [fetch polyfill](https://www.apollographql.com/docs/link/links/http.html#options) * * @param app the ReactApp to connect with the DataLayer * @schema specifies the schema to connect the store with, if undefined: use the uri (via network). see [[UseSchemaLinkSpec]] */ exports.connectWithDataLayer = (dataLayerId, request, isOffline) => (app) => __awaiter(void 0, void 0, void 0, function* () { /** * we MUST NOT IMPORT CONTEXTs directly, but require them at time of use generally from Infrastructure-Components * because this then resolves to node_modules */ const AttachDataLayer = require("infrastructure-components").AttachDataLayer; //console.log("AttachDataLayer: ", AttachDataLayer) //console.log("connectWithDataLayer: ", dataLayerId); // load the IsomorphicComponent // we must load it directly from the module here, to enable the aliad of the config_file_path const isoConfig = loader_1.loadConfigurationFromModule(require('__CONFIG_FILE_PATH__'), loader_1.INFRASTRUCTURE_MODES.RUNTIME); // with a clientApp, we can check whether it is wrapped into a datalayer const dataLayer = loader_1.extractObject(isoConfig, types_1.default.INFRASTRUCTURE_TYPE_COMPONENT, dataLayerId); if (isOffline) { //console.log("connectWithDataLayer - setOffline!") dataLayer.setOffline(true); } //console.log("dataLayer: ", dataLayer); return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () { const awsGraphqlFetch = (uri, options) => { //console.log("fetch: ",uri, options); //options.headers["Authorization"] = token; return fetch(uri, options); }; const graphqlUrl = exports.getGraphqlUrl(isOffline); // "https://yfse1b9v0m.execute-api.eu-west-1.amazonaws.com/dev/query";// process.env.DOMAIN_URL + "/"+process.env.GRAPHQL_PATH; const client = exports.createApolloClient(dataLayer, graphqlUrl, request); dataLayer.setClient(client); const connectedApp = React.createElement(react_apollo_1.ApolloProvider, { client: client }, React.createElement(react_apollo_1.ApolloConsumer, null, client => React.createElement(AttachDataLayer, { apolloClient: client, dataLayer: dataLayer }, app))); //console.log("connectedApp: ", connectedApp); try { //.catch((err) => console.log("err: ", err)) yield react_apollo_1.getDataFromTree(connectedApp).then(() => resolve({ connectedApp: connectedApp, getState: () => { //console.log("time to resolve"); const data = client.extract(); //console.log("data: ", data); return exports.importEnvironmentVariables(data, graphqlUrl.trim()); } })); } catch (error) { console.log("error: ", error); } })); }); //# sourceMappingURL=datalayer-integration.js.map