summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/olive-rabbits-rhyme.md5
-rw-r--r--packages/astro/src/content/types-generator.ts18
-rw-r--r--packages/astro/src/content/vite-plugin-content-virtual-mod.ts8
-rw-r--r--packages/astro/test/units/dev/collections-mixed-content-errors.test.js28
4 files changed, 52 insertions, 7 deletions
diff --git a/.changeset/olive-rabbits-rhyme.md b/.changeset/olive-rabbits-rhyme.md
new file mode 100644
index 000000000..7720c1ed5
--- /dev/null
+++ b/.changeset/olive-rabbits-rhyme.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix content collection build errors for empty collections or underscore files of type `.json`.
diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts
index 0280fc08b..7958c330f 100644
--- a/packages/astro/src/content/types-generator.ts
+++ b/packages/astro/src/content/types-generator.ts
@@ -414,7 +414,11 @@ async function writeContentFiles({
for (const collectionKey of Object.keys(collectionEntryMap).sort()) {
const collectionConfig = contentConfig?.collections[JSON.parse(collectionKey)];
const collection = collectionEntryMap[collectionKey];
- if (collectionConfig?.type && collection.type !== collectionConfig.type) {
+ if (
+ collectionConfig?.type &&
+ collection.type !== 'unknown' &&
+ collection.type !== collectionConfig.type
+ ) {
viteServer.ws.send({
type: 'error',
err: new AstroError({
@@ -433,7 +437,14 @@ async function writeContentFiles({
});
return;
}
- switch (collection.type) {
+ const resolvedType: 'content' | 'data' =
+ collection.type === 'unknown'
+ ? // Add empty / unknown collections to the data type map by default
+ // This ensures `getCollection('empty-collection')` doesn't raise a type error
+ collectionConfig?.type ?? 'data'
+ : collection.type;
+
+ switch (resolvedType) {
case 'content':
contentTypesStr += `${collectionKey}: {\n`;
for (const entryKey of Object.keys(collection.entries).sort()) {
@@ -449,9 +460,6 @@ async function writeContentFiles({
contentTypesStr += `};\n`;
break;
case 'data':
- // Add empty / unknown collections to the data type map by default
- // This ensures `getCollection('empty-collection')` doesn't raise a type error
- case 'unknown':
dataTypesStr += `${collectionKey}: {\n`;
for (const entryKey of Object.keys(collection.entries).sort()) {
const dataType = collectionConfig?.schema ? `InferEntrySchema<${collectionKey}>` : 'any';
diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts
index 78a8cd24d..838d6b425 100644
--- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts
+++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts
@@ -43,8 +43,12 @@ export function astroContentVirtualModPlugin({
new URL('reference-map.json', contentPaths.cacheDir).pathname
)
.replace('@@CONTENT_DIR@@', relContentDir)
- .replace('@@CONTENT_ENTRY_GLOB_PATH@@', `${relContentDir}**/*${getExtGlob(contentEntryExts)}`)
- .replace('@@DATA_ENTRY_GLOB_PATH@@', `${relContentDir}**/*${getExtGlob(dataEntryExts)}`)
+ .replace(
+ '@@CONTENT_ENTRY_GLOB_PATH@@',
+ // [!_] = ignore files starting with "_"
+ `${relContentDir}**/[!_]*${getExtGlob(contentEntryExts)}`
+ )
+ .replace('@@DATA_ENTRY_GLOB_PATH@@', `${relContentDir}**/[!_]*${getExtGlob(dataEntryExts)}`)
.replace(
'@@RENDER_ENTRY_GLOB_PATH@@',
`${relContentDir}**/*${getExtGlob(/** Note: data collections excluded */ contentEntryExts)}`
diff --git a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
index 355f54a0f..d323946f8 100644
--- a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
+++ b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
@@ -119,4 +119,32 @@ title: Post
expect(e.hint).to.include("Try adding `type: 'data'`");
}
});
+
+ it('does not raise error for empty collection with config', async () => {
+ const fs = createFsWithFallback(
+ {
+ // Add placeholder to ensure directory exists
+ '/src/content/i18n/_placeholder.txt': 'Need content here',
+ '/src/content/config.ts': `
+ import { z, defineCollection } from 'astro:content';
+
+ const i18n = defineCollection({
+ type: 'data',
+ schema: z.object({
+ greeting: z.string(),
+ }),
+ });
+
+ export const collections = { i18n };`,
+ },
+ root
+ );
+
+ try {
+ const res = await sync({ fs });
+ expect(res).to.equal(0);
+ } catch (e) {
+ expect.fail(0, 1, `Did not expect sync to throw: ${e.message}`);
+ }
+ });
});