From 5f7b885d1ce29f4e02fc18cefdad04bdeac77653 Mon Sep 17 00:00:00 2001 From: Alexandru Teodor Date: Wed, 24 Apr 2024 11:22:21 +0300 Subject: [PATCH] improve: LDP-2497: Add $ceApi helper and include query in server routes (#224) * improve: custom-fetch-instance: Add helper and include query in server routes * custom-fetch-instance: Add useCeApi helper * custom-fetch-instance: Improve code * custom-fetch-instance: Add dist * custom-fetch-instance: Remove query and add dist * custom-fetch-instance: Remove dist --- src/runtime/composables/useDrupalCe/index.ts | 71 ++++++++++++++------ src/runtime/server/api/drupalCe.ts | 5 +- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/runtime/composables/useDrupalCe/index.ts b/src/runtime/composables/useDrupalCe/index.ts index 65937d18..f01a6f39 100644 --- a/src/runtime/composables/useDrupalCe/index.ts +++ b/src/runtime/composables/useDrupalCe/index.ts @@ -2,6 +2,7 @@ import { callWithNuxt } from '#app' import { defu } from 'defu' import { appendResponseHeader } from 'h3' import type { UseFetchOptions } from '#app' +import type { $Fetch, NitroFetchRequest } from 'nitropack' import { getDrupalBaseUrl, getMenuBaseUrl } from './server' import { useRuntimeConfig, useState, useFetch, navigateTo, createError, h, resolveComponent, setResponseStatus, useNuxtApp, useRequestHeaders, ref, watch } from '#imports' @@ -25,9 +26,56 @@ export const useDrupalCe = () => { if (config.fetchProxyHeaders) { fetchOptions.headers = defu(fetchOptions.headers ?? {}, useRequestHeaders(config.fetchProxyHeaders)) } + + // If fetchOptions.query._content_format is undefined, use config.addRequestContentFormat. + // If fetchOptions.query._content_format is false, keep that. + fetchOptions.query = fetchOptions.query ?? {} + + fetchOptions.query._content_format = fetchOptions.query._content_format ?? config.addRequestContentFormat + if (!fetchOptions.query._content_format) { + // Remove _content_format if set to a falsy value (e.g. fetchOptions.query._content_format was set to false) + delete fetchOptions.query._content_format + } + + if (config.addRequestFormat) { + fetchOptions.query._format = 'custom_elements' + } return fetchOptions } + /** + * Custom $fetch instance + * @param fetchOptions UseFetchOptions + */ + const $ceApi = (fetchOptions: UseFetchOptions = {}): $Fetch => { + const useFetchOptions = processFetchOptions(fetchOptions) + + return $fetch.create({ + ...useFetchOptions + }) + } + + /** + * Fetch data from Drupal ce-API endpoint using $ceApi + * @param path Path of the Drupal ce-API endpoint to fetch + * @param fetchOptions UseFetchOptions + * @param passThroughHeaders Whether to pass through headers from Drupal to the client + */ + const useCeApi = (path: string | Ref, fetchOptions: UseFetchOptions = {}, doPassThroughHeaders?: boolean): Promise => { + const nuxtApp = useNuxtApp() + fetchOptions.onResponse = (context) => { + if (doPassThroughHeaders && config.passThroughHeaders && import.meta.server) { + const headersObject = Object.fromEntries([...context.response.headers.entries()]) + passThroughHeaders(nuxtApp, headersObject) + } + } + + return useFetch(path, { + ...fetchOptions, + $fetch: $ceApi(fetchOptions) + }) + } + /** * Returns the API endpoint with localization (if available) */ @@ -68,25 +116,8 @@ export const useDrupalCe = () => { title: '' })) useFetchOptions.key = `page-${path}` - useFetchOptions = processFetchOptions(useFetchOptions) - useFetchOptions.query = useFetchOptions.query ?? {} - - useFetchOptions.onResponse = (context) => { - if (config.passThroughHeaders && import.meta.server) { - const headersObject = Object.fromEntries([...context.response.headers.entries()]) - passThroughHeaders(nuxtApp, headersObject) - } - } - - if (config.addRequestContentFormat) { - useFetchOptions.query._content_format = config.addRequestContentFormat - } - - if (config.addRequestFormat) { - useFetchOptions.query._format = 'custom_elements' - } - const { data: page, error } = await useFetch(path, useFetchOptions) + const { data: page, error } = await useCeApi(path, useFetchOptions, true) if (page?.value?.redirect) { await callWithNuxt(nuxtApp, navigateTo, [ @@ -146,7 +177,7 @@ export const useDrupalCe = () => { } } - const { data: menu, error } = await useFetch(menuPath, useFetchOptions) + const { data: menu, error } = await useCeApi(menuPath, useFetchOptions) if (error.value) { overrideErrorHandler ? overrideErrorHandler(error) : menuErrorHandler(error) @@ -197,6 +228,8 @@ export const useDrupalCe = () => { } return { + $ceApi, + useCeApi, fetchPage, fetchMenu, getMessages, diff --git a/src/runtime/server/api/drupalCe.ts b/src/runtime/server/api/drupalCe.ts index e32667a8..1c6b9709 100644 --- a/src/runtime/server/api/drupalCe.ts +++ b/src/runtime/server/api/drupalCe.ts @@ -1,12 +1,13 @@ -import { defineEventHandler, proxyRequest, getRouterParams } from 'h3' +import { defineEventHandler, proxyRequest, getRouterParams, getQuery } from 'h3' import { getDrupalBaseUrl } from '../../composables/useDrupalCe/server' import { useRuntimeConfig } from '#imports' export default defineEventHandler(async (event) => { const params = getRouterParams(event)._ const path = params ? '/' + params : '' + const query = getQuery(event) ? '?' + new URLSearchParams(getQuery(event)) : '' const { ceApiEndpoint } = useRuntimeConfig().public.drupalCe // Remove x-forwarded-proto header as it causes issues with the request. delete event.req.headers['x-forwarded-proto'] - return await proxyRequest(event, getDrupalBaseUrl() + ceApiEndpoint + path) + return await proxyRequest(event, getDrupalBaseUrl() + ceApiEndpoint + path + query) })