fix(content): ensure underscore ignores only child paths of the content directory. (#6330)
* test: add test fixture * test: add cc config file * migrate to unit test instead * fix: only include child folders in ignore list * chore: changeset
This commit is contained in:
parent
5e86b011dc
commit
f91a7f376c
3 changed files with 81 additions and 54 deletions
5
.changeset/tiny-geckos-reply.md
Normal file
5
.changeset/tiny-geckos-reply.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Ensure prefixed underscore ignores only child paths of the content directory.
|
|
@ -160,12 +160,12 @@ export function getEntryInfo({
|
||||||
|
|
||||||
export function getEntryType(
|
export function getEntryType(
|
||||||
entryPath: string,
|
entryPath: string,
|
||||||
paths: Pick<ContentPaths, 'config'>
|
paths: Pick<ContentPaths, 'config' | 'contentDir'>
|
||||||
): 'content' | 'config' | 'ignored' | 'unsupported' {
|
): 'content' | 'config' | 'ignored' | 'unsupported' {
|
||||||
const { ext, base } = path.parse(entryPath);
|
const { ext, base } = path.parse(entryPath);
|
||||||
const fileUrl = pathToFileURL(entryPath);
|
const fileUrl = pathToFileURL(entryPath);
|
||||||
|
|
||||||
if (hasUnderscoreInPath(fileUrl) || isOnIgnoreList(base)) {
|
if (hasUnderscoreBelowContentDirectoryPath(fileUrl, paths.contentDir) || isOnIgnoreList(base)) {
|
||||||
return 'ignored';
|
return 'ignored';
|
||||||
} else if ((contentFileExts as readonly string[]).includes(ext)) {
|
} else if ((contentFileExts as readonly string[]).includes(ext)) {
|
||||||
return 'content';
|
return 'content';
|
||||||
|
@ -180,8 +180,11 @@ function isOnIgnoreList(fileName: string) {
|
||||||
return ['.DS_Store'].includes(fileName);
|
return ['.DS_Store'].includes(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasUnderscoreInPath(fileUrl: URL): boolean {
|
function hasUnderscoreBelowContentDirectoryPath(
|
||||||
const parts = fileUrl.pathname.split('/');
|
fileUrl: URL,
|
||||||
|
contentDir: ContentPaths['contentDir']
|
||||||
|
): boolean {
|
||||||
|
const parts = fileUrl.pathname.replace(contentDir.pathname, '').split('/');
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
if (part.startsWith('_')) return true;
|
if (part.startsWith('_')) return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,35 @@ import { getEntryType } from '../../../dist/content/utils.js';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
describe('Content Collections - getEntryType', () => {
|
const fixtures = [
|
||||||
const contentDir = new URL('src/content/', import.meta.url);
|
{
|
||||||
const contentPaths = {
|
title: 'Without any underscore above the content directory tree',
|
||||||
|
contentPaths: {
|
||||||
config: {
|
config: {
|
||||||
url: new URL('src/content/config.ts', import.meta.url),
|
url: new URL('src/content/config.ts', import.meta.url),
|
||||||
exists: true,
|
exists: true,
|
||||||
},
|
},
|
||||||
};
|
contentDir: new URL('src/content/', import.meta.url),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'With underscore levels above the content directory tree',
|
||||||
|
contentPaths: {
|
||||||
|
config: {
|
||||||
|
url: new URL('_src/content/config.ts', import.meta.url),
|
||||||
|
exists: true,
|
||||||
|
},
|
||||||
|
contentDir: new URL('_src/content/', import.meta.url),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('Content Collections - getEntryType', () => {
|
||||||
|
fixtures.forEach(({ title, contentPaths }) => {
|
||||||
|
describe(title, () => {
|
||||||
it('Returns "content" for Markdown files', () => {
|
it('Returns "content" for Markdown files', () => {
|
||||||
for (const entryPath of ['blog/first-post.md', 'blog/first-post.mdx']) {
|
for (const entryPath of ['blog/first-post.md', 'blog/first-post.mdx']) {
|
||||||
const entry = fileURLToPath(new URL(entryPath, contentDir));
|
const entry = fileURLToPath(new URL(entryPath, contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('content');
|
expect(type).to.equal('content');
|
||||||
}
|
}
|
||||||
|
@ -21,7 +38,7 @@ describe('Content Collections - getEntryType', () => {
|
||||||
|
|
||||||
it('Returns "content" for Markdown files in nested directories', () => {
|
it('Returns "content" for Markdown files in nested directories', () => {
|
||||||
for (const entryPath of ['blog/2021/01/01/index.md', 'blog/2021/01/01/index.mdx']) {
|
for (const entryPath of ['blog/2021/01/01/index.md', 'blog/2021/01/01/index.mdx']) {
|
||||||
const entry = fileURLToPath(new URL(entryPath, contentDir));
|
const entry = fileURLToPath(new URL(entryPath, contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('content');
|
expect(type).to.equal('content');
|
||||||
}
|
}
|
||||||
|
@ -34,32 +51,34 @@ describe('Content Collections - getEntryType', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns "unsupported" for non-Markdown files', () => {
|
it('Returns "unsupported" for non-Markdown files', () => {
|
||||||
const entry = fileURLToPath(new URL('blog/robots.txt', contentDir));
|
const entry = fileURLToPath(new URL('blog/robots.txt', contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('unsupported');
|
expect(type).to.equal('unsupported');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns "ignored" for .DS_Store', () => {
|
it('Returns "ignored" for .DS_Store', () => {
|
||||||
const entry = fileURLToPath(new URL('blog/.DS_Store', contentDir));
|
const entry = fileURLToPath(new URL('blog/.DS_Store', contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('ignored');
|
expect(type).to.equal('ignored');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns "ignored" for unsupported files using an underscore', () => {
|
it('Returns "ignored" for unsupported files using an underscore', () => {
|
||||||
const entry = fileURLToPath(new URL('blog/_draft-robots.txt', contentDir));
|
const entry = fileURLToPath(new URL('blog/_draft-robots.txt', contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('ignored');
|
expect(type).to.equal('ignored');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns "ignored" when using underscore on file name', () => {
|
it('Returns "ignored" when using underscore on file name', () => {
|
||||||
const entry = fileURLToPath(new URL('blog/_first-post.md', contentDir));
|
const entry = fileURLToPath(new URL('blog/_first-post.md', contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('ignored');
|
expect(type).to.equal('ignored');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns "ignored" when using underscore on directory name', () => {
|
it('Returns "ignored" when using underscore on directory name', () => {
|
||||||
const entry = fileURLToPath(new URL('blog/_draft/first-post.md', contentDir));
|
const entry = fileURLToPath(new URL('blog/_draft/first-post.md', contentPaths.contentDir));
|
||||||
const type = getEntryType(entry, contentPaths);
|
const type = getEntryType(entry, contentPaths);
|
||||||
expect(type).to.equal('ignored');
|
expect(type).to.equal('ignored');
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue