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
JavaScript
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
;