From fd8e3b82c1a0cf51fdae8b60f4363743427e895e Mon Sep 17 00:00:00 2001 From: Farnabaz Date: Wed, 30 Aug 2023 14:30:02 +0200 Subject: [PATCH] fix(navigation): prevent client-db conflict --- src/module.ts | 2 +- src/runtime/legacy/composables/navigation.ts | 54 ++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/runtime/legacy/composables/navigation.ts diff --git a/src/module.ts b/src/module.ts index eafbed0ed..98edd7b3c 100644 --- a/src/module.ts +++ b/src/module.ts @@ -520,7 +520,7 @@ export default defineNuxtModule({ // Register navigation if (options.navigation) { - addImports({ name: 'fetchContentNavigation', as: 'fetchContentNavigation', from: resolveRuntimeModule('./composables/navigation') }) + addImports({ name: 'fetchContentNavigation', as: 'fetchContentNavigation', from: resolveRuntimeModule(`./${options.experimental.advanceQuery ? '' : 'legacy/'}composables/navigation`) }) nuxt.hook('nitro:config', (nitroConfig) => { nitroConfig.handlers = nitroConfig.handlers || [] diff --git a/src/runtime/legacy/composables/navigation.ts b/src/runtime/legacy/composables/navigation.ts new file mode 100644 index 000000000..932e0aeb1 --- /dev/null +++ b/src/runtime/legacy/composables/navigation.ts @@ -0,0 +1,54 @@ +import { hash } from 'ohash' +import type { NavItem, QueryBuilder, QueryBuilderParams } from '../../types' +import { encodeQueryParams } from '../../utils/query' +import { jsonStringify } from '../../utils/json' +import { ContentQueryBuilder } from '../../types/query' +import { addPrerenderPath, shouldUseClientDB, withContentBase } from '../../composables/utils' +import { useContentPreview } from '../../composables/preview' +import { queryContent } from './query' +import { useRuntimeConfig } from '#app' + +export const fetchContentNavigation = async (queryBuilder?: QueryBuilder | QueryBuilderParams | ContentQueryBuilder): Promise> => { + const { content } = useRuntimeConfig().public + + // Ensure that queryBuilder is an instance of QueryBuilder + if (typeof queryBuilder?.params !== 'function') { + queryBuilder = queryContent(queryBuilder as any) + } + + // Get query params from queryBuilder instance to ensure default values are applied + const params = queryBuilder.params() + + const apiPath = content.experimental.stripQueryParameters + ? withContentBase(`/navigation/${process.dev ? '_' : `${hash(params)}.${content.integrity}`}/${encodeQueryParams(params)}.json`) + : withContentBase(process.dev ? `/navigation/${hash(params)}` : `/navigation/${hash(params)}.${content.integrity}.json`) + + // Add `prefetch` to `` in production + if (!process.dev && process.server) { + addPrerenderPath(apiPath) + } + + if (shouldUseClientDB()) { + const generateNavigation = await import('./client-db').then(m => m.generateNavigation) + return generateNavigation(params) + } + + const data = await $fetch(apiPath as any, { + method: 'GET', + responseType: 'json', + params: content.experimental.stripQueryParameters + ? undefined + : { + _params: jsonStringify(params), + previewToken: useContentPreview().getPreviewToken() + } + }) + + // On SSG, all url are redirected to `404.html` when not found, so we need to check the content type + // to know if the response is a valid JSON or not + if (typeof data === 'string' && (data as string).startsWith('')) { + throw new Error('Not found') + } + + return data +}