Support content collections with % in filename (#8684)
* Support content collections with % in filename * Add changeset * Unused eslint thing * Update packages/astro/src/core/build/static-build.ts Co-authored-by: Alexander Niebuhr <alexander@nbhr.io> --------- Co-authored-by: Alexander Niebuhr <alexander@nbhr.io>
This commit is contained in:
parent
0e35457c0f
commit
824dd4670a
6 changed files with 35 additions and 6 deletions
5
.changeset/quick-wolves-drive.md
Normal file
5
.changeset/quick-wolves-drive.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Support content collections with % in filename
|
|
@ -106,7 +106,8 @@ export async function createContentTypesGenerator({
|
|||
});
|
||||
|
||||
for (const entry of globResult) {
|
||||
const entryURL = new URL(entry.path, contentPaths.contentDir);
|
||||
const fullPath = path.join(fileURLToPath(contentPaths.contentDir), entry.path);
|
||||
const entryURL = pathToFileURL(fullPath);
|
||||
if (entryURL.href.startsWith(contentPaths.config.url.href)) continue;
|
||||
if (entry.dirent.isFile()) {
|
||||
events.push({
|
||||
|
|
|
@ -4,7 +4,7 @@ import glob from 'fast-glob';
|
|||
import { bgGreen, bgMagenta, black, dim } from 'kleur/colors';
|
||||
import fs from 'node:fs';
|
||||
import path, { extname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import * as vite from 'vite';
|
||||
import type { RouteData } from '../../@types/astro.js';
|
||||
import {
|
||||
|
@ -186,6 +186,17 @@ async function ssrBuild(
|
|||
const sanitizedName = name.split('.')[0];
|
||||
return `chunks/${sanitizedName}_[hash].mjs`;
|
||||
}
|
||||
// Detect if the chunk name has as % sign that is not encoded.
|
||||
// This is borrowed from Node core: https://github.com/nodejs/node/blob/3838b579e44bf0c2db43171c3ce0da51eb6b05d5/lib/internal/url.js#L1382-L1391
|
||||
// We do this because you cannot import a module with this character in it.
|
||||
for(let i = 0; i < name.length; i++) {
|
||||
if(name[i] === '%') {
|
||||
const third = name.codePointAt(i + 2)! | 0x20;
|
||||
if (name[i + 1] !== '2' || third !== 102) {
|
||||
return `chunks/${name.replace(/%/g, '_percent_')}_[hash].mjs`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return `chunks/[name]_[hash].mjs`;
|
||||
},
|
||||
assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
|
||||
|
@ -313,7 +324,8 @@ async function runPostBuildHooks(
|
|||
? build.server
|
||||
: build.client
|
||||
: config.outDir;
|
||||
const fileURL = new URL(fileName, root);
|
||||
const fullPath = path.join(fileURLToPath(root), fileName);
|
||||
const fileURL = pathToFileURL(fullPath);
|
||||
await fs.promises.mkdir(new URL('./', fileURL), { recursive: true });
|
||||
await fs.promises.writeFile(fileURL, mutation.code, 'utf-8');
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import matter from 'gray-matter';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
import type { Plugin } from 'vite';
|
||||
import { normalizePath } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
|
@ -76,9 +76,11 @@ export default function markdown({ settings, logger }: AstroPluginOptions): Plug
|
|||
const rawFile = await fs.promises.readFile(fileId, 'utf-8');
|
||||
const raw = safeMatter(rawFile, id);
|
||||
|
||||
const fileURL = pathToFileURL(fileId);
|
||||
|
||||
const renderResult = await processor
|
||||
.render(raw.content, {
|
||||
fileURL: new URL(`file://${fileId}`),
|
||||
fileURL,
|
||||
frontmatter: raw.data,
|
||||
})
|
||||
.catch((err) => {
|
||||
|
|
|
@ -54,12 +54,13 @@ describe('Content Collections', () => {
|
|||
|
||||
const ids = json.withSchemaConfig.map((item) => item.id);
|
||||
const publishedDates = json.withSchemaConfig.map((item) => item.data.publishedAt);
|
||||
expect(ids).to.deep.equal(['one.md', 'three.md', 'two.md']);
|
||||
expect(ids).to.deep.equal(['four%.md', 'one.md', 'three.md', 'two.md']);
|
||||
expect(publishedDates.every((date) => date instanceof Date)).to.equal(
|
||||
true,
|
||||
'Not all publishedAt dates are Date objects'
|
||||
);
|
||||
expect(publishedDates.map((date) => date.toISOString())).to.deep.equal([
|
||||
'2021-01-01T00:00:00.000Z',
|
||||
'2021-01-01T00:00:00.000Z',
|
||||
'2021-01-03T00:00:00.000Z',
|
||||
'2021-01-02T00:00:00.000Z',
|
||||
|
|
8
packages/astro/test/fixtures/content-collections/src/content/with-schema-config/four%.md
vendored
Normal file
8
packages/astro/test/fixtures/content-collections/src/content/with-schema-config/four%.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: Four
|
||||
description: The forth page
|
||||
lang: en
|
||||
publishedAt: 2021-01-01
|
||||
---
|
||||
|
||||
# It's the forth page, fancy!
|
Loading…
Reference in a new issue