UNPKG

relay-runtime

Version:

A core runtime for building GraphQL-driven applications.

948 lines (947 loc) • 45.3 kB
'use strict'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _excluded = ["message"]; var RelayFeatureFlags = require('../util/RelayFeatureFlags'); var _require = require('./live-resolvers/LiveResolverSuspenseSentinel'), isSuspenseSentinel = _require.isSuspenseSentinel; var RelayConcreteVariables = require('./RelayConcreteVariables'); var RelayModernRecord = require('./RelayModernRecord'); var _require2 = require('./RelayStoreUtils'), CLIENT_EDGE_TRAVERSAL_PATH = _require2.CLIENT_EDGE_TRAVERSAL_PATH, FRAGMENT_OWNER_KEY = _require2.FRAGMENT_OWNER_KEY, FRAGMENT_PROP_NAME_KEY = _require2.FRAGMENT_PROP_NAME_KEY, FRAGMENTS_KEY = _require2.FRAGMENTS_KEY, ID_KEY = _require2.ID_KEY, MODULE_COMPONENT_KEY = _require2.MODULE_COMPONENT_KEY, ROOT_ID = _require2.ROOT_ID, getArgumentValues = _require2.getArgumentValues, getModuleComponentKey = _require2.getModuleComponentKey, getStorageKey = _require2.getStorageKey; var _require3 = require('./ResolverCache'), NoopResolverCache = _require3.NoopResolverCache; var _require4 = require('./ResolverFragments'), RESOLVER_FRAGMENT_ERRORED_SENTINEL = _require4.RESOLVER_FRAGMENT_ERRORED_SENTINEL, withResolverContext = _require4.withResolverContext; var _require5 = require('./TypeID'), generateTypeID = _require5.generateTypeID; var invariant = require('invariant'); function read(recordSource, selector, resolverCache, resolverContext) { var reader = new RelayReader(recordSource, selector, resolverCache !== null && resolverCache !== void 0 ? resolverCache : new NoopResolverCache(), resolverContext); return reader.read(); } var RelayReader = /*#__PURE__*/function () { function RelayReader(recordSource, selector, resolverCache, resolverContext) { var _selector$clientEdgeT, _ref, _this$_owner$node$ope, _this$_owner$node$ope2; this._clientEdgeTraversalPath = (_selector$clientEdgeT = selector.clientEdgeTraversalPath) !== null && _selector$clientEdgeT !== void 0 && _selector$clientEdgeT.length ? (0, _toConsumableArray2["default"])(selector.clientEdgeTraversalPath) : []; this._missingClientEdges = []; this._missingLiveResolverFields = []; this._isMissingData = false; this._isWithinUnmatchedTypeRefinement = false; this._fieldErrors = null; this._owner = selector.owner; this._useExecTimeResolvers = (_ref = (_this$_owner$node$ope = this._owner.node.operation.use_exec_time_resolvers) !== null && _this$_owner$node$ope !== void 0 ? _this$_owner$node$ope : ((_this$_owner$node$ope2 = this._owner.node.operation.exec_time_resolvers_enabled_provider) === null || _this$_owner$node$ope2 === void 0 ? void 0 : _this$_owner$node$ope2.get()) === true) !== null && _ref !== void 0 ? _ref : false; this._recordSource = recordSource; this._seenRecords = new Set(); this._selector = selector; this._variables = selector.variables; this._resolverCache = resolverCache; this._fragmentName = selector.node.name; this._updatedDataIDs = new Set(); this._resolverContext = resolverContext; } var _proto = RelayReader.prototype; _proto.read = function read() { var _this$_selector$node$; var _this$_selector = this._selector, node = _this$_selector.node, dataID = _this$_selector.dataID, isWithinUnmatchedTypeRefinement = _this$_selector.isWithinUnmatchedTypeRefinement; var abstractKey = node.abstractKey; var record = this._recordSource.get(dataID); var isDataExpectedToBePresent = !isWithinUnmatchedTypeRefinement; if (isDataExpectedToBePresent && abstractKey == null && record != null) { if (!this._recordMatchesTypeCondition(record, node.type)) { isDataExpectedToBePresent = false; } } if (isDataExpectedToBePresent && abstractKey != null && record != null) { var implementsInterface = this._implementsInterface(record, abstractKey); if (implementsInterface === false) { isDataExpectedToBePresent = false; } } this._isWithinUnmatchedTypeRefinement = !isDataExpectedToBePresent; var data = this._traverse(node, dataID, null); var catchTo = (_this$_selector$node$ = this._selector.node.metadata) === null || _this$_selector$node$ === void 0 ? void 0 : _this$_selector$node$.catchTo; if (catchTo != null) { data = this._catchErrors(data, catchTo, null); } if (this._updatedDataIDs.size > 0) { this._resolverCache.notifyUpdatedSubscribers(this._updatedDataIDs); this._updatedDataIDs.clear(); } return { data: data, isMissingData: this._isMissingData && isDataExpectedToBePresent, missingClientEdges: this._missingClientEdges.length ? this._missingClientEdges : null, missingLiveResolverFields: this._missingLiveResolverFields, seenRecords: this._seenRecords, selector: this._selector, fieldErrors: this._fieldErrors }; }; _proto._maybeAddFieldErrors = function _maybeAddFieldErrors(record, storageKey) { var errors = RelayModernRecord.getErrors(record, storageKey); if (errors == null) { return; } var owner = this._fragmentName; if (this._fieldErrors == null) { this._fieldErrors = []; } for (var i = 0; i < errors.length; i++) { var _error$path, _this$_selector$node$2, _this$_selector$node$3; var error = errors[i]; this._fieldErrors.push({ kind: 'relay_field_payload.error', owner: owner, fieldPath: ((_error$path = error.path) !== null && _error$path !== void 0 ? _error$path : []).join('.'), error: error, shouldThrow: (_this$_selector$node$2 = (_this$_selector$node$3 = this._selector.node.metadata) === null || _this$_selector$node$3 === void 0 ? void 0 : _this$_selector$node$3.throwOnFieldError) !== null && _this$_selector$node$2 !== void 0 ? _this$_selector$node$2 : false, handled: false, uiContext: undefined }); } }; _proto._markDataAsMissing = function _markDataAsMissing(fieldName) { var _this$_selector$node$4, _this$_selector$node$5; if (this._isWithinUnmatchedTypeRefinement) { return; } if (this._fieldErrors == null) { this._fieldErrors = []; } var owner = this._fragmentName; this._fieldErrors.push(((_this$_selector$node$4 = (_this$_selector$node$5 = this._selector.node.metadata) === null || _this$_selector$node$5 === void 0 ? void 0 : _this$_selector$node$5.throwOnFieldError) !== null && _this$_selector$node$4 !== void 0 ? _this$_selector$node$4 : false) ? { kind: 'missing_expected_data.throw', owner: owner, fieldPath: fieldName, handled: false, uiContext: undefined } : { kind: 'missing_expected_data.log', owner: owner, fieldPath: fieldName, uiContext: undefined }); this._isMissingData = true; if (this._clientEdgeTraversalPath.length) { var top = this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1]; if (top !== null) { this._missingClientEdges.push({ request: top.readerClientEdge.operation, clientEdgeDestinationID: top.clientEdgeDestinationID }); } } }; _proto._traverse = function _traverse(node, dataID, prevData) { var record = this._recordSource.get(dataID); this._seenRecords.add(dataID); if (record == null) { if (record === undefined) { this._markDataAsMissing('<record>'); } return record; } var data = prevData || {}; var hadRequiredData = this._traverseSelections(node.selections, record, data); return hadRequiredData ? data : null; }; _proto._getVariableValue = function _getVariableValue(name) { !this._variables.hasOwnProperty(name) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Undefined variable `%s`.', name) : invariant(false) : void 0; return this._variables[name]; }; _proto._maybeReportUnexpectedNull = function _maybeReportUnexpectedNull(selection) { if (selection.action === 'NONE') { return; } var owner = this._fragmentName; if (this._fieldErrors == null) { this._fieldErrors = []; } var fieldName; if (selection.field.linkedField != null) { var _selection$field$link; fieldName = (_selection$field$link = selection.field.linkedField.alias) !== null && _selection$field$link !== void 0 ? _selection$field$link : selection.field.linkedField.name; } else { var _selection$field$alia; fieldName = (_selection$field$alia = selection.field.alias) !== null && _selection$field$alia !== void 0 ? _selection$field$alia : selection.field.name; } switch (selection.action) { case 'THROW': this._fieldErrors.push({ kind: 'missing_required_field.throw', fieldPath: fieldName, owner: owner, handled: false, uiContext: undefined }); return; case 'LOG': this._fieldErrors.push({ kind: 'missing_required_field.log', fieldPath: fieldName, owner: owner, uiContext: undefined }); return; default: selection.action; } }; _proto._handleRequiredFieldValue = function _handleRequiredFieldValue(selection, value) { if (value == null) { this._maybeReportUnexpectedNull(selection); return false; } return true; }; _proto._catchErrors = function _catchErrors(_value, to, previousResponseFields) { var value = _value; switch (to) { case 'RESULT': value = this._asResult(_value); break; case 'NULL': if (this._fieldErrors != null && this._fieldErrors.length > 0) { value = null; } break; default: to; } var childrenFieldErrors = this._fieldErrors; this._fieldErrors = previousResponseFields; if (childrenFieldErrors != null) { if (this._fieldErrors == null) { this._fieldErrors = []; } for (var i = 0; i < childrenFieldErrors.length; i++) { this._fieldErrors.push(markFieldErrorHasHandled(childrenFieldErrors[i])); } } return value; }; _proto._asResult = function _asResult(value) { if (this._fieldErrors == null || this._fieldErrors.length === 0) { return { ok: true, value: value }; } var errors = this._fieldErrors.map(function (error) { switch (error.kind) { case 'relay_field_payload.error': var _error$error = error.error, message = _error$error.message, displayError = (0, _objectWithoutPropertiesLoose2["default"])(_error$error, _excluded); return displayError; case 'missing_expected_data.throw': case 'missing_expected_data.log': return { path: error.fieldPath.split('.') }; case 'relay_resolver.error': return { message: "Relay: Error in resolver for field at ".concat(error.fieldPath, " in ").concat(error.owner) }; case 'missing_required_field.throw': return { message: "Relay: Missing @required value at path '".concat(error.fieldPath, "' in '").concat(error.owner, "'.") }; case 'missing_required_field.log': return null; default: error.kind; !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected error fieldError kind: %s', error.kind) : invariant(false) : void 0; } }).filter(Boolean); return { ok: false, errors: errors }; }; _proto._traverseSelections = function _traverseSelections(selections, record, data) { for (var i = 0; i < selections.length; i++) { var selection = selections[i]; switch (selection.kind) { case 'RequiredField': var requiredFieldValue = this._readClientSideDirectiveField(selection, record, data); if (!this._handleRequiredFieldValue(selection, requiredFieldValue)) { return false; } break; case 'CatchField': { var _selection$field$back, _selection$field, _field$alias; var previousResponseFields = this._fieldErrors; this._fieldErrors = null; var catchFieldValue = this._readClientSideDirectiveField(selection, record, data); var field = (_selection$field$back = (_selection$field = selection.field) === null || _selection$field === void 0 ? void 0 : _selection$field.backingField) !== null && _selection$field$back !== void 0 ? _selection$field$back : selection.field; var fieldName = (_field$alias = field === null || field === void 0 ? void 0 : field.alias) !== null && _field$alias !== void 0 ? _field$alias : field === null || field === void 0 ? void 0 : field.name; !(fieldName != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "Couldn't determine field name for this field. It might be a ReaderClientExtension - which is not yet supported.") : invariant(false) : void 0; data[fieldName] = this._catchErrors(catchFieldValue, selection.to, previousResponseFields); break; } case 'ScalarField': this._readScalar(selection, record, data); break; case 'LinkedField': if (selection.plural) { this._readPluralLink(selection, record, data); } else { this._readLink(selection, record, data); } break; case 'Condition': var conditionValue = Boolean(this._getVariableValue(selection.condition)); if (conditionValue === selection.passingValue) { var hasExpectedData = this._traverseSelections(selection.selections, record, data); if (!hasExpectedData) { return false; } } break; case 'InlineFragment': { var _hasExpectedData = this._readInlineFragment(selection, record, data, false); if (_hasExpectedData === false) { return false; } break; } case 'RelayLiveResolver': case 'RelayResolver': { if (this._useExecTimeResolvers) { this._readScalar(selection, record, data); } else { this._readResolverField(selection, record, data); } break; } case 'FragmentSpread': this._createFragmentPointer(selection, record, data); break; case 'AliasedInlineFragmentSpread': { this._readAliasedInlineFragment(selection, record, data); break; } case 'ModuleImport': this._readModuleImport(selection, record, data); break; case 'InlineDataFragmentSpread': this._createInlineDataOrResolverFragmentPointer(selection, record, data); break; case 'Defer': case 'ClientExtension': { var isMissingData = this._isMissingData; var alreadyMissingClientEdges = this._missingClientEdges.length; this._clientEdgeTraversalPath.push(null); var _hasExpectedData2 = this._traverseSelections(selection.selections, record, data); this._isMissingData = isMissingData || this._missingClientEdges.length > alreadyMissingClientEdges || this._missingLiveResolverFields.length > 0; this._clientEdgeTraversalPath.pop(); if (!_hasExpectedData2) { return false; } break; } case 'Stream': { var _hasExpectedData3 = this._traverseSelections(selection.selections, record, data); if (!_hasExpectedData3) { return false; } break; } case 'ActorChange': this._readActorChange(selection, record, data); break; case 'ClientEdgeToClientObject': case 'ClientEdgeToServerObject': if (this._useExecTimeResolvers && (selection.backingField.kind === 'RelayResolver' || selection.backingField.kind === 'RelayLiveResolver')) { var linkedField = selection.linkedField; if (linkedField.plural) { this._readPluralLink(linkedField, record, data); } else { this._readLink(linkedField, record, data); } } else { this._readClientEdge(selection, record, data); } break; default: selection; !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.kind) : invariant(false) : void 0; } } return true; }; _proto._readClientSideDirectiveField = function _readClientSideDirectiveField(selection, record, data) { switch (selection.field.kind) { case 'ScalarField': return this._readScalar(selection.field, record, data); case 'LinkedField': if (selection.field.plural) { return this._readPluralLink(selection.field, record, data); } else { return this._readLink(selection.field, record, data); } case 'RelayResolver': case 'RelayLiveResolver': { if (this._useExecTimeResolvers) { return this._readScalar(selection.field, record, data); } else { return this._readResolverField(selection.field, record, data); } } case 'ClientEdgeToClientObject': case 'ClientEdgeToServerObject': if (this._useExecTimeResolvers && (selection.field.backingField.kind === 'RelayResolver' || selection.field.backingField.kind === 'RelayLiveResolver')) { var field = selection.field; if (field.linkedField.plural) { return this._readPluralLink(field.linkedField, record, data); } else { return this._readLink(field.linkedField, record, data); } } else { return this._readClientEdge(selection.field, record, data); } case 'AliasedInlineFragmentSpread': return this._readAliasedInlineFragment(selection.field, record, data); default: selection.field.kind; !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Unexpected ast kind `%s`.', selection.field.kind) : invariant(false) : void 0; } }; _proto._readResolverField = function _readResolverField(field, record, data) { var _field$alias2; var parentRecordID = RelayModernRecord.getDataID(record); var prevErrors = this._fieldErrors; this._fieldErrors = null; var result = this._readResolverFieldImpl(field, parentRecordID); var fieldName = (_field$alias2 = field.alias) !== null && _field$alias2 !== void 0 ? _field$alias2 : field.name; this._prependPreviousErrors(prevErrors, fieldName); data[fieldName] = result; return result; }; _proto._readResolverFieldImpl = function _readResolverFieldImpl(field, parentRecordID) { var _this = this; var fragment = field.fragment; var snapshot; var getDataForResolverFragment = function getDataForResolverFragment(singularReaderSelector) { if (snapshot != null) { return { data: snapshot.data, isMissingData: snapshot.isMissingData, fieldErrors: snapshot.fieldErrors }; } snapshot = read(_this._recordSource, singularReaderSelector, _this._resolverCache); return { data: snapshot.data, isMissingData: snapshot.isMissingData, fieldErrors: snapshot.fieldErrors }; }; var evaluate = function evaluate() { if (fragment != null) { var key = { __id: parentRecordID, __fragmentOwner: _this._owner, __fragments: (0, _defineProperty2["default"])({}, fragment.name, fragment.args ? getArgumentValues(fragment.args, _this._variables) : {}) }; if (_this._clientEdgeTraversalPath.length > 0 && _this._clientEdgeTraversalPath[_this._clientEdgeTraversalPath.length - 1] !== null) { key[CLIENT_EDGE_TRAVERSAL_PATH] = (0, _toConsumableArray2["default"])(_this._clientEdgeTraversalPath); } var resolverContext = { getDataForResolverFragment: getDataForResolverFragment }; return withResolverContext(resolverContext, function () { var _getResolverValue = getResolverValue(field, _this._variables, key, _this._resolverContext), resolverResult = _getResolverValue[0], resolverError = _getResolverValue[1]; return { resolverResult: resolverResult, snapshot: snapshot, error: resolverError }; }); } else { var _getResolverValue2 = getResolverValue(field, _this._variables, null, _this._resolverContext), resolverResult = _getResolverValue2[0], _resolverError = _getResolverValue2[1]; return { resolverResult: resolverResult, snapshot: undefined, error: _resolverError }; } }; var _this$_resolverCache$ = this._resolverCache.readFromCacheOrEvaluate(parentRecordID, field, this._variables, evaluate, getDataForResolverFragment), result = _this$_resolverCache$[0], seenRecord = _this$_resolverCache$[1], resolverError = _this$_resolverCache$[2], cachedSnapshot = _this$_resolverCache$[3], suspenseID = _this$_resolverCache$[4], updatedDataIDs = _this$_resolverCache$[5]; this._propagateResolverMetadata(field.path, cachedSnapshot, resolverError, seenRecord, suspenseID, updatedDataIDs); return result; }; _proto._propagateResolverMetadata = function _propagateResolverMetadata(fieldPath, cachedSnapshot, resolverError, seenRecord, suspenseID, updatedDataIDs) { var _this2 = this; if (cachedSnapshot != null) { if (cachedSnapshot.missingClientEdges != null) { for (var i = 0; i < cachedSnapshot.missingClientEdges.length; i++) { var missing = cachedSnapshot.missingClientEdges[i]; this._missingClientEdges.push(missing); } } if (cachedSnapshot.missingLiveResolverFields != null) { this._isMissingData = this._isMissingData || cachedSnapshot.missingLiveResolverFields.length > 0; for (var _i = 0; _i < cachedSnapshot.missingLiveResolverFields.length; _i++) { var missingResolverField = cachedSnapshot.missingLiveResolverFields[_i]; this._missingLiveResolverFields.push(missingResolverField); } } if (cachedSnapshot.fieldErrors != null) { if (this._fieldErrors == null) { this._fieldErrors = []; } for (var _i2 = 0; _i2 < cachedSnapshot.fieldErrors.length; _i2++) { var _this$_selector$node$6; var error = cachedSnapshot.fieldErrors[_i2]; if (((_this$_selector$node$6 = this._selector.node.metadata) === null || _this$_selector$node$6 === void 0 ? void 0 : _this$_selector$node$6.throwOnFieldError) === true) { this._fieldErrors.push(error); } else { this._fieldErrors.push(markFieldErrorHasHandled(error)); } } } this._isMissingData = this._isMissingData || cachedSnapshot.isMissingData; } if (resolverError) { var _this$_selector$node$7, _this$_selector$node$8; var errorEvent = { kind: 'relay_resolver.error', fieldPath: fieldPath, owner: this._fragmentName, error: resolverError, shouldThrow: (_this$_selector$node$7 = (_this$_selector$node$8 = this._selector.node.metadata) === null || _this$_selector$node$8 === void 0 ? void 0 : _this$_selector$node$8.throwOnFieldError) !== null && _this$_selector$node$7 !== void 0 ? _this$_selector$node$7 : false, handled: false, uiContext: undefined }; if (this._fieldErrors == null) { this._fieldErrors = [errorEvent]; } else { this._fieldErrors.push(errorEvent); } } if (seenRecord != null) { this._seenRecords.add(seenRecord); } if (suspenseID != null) { this._isMissingData = true; this._missingLiveResolverFields.push(suspenseID); } if (updatedDataIDs != null) { updatedDataIDs.forEach(function (recordID) { _this2._updatedDataIDs.add(recordID); }); } }; _proto._readClientEdge = function _readClientEdge(field, record, data) { var _this3 = this; var _backingField$alias; var backingField = field.backingField; !(backingField.kind !== 'ClientExtension') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Client extension client edges are not yet implemented.') : invariant(false) : void 0; var fieldName = (_backingField$alias = backingField.alias) !== null && _backingField$alias !== void 0 ? _backingField$alias : backingField.name; var backingFieldData = {}; this._traverseSelections([backingField], record, backingFieldData); var clientEdgeResolverResponse = backingFieldData[fieldName]; if (clientEdgeResolverResponse == null || isSuspenseSentinel(clientEdgeResolverResponse)) { data[fieldName] = clientEdgeResolverResponse; return clientEdgeResolverResponse; } if (field.linkedField.plural) { !Array.isArray(clientEdgeResolverResponse) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected plural Client Edge Relay Resolver at `%s` in `%s` to return an array containing IDs or objects with shape {id}.', backingField.path, this._owner.identifier) : invariant(false) : void 0; var storeIDs; !(field.kind === 'ClientEdgeToClientObject') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected Client Edge to plural server type `%s`. This should be prevented by the compiler.', field.kind) : invariant(false) : void 0; if (field.backingField.normalizationInfo == null) { storeIDs = clientEdgeResolverResponse.map(function (itemResponse) { var _field$concreteType; var concreteType = (_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : itemResponse.__typename; !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, _this3._owner.identifier) : invariant(false) : void 0; var localId = extractIdFromResponse(itemResponse, backingField.path, _this3._owner.identifier); var id = _this3._resolverCache.ensureClientRecord(localId, concreteType); var modelResolvers = field.modelResolvers; if (modelResolvers != null) { var modelResolver = modelResolvers[concreteType]; !(modelResolver !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Invalid `__typename` returned by resolver at `%s` in `%s`. Expected one of %s but got `%s`.', backingField.path, _this3._owner.identifier, Object.keys(modelResolvers).join(', '), concreteType) : invariant(false) : void 0; var model = _this3._readResolverFieldImpl(modelResolver, id); return model != null ? id : null; } return id; }); } else { storeIDs = clientEdgeResolverResponse.map(function (obj) { return extractIdFromResponse(obj, backingField.path, _this3._owner.identifier); }); } this._clientEdgeTraversalPath.push(null); var edgeValues = this._readLinkedIds(field.linkedField, storeIDs, record, data); this._clientEdgeTraversalPath.pop(); data[fieldName] = edgeValues; return edgeValues; } else { var _field$concreteType2; var id = extractIdFromResponse(clientEdgeResolverResponse, backingField.path, this._owner.identifier); var storeID; var concreteType = (_field$concreteType2 = field.concreteType) !== null && _field$concreteType2 !== void 0 ? _field$concreteType2 : clientEdgeResolverResponse.__typename; var traversalPathSegment; if (field.kind === 'ClientEdgeToClientObject') { if (field.backingField.normalizationInfo == null) { !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, this._owner.identifier) : invariant(false) : void 0; storeID = this._resolverCache.ensureClientRecord(id, concreteType); traversalPathSegment = null; } else { storeID = id; traversalPathSegment = null; } } else { storeID = id; traversalPathSegment = { readerClientEdge: field, clientEdgeDestinationID: id }; } var modelResolvers = field.modelResolvers; if (modelResolvers != null) { !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, this._owner.identifier) : invariant(false) : void 0; var modelResolver = modelResolvers[concreteType]; !(modelResolver !== undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Invalid `__typename` returned by resolver at `%s` in `%s`. Expected one of %s but got `%s`.', backingField.path, this._owner.identifier, Object.keys(modelResolvers).join(', '), concreteType) : invariant(false) : void 0; var model = this._readResolverFieldImpl(modelResolver, storeID); if (model == null) { data[fieldName] = null; return null; } } this._clientEdgeTraversalPath.push(traversalPathSegment); var prevData = data[fieldName]; !(prevData == null || typeof prevData === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field at `%s` in `%s` on record `%s` ' + 'to be an object, got `%s`.', backingField.path, this._owner.identifier, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0; var prevErrors = this._fieldErrors; this._fieldErrors = null; var edgeValue = this._traverse(field.linkedField, storeID, prevData); this._prependPreviousErrors(prevErrors, fieldName); this._clientEdgeTraversalPath.pop(); data[fieldName] = edgeValue; return edgeValue; } }; _proto._readScalar = function _readScalar(field, record, data) { var _field$alias3; var fieldName = (_field$alias3 = field.alias) !== null && _field$alias3 !== void 0 ? _field$alias3 : field.name; var storageKey = getStorageKey(field, this._variables); var value = RelayModernRecord.getValue(record, storageKey); if (value === null || RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(value) && value.length === 0) { this._maybeAddFieldErrors(record, storageKey); } else if (value === undefined) { this._markDataAsMissing(fieldName); } data[fieldName] = value; return value; }; _proto._readLink = function _readLink(field, record, data) { var _field$alias4; var fieldName = (_field$alias4 = field.alias) !== null && _field$alias4 !== void 0 ? _field$alias4 : field.name; var storageKey = getStorageKey(field, this._variables); var linkedID = RelayModernRecord.getLinkedRecordID(record, storageKey); if (linkedID == null) { data[fieldName] = linkedID; if (linkedID === null) { this._maybeAddFieldErrors(record, storageKey); } else if (linkedID === undefined) { this._markDataAsMissing(fieldName); } return linkedID; } var prevData = data[fieldName]; !(prevData == null || typeof prevData === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` at `%s` on record `%s` ' + 'to be an object, got `%s`.', fieldName, this._owner.identifier, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0; var prevErrors = this._fieldErrors; this._fieldErrors = null; var value = this._traverse(field, linkedID, prevData); this._prependPreviousErrors(prevErrors, fieldName); data[fieldName] = value; return value; }; _proto._prependPreviousErrors = function _prependPreviousErrors(prevErrors, fieldNameOrIndex) { if (this._fieldErrors != null) { for (var i = 0; i < this._fieldErrors.length; i++) { var event = this._fieldErrors[i]; if (event.owner === this._fragmentName && (event.kind === 'missing_expected_data.throw' || event.kind === 'missing_expected_data.log' || event.kind === 'missing_required_field.throw' || event.kind === 'missing_required_field.log')) { event.fieldPath = "".concat(fieldNameOrIndex, ".").concat(event.fieldPath); } } if (prevErrors != null) { for (var _i3 = this._fieldErrors.length - 1; _i3 >= 0; _i3--) { prevErrors.push(this._fieldErrors[_i3]); } this._fieldErrors = prevErrors; } } else { this._fieldErrors = prevErrors; } }; _proto._readActorChange = function _readActorChange(field, record, data) { var _field$alias5; var fieldName = (_field$alias5 = field.alias) !== null && _field$alias5 !== void 0 ? _field$alias5 : field.name; var storageKey = getStorageKey(field, this._variables); var externalRef = RelayModernRecord.getActorLinkedRecordID(record, storageKey); if (externalRef == null) { data[fieldName] = externalRef; if (externalRef === undefined) { this._markDataAsMissing(fieldName); } else if (externalRef === null) { this._maybeAddFieldErrors(record, storageKey); } return data[fieldName]; } var actorIdentifier = externalRef[0], dataID = externalRef[1]; var fragmentRef = {}; this._createFragmentPointer(field.fragmentSpread, RelayModernRecord.fromObject({ __id: dataID }), fragmentRef); data[fieldName] = { __fragmentRef: fragmentRef, __viewer: actorIdentifier }; return data[fieldName]; }; _proto._readPluralLink = function _readPluralLink(field, record, data) { var storageKey = getStorageKey(field, this._variables); var linkedIDs = RelayModernRecord.getLinkedRecordIDs(record, storageKey); if (linkedIDs === null || RelayFeatureFlags.ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS && Array.isArray(linkedIDs) && linkedIDs.length === 0) { this._maybeAddFieldErrors(record, storageKey); } return this._readLinkedIds(field, linkedIDs, record, data); }; _proto._readLinkedIds = function _readLinkedIds(field, linkedIDs, record, data) { var _this4 = this; var _field$alias6; var fieldName = (_field$alias6 = field.alias) !== null && _field$alias6 !== void 0 ? _field$alias6 : field.name; if (linkedIDs == null) { data[fieldName] = linkedIDs; if (linkedIDs === undefined) { this._markDataAsMissing(fieldName); } return linkedIDs; } var prevData = data[fieldName]; !(prevData == null || Array.isArray(prevData)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` on record `%s` ' + 'to be an array, got `%s`.', fieldName, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0; var prevErrors = this._fieldErrors; this._fieldErrors = null; var linkedArray = prevData || []; linkedIDs.forEach(function (linkedID, nextIndex) { if (linkedID == null) { if (linkedID === undefined) { _this4._markDataAsMissing(String(nextIndex)); } linkedArray[nextIndex] = linkedID; return; } var prevItem = linkedArray[nextIndex]; !(prevItem == null || typeof prevItem === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` on record `%s` ' + 'to be an object, got `%s`.', fieldName, RelayModernRecord.getDataID(record), prevItem) : invariant(false) : void 0; var prevErrors = _this4._fieldErrors; _this4._fieldErrors = null; linkedArray[nextIndex] = _this4._traverse(field, linkedID, prevItem); _this4._prependPreviousErrors(prevErrors, nextIndex); }); this._prependPreviousErrors(prevErrors, fieldName); data[fieldName] = linkedArray; return linkedArray; }; _proto._readModuleImport = function _readModuleImport(moduleImport, record, data) { var componentKey = getModuleComponentKey(moduleImport.documentName); var relayStoreComponent = RelayModernRecord.getValue(record, componentKey); var component = relayStoreComponent !== undefined ? relayStoreComponent : moduleImport.componentModuleProvider; if (component == null) { if (component === undefined) { this._markDataAsMissing('<module-import>'); } return; } this._createFragmentPointer({ kind: 'FragmentSpread', name: moduleImport.fragmentName, args: moduleImport.args }, record, data); data[FRAGMENT_PROP_NAME_KEY] = moduleImport.fragmentPropName; data[MODULE_COMPONENT_KEY] = component; }; _proto._readAliasedInlineFragment = function _readAliasedInlineFragment(aliasedInlineFragment, record, data) { var prevErrors = this._fieldErrors; this._fieldErrors = null; var fieldValue = this._readInlineFragment(aliasedInlineFragment.fragment, record, {}, true); this._prependPreviousErrors(prevErrors, aliasedInlineFragment.name); if (fieldValue === false) { fieldValue = null; } data[aliasedInlineFragment.name] = fieldValue; }; _proto._readInlineFragment = function _readInlineFragment(inlineFragment, record, data, skipUnmatchedAbstractTypes) { if (inlineFragment.type == null) { var hasExpectedData = this._traverseSelections(inlineFragment.selections, record, data); if (hasExpectedData === false) { return false; } return data; } var abstractKey = inlineFragment.abstractKey; if (abstractKey == null) { if (!this._recordMatchesTypeCondition(record, inlineFragment.type)) { return null; } else { var hasExpectedData = this._traverseSelections(inlineFragment.selections, record, data); if (!hasExpectedData) { return false; } } } else { var implementsInterface = this._implementsInterface(record, abstractKey); if (implementsInterface === false && skipUnmatchedAbstractTypes) { return null; } var parentIsMissingData = this._isMissingData; var parentIsWithinUnmatchedTypeRefinement = this._isWithinUnmatchedTypeRefinement; this._isWithinUnmatchedTypeRefinement = parentIsWithinUnmatchedTypeRefinement || implementsInterface === false; var hasMissingData = this._traverseSelections(inlineFragment.selections, record, data); this._isWithinUnmatchedTypeRefinement = parentIsWithinUnmatchedTypeRefinement; if (implementsInterface === false) { this._isMissingData = parentIsMissingData; return null; } else if (implementsInterface == null) { return undefined; } else if (hasMissingData === false) { return false; } } return data; }; _proto._recordMatchesTypeCondition = function _recordMatchesTypeCondition(record, type) { var typeName = RelayModernRecord.getType(record); return typeName != null && typeName === type || RelayModernRecord.getDataID(record) === ROOT_ID; }; _proto._createFragmentPointer = function _createFragmentPointer(fragmentSpread, record, data) { var fragmentPointers = data[FRAGMENTS_KEY]; if (fragmentPointers == null) { fragmentPointers = data[FRAGMENTS_KEY] = {}; } !(typeof fragmentPointers === 'object' && fragmentPointers != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader: Expected fragment spread data to be an object, got `%s`.', fragmentPointers) : invariant(false) : void 0; if (data[ID_KEY] == null) { data[ID_KEY] = RelayModernRecord.getDataID(record); } fragmentPointers[fragmentSpread.name] = getArgumentValues(fragmentSpread.args, this._variables, this._isWithinUnmatchedTypeRefinement); data[FRAGMENT_OWNER_KEY] = this._owner; if (this._clientEdgeTraversalPath.length > 0 && this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1] !== null) { data[CLIENT_EDGE_TRAVERSAL_PATH] = (0, _toConsumableArray2["default"])(this._clientEdgeTraversalPath); } }; _proto._createInlineDataOrResolverFragmentPointer = function _createInlineDataOrResolverFragmentPointer(fragmentSpreadOrFragment, record, data) { var fragmentPointers = data[FRAGMENTS_KEY]; if (fragmentPointers == null) { fragmentPointers = data[FRAGMENTS_KEY] = {}; } !(typeof fragmentPointers === 'object' && fragmentPointers != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader: Expected fragment spread data to be an object, got `%s`.', fragmentPointers) : invariant(false) : void 0; if (data[ID_KEY] == null) { data[ID_KEY] = RelayModernRecord.getDataID(record); } var inlineData = {}; var parentFragmentName = this._fragmentName; this._fragmentName = fragmentSpreadOrFragment.name; var parentVariables = this._variables; var argumentVariables = fragmentSpreadOrFragment.args ? getArgumentValues(fragmentSpreadOrFragment.args, this._variables) : {}; this._variables = RelayConcreteVariables.getFragmentVariables(fragmentSpreadOrFragment, this._owner.variables, argumentVariables); this._traverseSelections(fragmentSpreadOrFragment.selections, record, inlineData); this._variables = parentVariables; this._fragmentName = parentFragmentName; fragmentPointers[fragmentSpreadOrFragment.name] = inlineData; }; _proto._implementsInterface = function _implementsInterface(record, abstractKey) { var typeName = RelayModernRecord.getType(record); var typeRecord = this._recordSource.get(generateTypeID(typeName)); var implementsInterface = typeRecord != null ? RelayModernRecord.getValue(typeRecord, abstractKey) : null; if (implementsInterface == null) { this._markDataAsMissing('<abstract-type-hint>'); } return implementsInterface; }; return RelayReader; }(); function markFieldErrorHasHandled(event) { switch (event.kind) { case 'missing_expected_data.throw': case 'missing_required_field.throw': case 'relay_field_payload.error': case 'relay_resolver.error': return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, event), {}, { handled: true }); case 'missing_expected_data.log': case 'missing_required_field.log': return event; default: event.kind; !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected error response field kind: %s', event.kind) : invariant(false) : void 0; } } function getResolverValue(field, variables, fragmentKey, resolverContext) { var resolverFunction = typeof field.resolverModule === 'function' ? field.resolverModule : field.resolverModule["default"]; var resolverResult = null; var resolverError = null; try { var resolverFunctionArgs = []; if (field.fragment != null) { resolverFunctionArgs.push(fragmentKey); } var args = field.args ? getArgumentValues(field.args, variables) : undefined; resolverFunctionArgs.push(args); resolverFunctionArgs.push(resolverContext); resolverResult = resolverFunction.apply(null, resolverFunctionArgs); } catch (e) { resolverResult = null; if (e !== RESOLVER_FRAGMENT_ERRORED_SENTINEL) { resolverError = e; } } return [resolverResult, resolverError]; } function extractIdFromResponse(individualResponse, path, owner) { if (typeof individualResponse === 'string') { return individualResponse; } else if (typeof individualResponse === 'object' && individualResponse != null && typeof individualResponse.id === 'string') { return individualResponse.id; } !false ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected object returned from edge resolver to be a string or an object with an `id` property at path %s in %s,', path, owner) : invariant(false) : void 0; } module.exports = { read: read };