diff --git a/src/runtime/server/storage.ts b/src/runtime/server/storage.ts index 76cf0e204..0d4363e44 100644 --- a/src/runtime/server/storage.ts +++ b/src/runtime/server/storage.ts @@ -17,18 +17,34 @@ export const cacheParsedStorage = prefixStorage(useStorage(), 'cache:content:par const isProduction = process.env.NODE_ENV === 'production' const contentConfig = useRuntimeConfig().content + /** * Content ignore patterns */ -export const contentIgnores = contentConfig.ignores.map((p: any) => - typeof p === 'string' ? new RegExp(`^${p}`) : p +export const contentIgnores: Array = contentConfig.ignores.map((p: any) => + typeof p === 'string' ? new RegExp(`^${p}|:${p}`) : p ) +/** + * Invalid key characters + */ +const invalidKeyCharacters = "'\"?#/".split('') + /** * Filter predicate for ignore patterns */ -const contentIgnorePredicate = (key: string) => - !key.startsWith('preview:') && !contentIgnores.some((prefix: RegExp) => key.split(':').some(k => prefix.test(k))) +const contentIgnorePredicate = (key: string) => { + if (key.startsWith('preview:') || contentIgnores.some(prefix => prefix.test(key))) { + return false + } + if (invalidKeyCharacters.some(ik => key.includes(ik))) { + // eslint-disable-next-line no-console + console.warn(`Ignoring [${key}]. File name should not contain any of the following characters: ${invalidKeyCharacters.join(', ')}`) + return false + } + + return true +} export const getContentsIds = async (event: CompatibilityEvent, prefix?: string) => { let keys = [] diff --git a/test/basic.test.ts b/test/basic.test.ts index da14a5a3a..0fd542868 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -1,5 +1,5 @@ import { fileURLToPath } from 'url' -import { assert, test, describe, expect } from 'vitest' +import { assert, test, describe, expect, vi } from 'vitest' import { setup, $fetch } from '@nuxt/test-utils' import { hash } from 'ohash' import { testMarkdownParser } from './features/parser-markdown' @@ -15,6 +15,8 @@ import { testParserHooks } from './features/parser-hooks' import { testModuleOption } from './features/module-options' import { testContentQuery } from './features/content-query' +const spyConsoleWarn = vi.spyOn(global.console, 'warn') + describe('fixtures:basic', async () => { await setup({ rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)), @@ -106,6 +108,11 @@ describe('fixtures:basic', async () => { expect(html).contains('Content (v2)') }) + test('warn invalid file name', () => { + expect(spyConsoleWarn).toHaveBeenCalled() + expect(spyConsoleWarn).toHaveBeenCalledWith('Ignoring [content:with-\'invalid\'-char.md]. File name should not contain any of the following characters: \', ", ?, #, /') + }) + testContentQuery() testNavigation() diff --git a/test/fixtures/basic/content/with-'invalid'-char.md b/test/fixtures/basic/content/with-'invalid'-char.md new file mode 100644 index 000000000..7f7dca79b --- /dev/null +++ b/test/fixtures/basic/content/with-'invalid'-char.md @@ -0,0 +1 @@ +# This file's name is invalid \ No newline at end of file