refactor: remove fallback loader

This commit is contained in:
bholmesdev 2023-02-09 12:29:32 -05:00
parent 8beb9680cb
commit 57b36498fd

View file

@ -1,8 +1,9 @@
import * as devalue from 'devalue'; import * as devalue from 'devalue';
import type fsMod from 'node:fs'; import type fsMod from 'node:fs';
import { extname } from 'node:path';
import { pathToFileURL } from 'url'; import { pathToFileURL } from 'url';
import type { Plugin } from 'vite'; import type { Plugin } from 'vite';
import { AstroSettings } from '../@types/astro.js'; import { AstroSettings, ContentEntryType } from '../@types/astro.js';
import { AstroErrorData } from '../core/errors/errors-data.js'; import { AstroErrorData } from '../core/errors/errors-data.js';
import { AstroError } from '../core/errors/errors.js'; import { AstroError } from '../core/errors/errors.js';
import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js'; import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';
@ -34,6 +35,13 @@ export function astroContentImportPlugin({
const contentPaths = getContentPaths(settings.config, fs); const contentPaths = getContentPaths(settings.config, fs);
const contentEntryExts = getContentEntryExts(settings); const contentEntryExts = getContentEntryExts(settings);
const contentEntryExtToParser: Map<string, ContentEntryType> = new Map();
for (const entryType of settings.contentEntryTypes) {
for (const ext of entryType.extensions) {
contentEntryExtToParser.set(ext, entryType);
}
}
return { return {
name: 'astro:content-imports', name: 'astro:content-imports',
async load(id) { async load(id) {
@ -71,55 +79,48 @@ export function astroContentImportPlugin({
}); });
} }
const rawContents = await fs.promises.readFile(fileId, 'utf-8'); const rawContents = await fs.promises.readFile(fileId, 'utf-8');
const contentEntryType = settings.contentEntryTypes.find((entryType) => const fileExt = extname(fileId);
entryType.extensions.some((ext) => fileId.endsWith(ext)) if (!contentEntryExtToParser.has(fileExt)) {
); throw new AstroError({
let body: string, ...AstroErrorData.UnknownContentCollectionError,
unvalidatedData: Record<string, unknown>, message: `No parser found for content entry ${JSON.stringify(
unvalidatedSlug: string, fileId
rawData: string; )}. Did you apply an integration for this file type?`,
if (contentEntryType) {
const info = await contentEntryType.getEntryInfo({
fileUrl: pathToFileURL(fileId),
contents: rawContents,
}); });
body = info.body;
unvalidatedData = info.data;
unvalidatedSlug = info.slug;
rawData = info.rawData;
} else {
const parsed = parseFrontmatter(rawContents, fileId);
body = parsed.content;
unvalidatedData = parsed.data;
unvalidatedSlug = parsed.data.slug;
rawData = parsed.matter;
} }
const contentEntryParser = contentEntryExtToParser.get(fileExt)!;
const entryInfo = getEntryInfo({ const info = await contentEntryParser.getEntryInfo({
fileUrl: pathToFileURL(fileId),
contents: rawContents,
});
const generatedInfo = getEntryInfo({
entry: pathToFileURL(fileId), entry: pathToFileURL(fileId),
contentDir: contentPaths.contentDir, contentDir: contentPaths.contentDir,
}); });
if (entryInfo instanceof Error) return; if (generatedInfo instanceof Error) return;
const _internal = { filePath: fileId, rawData }; const _internal = { filePath: fileId, rawData: info.rawData };
// TODO: move slug calculation to the start of the build // TODO: move slug calculation to the start of the build
// to generate a performant lookup map for `getEntryBySlug` // to generate a performant lookup map for `getEntryBySlug`
const slug = getEntrySlug({ ...entryInfo, unvalidatedSlug }); const slug = getEntrySlug({ ...generatedInfo, unvalidatedSlug: info.slug });
const collectionConfig = contentConfig?.collections[entryInfo.collection]; const collectionConfig = contentConfig?.collections[generatedInfo.collection];
const data = collectionConfig const data = collectionConfig
? await getEntryData({ ...entryInfo, _internal, unvalidatedData }, collectionConfig) ? await getEntryData(
: unvalidatedData; { ...generatedInfo, _internal, unvalidatedData: info.data },
collectionConfig
)
: info.data;
const code = escapeViteEnvReferences(` const code = escapeViteEnvReferences(`
export const id = ${JSON.stringify(entryInfo.id)}; export const id = ${JSON.stringify(generatedInfo.id)};
export const collection = ${JSON.stringify(entryInfo.collection)}; export const collection = ${JSON.stringify(generatedInfo.collection)};
export const slug = ${JSON.stringify(slug)}; export const slug = ${JSON.stringify(slug)};
export const body = ${JSON.stringify(body)}; export const body = ${JSON.stringify(info.body)};
export const data = ${devalue.uneval(data) /* TODO: reuse astro props serializer */}; export const data = ${devalue.uneval(data) /* TODO: reuse astro props serializer */};
export const _internal = { export const _internal = {
filePath: ${JSON.stringify(fileId)}, filePath: ${JSON.stringify(_internal.filePath)},
rawData: ${JSON.stringify(unvalidatedData)}, rawData: ${JSON.stringify(_internal.rawData)},
}; };
`); `);
return { code }; return { code };