graphql-paper
Version:
A flexible in-memory store based on a GraphQL Schema
57 lines (55 loc) • 2.54 kB
JavaScript
;
var getConnections = require('./get-connections.js');
var getDocumentKey = require('./get-document-key.js');
var extractListType = require('../graphql/extract-list-type.js');
var extractObjectTypes = require('../graphql/extract-object-types.js');
var isDocument = require('./is-document.js');
var nullDocument = require('./null-document.js');
function collapseDocument(schema, document) {
const connections = getConnections.getConnections(document);
const type = schema.getType(document.__typename);
if (!type) {
throw new Error(`Could not find type ${document.__typename} in the GraphQL Schema`);
}
const fields = type.getFields();
for (const fieldName in fields) {
const documentFieldValue = document[fieldName];
const field = fields[fieldName];
const hasObjectReferences = extractObjectTypes.extractObjectTypes(schema, field.type).length > 0;
const isListConnection = extractListType.extractListType(field.type) && hasObjectReferences;
const isSingularConnection = !extractListType.extractListType(field.type) && hasObjectReferences;
const isConnectionField = isListConnection || isSingularConnection;
// skip non-connection fields
if (!isConnectionField) {
continue;
}
// skip undefined and null
if (documentFieldValue === undefined || documentFieldValue === null) {
continue;
}
// handle list of connected documents
const connectedDocuments = Array.isArray(documentFieldValue) ? documentFieldValue : [documentFieldValue];
const connectionKeys = connectedDocuments.map(maybeDocument => {
// include positional null documents in list if necessary
maybeDocument = maybeDocument === null ? nullDocument.nullDocument : maybeDocument;
if (!isDocument.isDocument(maybeDocument)) {
throw new Error(`Expected document in array on field ${fieldName}, got:\n${JSON.stringify(maybeDocument, null, 2)}`);
}
return getDocumentKey.getDocumentKey(maybeDocument);
});
connections[fieldName] = connectionKeys;
// remove the existing value, the key is considered represented as a connection
delete document[fieldName];
}
}
function collapseConnections(graphqlSchema, store) {
for (const typeName in store) {
const typeStore = store[typeName];
for (const document of typeStore) {
collapseDocument(graphqlSchema, document);
}
}
}
exports.collapseConnections = collapseConnections;
exports.collapseDocument = collapseDocument;
//# sourceMappingURL=collapse-connections.js.map