@@ -3,13 +3,18 @@ package com.apollographql.cache.normalized.api
33import com.apollographql.apollo.api.CompiledField
44import com.apollographql.apollo.api.CompiledListType
55import com.apollographql.apollo.api.CompiledNotNullType
6+ import com.apollographql.apollo.api.Error
67import com.apollographql.apollo.api.Executable
78import com.apollographql.apollo.api.MutableExecutionOptions
9+ import com.apollographql.apollo.api.json.MapJsonReader.Companion.buffer
10+ import com.apollographql.apollo.api.json.jsonReader
811import com.apollographql.apollo.exception.CacheMissException
912import com.apollographql.apollo.mpp.currentTimeMillis
1013import com.apollographql.cache.normalized.api.CacheResolver.ResolvedValue
1114import com.apollographql.cache.normalized.maxStale
1215import com.apollographql.cache.normalized.storeExpirationDate
16+ import com.apollographql.cache.normalized.storeReceivedDate
17+ import okio.Buffer
1318import kotlin.jvm.JvmSuppressWildcards
1419
1520/* *
@@ -255,7 +260,8 @@ fun FieldPolicyCacheResolver(
255260 keyScope : CacheKey .Scope = CacheKey .Scope .TYPE ,
256261) = object : CacheResolver {
257262 override fun resolveField (context : ResolverContext ): Any? {
258- val keyArgsValues = context.field.argumentValues(context.variables) { it.definition.isKey }.values
263+ val keyArgs = context.field.argumentValues(context.variables) { it.definition.isKey }
264+ val keyArgsValues = keyArgs.values
259265 if (keyArgsValues.isEmpty()) {
260266 return DefaultCacheResolver .resolveField(context)
261267 }
@@ -270,21 +276,70 @@ fun FieldPolicyCacheResolver(
270276 if (keyArgsValues.size == 1 ) {
271277 val keyArgsValue = keyArgsValues.first() as ? List <* >
272278 if (keyArgsValue != null && keyArgsValue.firstOrNull() !is List <* >) {
273- return keyArgsValue.map {
274- if (keyScope == CacheKey .Scope .TYPE ) {
275- CacheKey (type.rawType().name, it.toString())
279+ val listItemsInParent: Map <Any ?, Any ?> = listItemsInParent(context, keyArgs.keys.first())
280+ return keyArgsValue.mapIndexed { index, value ->
281+ if (listItemsInParent.containsKey(value)) {
282+ listItemsInParent[value]?.let {
283+ if (it is Error ) {
284+ it.withIndex(index)
285+ } else {
286+ it
287+ }
288+ }
276289 } else {
277- CacheKey (it.toString())
290+ if (keyScope == CacheKey .Scope .TYPE ) {
291+ CacheKey (type.rawType().name, value.toString())
292+ } else {
293+ CacheKey (value.toString())
294+ }
278295 }
279296 }
280297 }
281298 }
282299 }
283300 }
284- return if (keyScope == CacheKey .Scope .TYPE ) {
285- CacheKey (type.rawType().name, keyArgsValues.map { it.toString() })
301+ val fieldKey = context.getFieldKey()
302+ return if (context.parent.containsKey(fieldKey)) {
303+ context.parent[fieldKey]
286304 } else {
287- CacheKey (keyArgsValues.map { it.toString() })
305+ if (keyScope == CacheKey .Scope .TYPE ) {
306+ CacheKey (type.rawType().name, keyArgsValues.map { it.toString() })
307+ } else {
308+ CacheKey (keyArgsValues.map { it.toString() })
309+ }
310+ }
311+ }
312+
313+ private fun Error.withIndex (index : Int ): Error {
314+ val builder = Error .Builder (message)
315+ if (locations != null ) builder.locations(locations!! )
316+ if (extensions != null ) {
317+ for ((k, v) in extensions!! ) {
318+ builder.putExtension(k, v)
319+ }
320+ }
321+ if (path != null ) {
322+ builder.path(path!! .toMutableList().apply { this [this .lastIndex] = index })
323+ }
324+ return builder.build()
325+ }
326+
327+ private fun listItemsInParent (
328+ context : ResolverContext ,
329+ keyArg : String ,
330+ ): Map <Any ?, Any ?> {
331+ val keyPrefix = " ${context.field.name} ("
332+ val filteredParent = context.parent.filterKeys { it.startsWith(keyPrefix) && it.contains(" \" $keyArg \" :" ) }
333+ val items: Map <Any ?, Any ?> = filteredParent.map { (k, v) ->
334+ val argumentsText = k.removePrefix(keyPrefix).removeSuffix(" )" )
335+ val argumentsMap = Buffer ().writeUtf8(argumentsText).jsonReader().buffer().root as Map <* , * >
336+ val keyValues = argumentsMap[keyArg] as List <* >
337+ keyValues.mapIndexed { index, id ->
338+ id to (v as List <* >)[index]
339+ }.toMap()
340+ }.fold(emptyMap()) { acc, map ->
341+ acc + map
288342 }
343+ return items
289344 }
290345}
0 commit comments