From 95a4010be073c5ae5cd4383b20a7012adf7c62cb Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 12 Jul 2024 17:17:38 +0200 Subject: [PATCH] feat: Handle io.cozy.apps_registry query On the StackLink side, the `io.cozy.apps_registry` is handled by the AppsRegistryCollection that queries a specific cozy-stack route when the `slug` parameter equals `maintenance` This is a shortcut to query all apps under maintenance This is problematic because the local Pouch is synchronized on this doctype and stores all apps with their respective IDs. There is no `maintenance` document, so we cannot process a query that selects this ID To make this possible, we want to persist the `maintenance` query's result as a single document with the `maintenance` id --- packages/cozy-client/src/CozyClient.js | 17 +++++++++++++++-- packages/cozy-pouch-link/src/jsonapi.js | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/cozy-client/src/CozyClient.js b/packages/cozy-client/src/CozyClient.js index cf0c83f22e..4ab834f804 100644 --- a/packages/cozy-client/src/CozyClient.js +++ b/packages/cozy-client/src/CozyClient.js @@ -1086,7 +1086,7 @@ client.query(Q('io.cozy.bills'))`) async requestQuery(definition) { const mainResponse = await this.chain.request(definition) - this.persistVirtualDocuments(mainResponse.data) + this.persistVirtualDocuments(definition, mainResponse.data) if (!definition.includes) { return mainResponse @@ -1105,7 +1105,20 @@ client.query(Q('io.cozy.bills'))`) * @param {CozyClientDocument | Array} data - Document or array of documents to be saved * @returns {Promise} */ - async persistVirtualDocuments(data) { + async persistVirtualDocuments(definition, data) { + if (definition.doctype === 'io.cozy.apps_registry') { + // io.cozy.apps_registry has a dedicated endpoint on cozy-stack that + // returns data different than the one stored in database + // We want to store the full answer data under the `maintenance` id + // so we can query it from the Pouch the same way we query it from the stack + return await this.persistVirtualDocument({ + _type: 'io.cozy.apps_registry', + _id: 'maintenance', + // @ts-ignore + cozyPouchData: data + }) + } + if (!Array.isArray(data)) { await this.persistVirtualDocument(data) } else { diff --git a/packages/cozy-pouch-link/src/jsonapi.js b/packages/cozy-pouch-link/src/jsonapi.js index 159435bf73..5ff0a18f58 100644 --- a/packages/cozy-pouch-link/src/jsonapi.js +++ b/packages/cozy-pouch-link/src/jsonapi.js @@ -22,6 +22,20 @@ export const normalizeDoc = (doc, doctype) => { const filterDeletedDocumentsFromRows = doc => !!doc export const fromPouchResult = (res, withRows, doctype) => { + // Sometimes, queries are transformed by Collections and they call a dedicated + // cozy-stack route. When this is the case, we want to be able to replicate the same + // query from cozy-pouch-link. It is not possible as-is because the received data + // is not the same as the one stored in the Couch database + // To handle this, we store the received data in the Pouch with a dedicated id and + // we store the query result in a `cozyPouchData` attribute + // So when `cozyPouchData` attribute exists, we know that we want to return its content + // as the result of the query + if (res.cozyPouchData) { + return { + data: res.cozyPouchData + } + } + if (withRows) { const docs = res.rows ? res.rows.map(row => row.doc).filter(filterDeletedDocumentsFromRows)