refactor: remove fallback loader
This commit is contained in:
parent
8beb9680cb
commit
57b36498fd
1 changed files with 36 additions and 35 deletions
|
@ -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 };
|
||||||
|
|
Loading…
Reference in a new issue