From 273a8a1e41331a82b0b448253f64b4704e892bdd Mon Sep 17 00:00:00 2001 From: Johann Schopplich Date: Wed, 24 Aug 2022 20:18:25 +0200 Subject: [PATCH] feat: custom queries for `usePage` composable --- package-lock.json | 1 + package.json | 1 + src/composables/useKirbyApi.js | 24 +++++++++++++----------- src/composables/usePage.js | 15 ++++++++------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c317de9..2e238a7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "dependencies": { "ohmyfetch": "^0.4.18", "scule": "^0.3.2", + "ufo": "^0.8.5", "vue": "^3.2.37", "vue-router": "^4.1.3" }, diff --git a/package.json b/package.json index 07c3a8f0..b38df65c 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "ohmyfetch": "^0.4.18", "scule": "^0.3.2", + "ufo": "^0.8.5", "vue": "^3.2.37", "vue-router": "^4.1.3" }, diff --git a/src/composables/useKirbyApi.js b/src/composables/useKirbyApi.js index 5d3534fd..0db6068b 100644 --- a/src/composables/useKirbyApi.js +++ b/src/composables/useKirbyApi.js @@ -1,15 +1,16 @@ import { $fetch } from "ohmyfetch"; +import { withQuery } from "ufo"; import { useLanguages } from "./"; const cache = new Map(); /** - * Builds an API URL for a specific file and language + * Builds the full API URL for a specific path for the current language * - * @param {string} path The path to the file desired + * @param {string} path The target path * @returns {string} The final URL */ -function getApiUri(path) { +function getApiUrl(path) { const { isMultilang, languageCode } = useLanguages(); let result = ""; @@ -21,7 +22,7 @@ function getApiUri(path) { // Add the API path result += `/${import.meta.env.VITE_BACKEND_API_SLUG}`; - // Add the file path to fetch + // Add the file path result += `/${path}`; return result; @@ -33,13 +34,13 @@ function getApiUri(path) { * @param {string} id The page to retrieve * @param {object} [options] Optional options * @param {boolean} [options.revalidate=false] Skip cache look-up and fetch page freshly - * @param {string} [options.token] Add a token to the request to fetch a draft preview - * @returns {Promise|boolean>} The page's data or `false` if fetch request failed + * @param {Record} [options.query] Custom query parameters + * @returns {Promise|boolean>} The page's data or `false` if the fetch request failed */ -async function getPage(id, { revalidate = false, token } = {}) { +async function getPage(id, { revalidate = false, query = {} } = {}) { let page; - const isCached = cache.has(id); - const targetUrl = getApiUri(`${id}.json${token ? `?token=${token}` : ""}`); + const isCached = hasPage(id, query); + const targetUrl = getApiUrl(withQuery(`${id}.json`, query)); // Use cached page if present in the store, except when revalidating if (!revalidate && isCached) { @@ -82,10 +83,11 @@ async function getPage(id, { revalidate = false, token } = {}) { * Checks if a page has been cached already * * @param {string} id The page id to look up + * @param {Record} [query] Custom query parameters (optional) * @returns {boolean} `true` if the page exists */ -function hasPage(id) { - return cache.has(id); +function hasPage(id, query = {}) { + return cache.has(withQuery(id, query)); } /** diff --git a/src/composables/usePage.js b/src/composables/usePage.js index d029c23a..636f6338 100644 --- a/src/composables/usePage.js +++ b/src/composables/usePage.js @@ -5,20 +5,21 @@ import { useAnnouncer, useKirbyApi } from "./"; /** * Returns page data by id or the current route path * - * @param {string} [path] The ptional page id (path) to retrieve + * @param {string} [path] The page id to retrieve (optional) + * @param {Record} [query] Custom query parameters (optional) * @returns {Record} The readonly reactive page object */ -export function usePage(path) { +export function usePage(path, query = {}) { const router = useRouter(); - const { path: currentPath, query } = useRoute(); + const { path: currentPath, query: currentQuery } = useRoute(); const { hasPage, getPage } = useKirbyApi(); const { setAnnouncer } = useAnnouncer(); - // Build page id and trim leading or trailing slashes + // Build page id, trim leading and trailing slashes let id = (path ?? currentPath).replace(/^\/|\/$/g, ""); // Get the token query parameter for draft previews - const token = query.token; + const token = currentQuery.token; // Fall back to homepage if id is empty if (!id) id = "home"; @@ -38,9 +39,9 @@ export function usePage(path) { (async () => { // Check if cached page exists (otherwise skip SWR) - const isCached = hasPage(id); + const isCached = hasPage(id, query); // Get page from cache or freshly fetch it - const data = await getPage(id, { token }); + const data = await getPage(id, { ...query, token }); if (!data) { page.__status = "error";