🎉 initiate project *astro_rewrite*
This commit is contained in:
parent
ffd4d5e86c
commit
2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions
10
node_modules/astro/dist/content/consts.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/content/consts.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
export declare const PROPAGATED_ASSET_FLAG = "astroPropagatedAssets";
|
||||
export declare const CONTENT_RENDER_FLAG = "astroRenderContent";
|
||||
export declare const CONTENT_FLAG = "astroContentCollectionEntry";
|
||||
export declare const DATA_FLAG = "astroDataCollectionEntry";
|
||||
export declare const VIRTUAL_MODULE_ID = "astro:content";
|
||||
export declare const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
|
||||
export declare const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
|
||||
export declare const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
|
||||
export declare const CONTENT_FLAGS: readonly ["astroContentCollectionEntry", "astroRenderContent", "astroDataCollectionEntry", "astroPropagatedAssets"];
|
||||
export declare const CONTENT_TYPES_FILE = "types.d.ts";
|
27
node_modules/astro/dist/content/consts.js
generated
vendored
Normal file
27
node_modules/astro/dist/content/consts.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
const PROPAGATED_ASSET_FLAG = "astroPropagatedAssets";
|
||||
const CONTENT_RENDER_FLAG = "astroRenderContent";
|
||||
const CONTENT_FLAG = "astroContentCollectionEntry";
|
||||
const DATA_FLAG = "astroDataCollectionEntry";
|
||||
const VIRTUAL_MODULE_ID = "astro:content";
|
||||
const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
|
||||
const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
|
||||
const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
|
||||
const CONTENT_FLAGS = [
|
||||
CONTENT_FLAG,
|
||||
CONTENT_RENDER_FLAG,
|
||||
DATA_FLAG,
|
||||
PROPAGATED_ASSET_FLAG
|
||||
];
|
||||
const CONTENT_TYPES_FILE = "types.d.ts";
|
||||
export {
|
||||
CONTENT_FLAG,
|
||||
CONTENT_FLAGS,
|
||||
CONTENT_RENDER_FLAG,
|
||||
CONTENT_TYPES_FILE,
|
||||
DATA_FLAG,
|
||||
LINKS_PLACEHOLDER,
|
||||
PROPAGATED_ASSET_FLAG,
|
||||
SCRIPTS_PLACEHOLDER,
|
||||
STYLES_PLACEHOLDER,
|
||||
VIRTUAL_MODULE_ID
|
||||
};
|
2
node_modules/astro/dist/content/error-map.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/content/error-map.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import type { ZodErrorMap } from 'zod';
|
||||
export declare const errorMap: ZodErrorMap;
|
78
node_modules/astro/dist/content/error-map.js
generated
vendored
Normal file
78
node_modules/astro/dist/content/error-map.js
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
const errorMap = (baseError, ctx) => {
|
||||
const baseErrorPath = flattenErrorPath(baseError.path);
|
||||
if (baseError.code === "invalid_union") {
|
||||
let typeOrLiteralErrByPath = /* @__PURE__ */ new Map();
|
||||
for (const unionError of baseError.unionErrors.map((e) => e.errors).flat()) {
|
||||
if (unionError.code === "invalid_type" || unionError.code === "invalid_literal") {
|
||||
const flattenedErrorPath = flattenErrorPath(unionError.path);
|
||||
if (typeOrLiteralErrByPath.has(flattenedErrorPath)) {
|
||||
typeOrLiteralErrByPath.get(flattenedErrorPath).expected.push(unionError.expected);
|
||||
} else {
|
||||
typeOrLiteralErrByPath.set(flattenedErrorPath, {
|
||||
code: unionError.code,
|
||||
received: unionError.received,
|
||||
expected: [unionError.expected]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let messages = [
|
||||
prefix(
|
||||
baseErrorPath,
|
||||
typeOrLiteralErrByPath.size ? "Did not match union:" : "Did not match union."
|
||||
)
|
||||
];
|
||||
return {
|
||||
message: messages.concat(
|
||||
[...typeOrLiteralErrByPath.entries()].filter(([, error]) => error.expected.length === baseError.unionErrors.length).map(
|
||||
([key, error]) => key === baseErrorPath ? (
|
||||
// Avoid printing the key again if it's a base error
|
||||
`> ${getTypeOrLiteralMsg(error)}`
|
||||
) : `> ${prefix(key, getTypeOrLiteralMsg(error))}`
|
||||
)
|
||||
).join("\n")
|
||||
};
|
||||
}
|
||||
if (baseError.code === "invalid_literal" || baseError.code === "invalid_type") {
|
||||
return {
|
||||
message: prefix(
|
||||
baseErrorPath,
|
||||
getTypeOrLiteralMsg({
|
||||
code: baseError.code,
|
||||
received: baseError.received,
|
||||
expected: [baseError.expected]
|
||||
})
|
||||
)
|
||||
};
|
||||
} else if (baseError.message) {
|
||||
return { message: prefix(baseErrorPath, baseError.message) };
|
||||
} else {
|
||||
return { message: prefix(baseErrorPath, ctx.defaultError) };
|
||||
}
|
||||
};
|
||||
const getTypeOrLiteralMsg = (error) => {
|
||||
if (error.received === "undefined")
|
||||
return "Required";
|
||||
const expectedDeduped = new Set(error.expected);
|
||||
switch (error.code) {
|
||||
case "invalid_type":
|
||||
return `Expected type \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
|
||||
error.received
|
||||
)}`;
|
||||
case "invalid_literal":
|
||||
return `Expected \`${unionExpectedVals(expectedDeduped)}\`, received ${JSON.stringify(
|
||||
error.received
|
||||
)}`;
|
||||
}
|
||||
};
|
||||
const prefix = (key, msg) => key.length ? `**${key}**: ${msg}` : msg;
|
||||
const unionExpectedVals = (expectedVals) => [...expectedVals].map((expectedVal, idx) => {
|
||||
if (idx === 0)
|
||||
return JSON.stringify(expectedVal);
|
||||
const sep = " | ";
|
||||
return `${sep}${JSON.stringify(expectedVal)}`;
|
||||
}).join("");
|
||||
const flattenErrorPath = (errorPath) => errorPath.join(".");
|
||||
export {
|
||||
errorMap
|
||||
};
|
8
node_modules/astro/dist/content/index.d.ts
generated
vendored
Normal file
8
node_modules/astro/dist/content/index.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
export { CONTENT_FLAG, PROPAGATED_ASSET_FLAG } from './consts.js';
|
||||
export { errorMap } from './error-map.js';
|
||||
export { attachContentServerListeners } from './server-listeners.js';
|
||||
export { createContentTypesGenerator } from './types-generator.js';
|
||||
export { contentObservable, getContentPaths, getDotAstroTypeReference } from './utils.js';
|
||||
export { astroContentAssetPropagationPlugin } from './vite-plugin-content-assets.js';
|
||||
export { astroContentImportPlugin } from './vite-plugin-content-imports.js';
|
||||
export { astroContentVirtualModPlugin } from './vite-plugin-content-virtual-mod.js';
|
21
node_modules/astro/dist/content/index.js
generated
vendored
Normal file
21
node_modules/astro/dist/content/index.js
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { CONTENT_FLAG, PROPAGATED_ASSET_FLAG } from "./consts.js";
|
||||
import { errorMap } from "./error-map.js";
|
||||
import { attachContentServerListeners } from "./server-listeners.js";
|
||||
import { createContentTypesGenerator } from "./types-generator.js";
|
||||
import { contentObservable, getContentPaths, getDotAstroTypeReference } from "./utils.js";
|
||||
import { astroContentAssetPropagationPlugin } from "./vite-plugin-content-assets.js";
|
||||
import { astroContentImportPlugin } from "./vite-plugin-content-imports.js";
|
||||
import { astroContentVirtualModPlugin } from "./vite-plugin-content-virtual-mod.js";
|
||||
export {
|
||||
CONTENT_FLAG,
|
||||
PROPAGATED_ASSET_FLAG,
|
||||
astroContentAssetPropagationPlugin,
|
||||
astroContentImportPlugin,
|
||||
astroContentVirtualModPlugin,
|
||||
attachContentServerListeners,
|
||||
contentObservable,
|
||||
createContentTypesGenerator,
|
||||
errorMap,
|
||||
getContentPaths,
|
||||
getDotAstroTypeReference
|
||||
};
|
3
node_modules/astro/dist/content/runtime-assets.d.ts
generated
vendored
Normal file
3
node_modules/astro/dist/content/runtime-assets.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
import type { PluginContext } from 'rollup';
|
||||
import { z } from 'zod';
|
||||
export declare function createImage(pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/types.js").ImageMetadata | z.ZodNever, string>;
|
27
node_modules/astro/dist/content/runtime-assets.js
generated
vendored
Normal file
27
node_modules/astro/dist/content/runtime-assets.js
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { z } from "zod";
|
||||
import { emitESMImage } from "../assets/utils/emitAsset.js";
|
||||
function createImage(pluginContext, entryFilePath) {
|
||||
return () => {
|
||||
return z.string().transform(async (imagePath, ctx) => {
|
||||
var _a;
|
||||
const resolvedFilePath = (_a = await pluginContext.resolve(imagePath, entryFilePath)) == null ? void 0 : _a.id;
|
||||
const metadata = await emitESMImage(
|
||||
resolvedFilePath,
|
||||
pluginContext.meta.watchMode,
|
||||
pluginContext.emitFile
|
||||
);
|
||||
if (!metadata) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `Image ${imagePath} does not exist. Is the path correct?`,
|
||||
fatal: true
|
||||
});
|
||||
return z.never();
|
||||
}
|
||||
return metadata;
|
||||
});
|
||||
};
|
||||
}
|
||||
export {
|
||||
createImage
|
||||
};
|
82
node_modules/astro/dist/content/runtime.d.ts
generated
vendored
Normal file
82
node_modules/astro/dist/content/runtime.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
import type { MarkdownHeading } from '@astrojs/markdown-remark';
|
||||
import { type AstroComponentFactory } from '../runtime/server/index.js';
|
||||
import type { ContentLookupMap } from './utils.js';
|
||||
type LazyImport = () => Promise<any>;
|
||||
type GlobResult = Record<string, LazyImport>;
|
||||
type CollectionToEntryMap = Record<string, GlobResult>;
|
||||
type GetEntryImport = (collection: string, lookupId: string) => Promise<LazyImport>;
|
||||
export declare function createCollectionToGlobResultMap({ globResult, contentDir, }: {
|
||||
globResult: GlobResult;
|
||||
contentDir: string;
|
||||
}): CollectionToEntryMap;
|
||||
export declare function createGetCollection({ contentCollectionToEntryMap, dataCollectionToEntryMap, getRenderEntryImport, }: {
|
||||
contentCollectionToEntryMap: CollectionToEntryMap;
|
||||
dataCollectionToEntryMap: CollectionToEntryMap;
|
||||
getRenderEntryImport: GetEntryImport;
|
||||
}): (collection: string, filter?: ((entry: any) => unknown) | undefined) => Promise<any[]>;
|
||||
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, }: {
|
||||
getEntryImport: GetEntryImport;
|
||||
getRenderEntryImport: GetEntryImport;
|
||||
}): (collection: string, slug: string) => Promise<{
|
||||
id: any;
|
||||
slug: any;
|
||||
body: any;
|
||||
collection: any;
|
||||
data: any;
|
||||
render(): Promise<RenderResult>;
|
||||
} | undefined>;
|
||||
export declare function createGetDataEntryById({ dataCollectionToEntryMap, }: {
|
||||
dataCollectionToEntryMap: CollectionToEntryMap;
|
||||
}): (collection: string, id: string) => Promise<{
|
||||
id: any;
|
||||
collection: any;
|
||||
data: any;
|
||||
}>;
|
||||
type ContentEntryResult = {
|
||||
id: string;
|
||||
slug: string;
|
||||
body: string;
|
||||
collection: string;
|
||||
data: Record<string, any>;
|
||||
render(): Promise<RenderResult>;
|
||||
};
|
||||
type DataEntryResult = {
|
||||
id: string;
|
||||
collection: string;
|
||||
data: Record<string, any>;
|
||||
};
|
||||
type EntryLookupObject = {
|
||||
collection: string;
|
||||
id: string;
|
||||
} | {
|
||||
collection: string;
|
||||
slug: string;
|
||||
};
|
||||
export declare function createGetEntry({ getEntryImport, getRenderEntryImport, }: {
|
||||
getEntryImport: GetEntryImport;
|
||||
getRenderEntryImport: GetEntryImport;
|
||||
}): (collectionOrLookupObject: string | EntryLookupObject, _lookupId?: string) => Promise<ContentEntryResult | DataEntryResult | undefined>;
|
||||
export declare function createGetEntries(getEntry: ReturnType<typeof createGetEntry>): (entries: {
|
||||
collection: string;
|
||||
id: string;
|
||||
}[] | {
|
||||
collection: string;
|
||||
slug: string;
|
||||
}[]) => Promise<(ContentEntryResult | DataEntryResult | undefined)[]>;
|
||||
type RenderResult = {
|
||||
Content: AstroComponentFactory;
|
||||
headings: MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
};
|
||||
export declare function createReference({ lookupMap }: {
|
||||
lookupMap: ContentLookupMap;
|
||||
}): (collection: string) => import("zod").ZodEffects<import("zod").ZodString, {
|
||||
slug: string;
|
||||
collection: string;
|
||||
id?: undefined;
|
||||
} | {
|
||||
id: string;
|
||||
collection: string;
|
||||
slug?: undefined;
|
||||
} | undefined, string>;
|
||||
export {};
|
302
node_modules/astro/dist/content/runtime.js
generated
vendored
Normal file
302
node_modules/astro/dist/content/runtime.js
generated
vendored
Normal file
|
@ -0,0 +1,302 @@
|
|||
import { string as zodString, ZodIssueCode } from "zod";
|
||||
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
||||
import { prependForwardSlash } from "../core/path.js";
|
||||
import {
|
||||
createComponent,
|
||||
createHeadAndContent,
|
||||
renderComponent,
|
||||
renderScriptElement,
|
||||
renderTemplate,
|
||||
renderUniqueStylesheet,
|
||||
unescapeHTML
|
||||
} from "../runtime/server/index.js";
|
||||
function createCollectionToGlobResultMap({
|
||||
globResult,
|
||||
contentDir
|
||||
}) {
|
||||
const collectionToGlobResultMap = {};
|
||||
for (const key in globResult) {
|
||||
const keyRelativeToContentDir = key.replace(new RegExp(`^${contentDir}`), "");
|
||||
const segments = keyRelativeToContentDir.split("/");
|
||||
if (segments.length <= 1)
|
||||
continue;
|
||||
const collection = segments[0];
|
||||
collectionToGlobResultMap[collection] ??= {};
|
||||
collectionToGlobResultMap[collection][key] = globResult[key];
|
||||
}
|
||||
return collectionToGlobResultMap;
|
||||
}
|
||||
const cacheEntriesByCollection = /* @__PURE__ */ new Map();
|
||||
function createGetCollection({
|
||||
contentCollectionToEntryMap,
|
||||
dataCollectionToEntryMap,
|
||||
getRenderEntryImport
|
||||
}) {
|
||||
return async function getCollection(collection, filter) {
|
||||
let type;
|
||||
if (collection in contentCollectionToEntryMap) {
|
||||
type = "content";
|
||||
} else if (collection in dataCollectionToEntryMap) {
|
||||
type = "data";
|
||||
} else {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.CollectionDoesNotExistError,
|
||||
message: AstroErrorData.CollectionDoesNotExistError.message(collection)
|
||||
});
|
||||
}
|
||||
const lazyImports = Object.values(
|
||||
type === "content" ? contentCollectionToEntryMap[collection] : dataCollectionToEntryMap[collection]
|
||||
);
|
||||
let entries = [];
|
||||
if (import.meta.env.PROD && cacheEntriesByCollection.has(collection)) {
|
||||
entries = cacheEntriesByCollection.get(collection);
|
||||
} else {
|
||||
entries = await Promise.all(
|
||||
lazyImports.map(async (lazyImport) => {
|
||||
const entry = await lazyImport();
|
||||
return type === "content" ? {
|
||||
id: entry.id,
|
||||
slug: entry.slug,
|
||||
body: entry.body,
|
||||
collection: entry.collection,
|
||||
data: entry.data,
|
||||
async render() {
|
||||
return render({
|
||||
collection: entry.collection,
|
||||
id: entry.id,
|
||||
renderEntryImport: await getRenderEntryImport(collection, entry.slug)
|
||||
});
|
||||
}
|
||||
} : {
|
||||
id: entry.id,
|
||||
collection: entry.collection,
|
||||
data: entry.data
|
||||
};
|
||||
})
|
||||
);
|
||||
cacheEntriesByCollection.set(collection, entries);
|
||||
}
|
||||
if (typeof filter === "function") {
|
||||
return entries.filter(filter);
|
||||
} else {
|
||||
return entries;
|
||||
}
|
||||
};
|
||||
}
|
||||
function createGetEntryBySlug({
|
||||
getEntryImport,
|
||||
getRenderEntryImport
|
||||
}) {
|
||||
return async function getEntryBySlug(collection, slug) {
|
||||
const entryImport = await getEntryImport(collection, slug);
|
||||
if (typeof entryImport !== "function")
|
||||
return void 0;
|
||||
const entry = await entryImport();
|
||||
return {
|
||||
id: entry.id,
|
||||
slug: entry.slug,
|
||||
body: entry.body,
|
||||
collection: entry.collection,
|
||||
data: entry.data,
|
||||
async render() {
|
||||
return render({
|
||||
collection: entry.collection,
|
||||
id: entry.id,
|
||||
renderEntryImport: await getRenderEntryImport(collection, slug)
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
function createGetDataEntryById({
|
||||
dataCollectionToEntryMap
|
||||
}) {
|
||||
return async function getDataEntryById(collection, id) {
|
||||
var _a;
|
||||
const lazyImport = (_a = dataCollectionToEntryMap[collection]) == null ? void 0 : _a[
|
||||
/*TODO: filePathToIdMap*/
|
||||
id + ".json"
|
||||
];
|
||||
if (!lazyImport)
|
||||
throw new Error(`Entry ${collection} \u2192 ${id} was not found.`);
|
||||
const entry = await lazyImport();
|
||||
return {
|
||||
id: entry.id,
|
||||
collection: entry.collection,
|
||||
data: entry.data
|
||||
};
|
||||
};
|
||||
}
|
||||
function createGetEntry({
|
||||
getEntryImport,
|
||||
getRenderEntryImport
|
||||
}) {
|
||||
return async function getEntry(collectionOrLookupObject, _lookupId) {
|
||||
let collection, lookupId;
|
||||
if (typeof collectionOrLookupObject === "string") {
|
||||
collection = collectionOrLookupObject;
|
||||
if (!_lookupId)
|
||||
throw new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: "`getEntry()` requires an entry identifier as the second argument."
|
||||
});
|
||||
lookupId = _lookupId;
|
||||
} else {
|
||||
collection = collectionOrLookupObject.collection;
|
||||
lookupId = "id" in collectionOrLookupObject ? collectionOrLookupObject.id : collectionOrLookupObject.slug;
|
||||
}
|
||||
const entryImport = await getEntryImport(collection, lookupId);
|
||||
if (typeof entryImport !== "function")
|
||||
return void 0;
|
||||
const entry = await entryImport();
|
||||
if (entry._internal.type === "content") {
|
||||
return {
|
||||
id: entry.id,
|
||||
slug: entry.slug,
|
||||
body: entry.body,
|
||||
collection: entry.collection,
|
||||
data: entry.data,
|
||||
async render() {
|
||||
return render({
|
||||
collection: entry.collection,
|
||||
id: entry.id,
|
||||
renderEntryImport: await getRenderEntryImport(collection, lookupId)
|
||||
});
|
||||
}
|
||||
};
|
||||
} else if (entry._internal.type === "data") {
|
||||
return {
|
||||
id: entry.id,
|
||||
collection: entry.collection,
|
||||
data: entry.data
|
||||
};
|
||||
}
|
||||
return void 0;
|
||||
};
|
||||
}
|
||||
function createGetEntries(getEntry) {
|
||||
return async function getEntries(entries) {
|
||||
return Promise.all(entries.map((e) => getEntry(e)));
|
||||
};
|
||||
}
|
||||
async function render({
|
||||
collection,
|
||||
id,
|
||||
renderEntryImport
|
||||
}) {
|
||||
var _a, _b;
|
||||
const UnexpectedRenderError = new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: `Unexpected error while rendering ${String(collection)} \u2192 ${String(id)}.`
|
||||
});
|
||||
if (typeof renderEntryImport !== "function")
|
||||
throw UnexpectedRenderError;
|
||||
const baseMod = await renderEntryImport();
|
||||
if (baseMod == null || typeof baseMod !== "object")
|
||||
throw UnexpectedRenderError;
|
||||
const { default: defaultMod } = baseMod;
|
||||
if (isPropagatedAssetsModule(defaultMod)) {
|
||||
const { collectedStyles, collectedLinks, collectedScripts, getMod } = defaultMod;
|
||||
if (typeof getMod !== "function")
|
||||
throw UnexpectedRenderError;
|
||||
const propagationMod = await getMod();
|
||||
if (propagationMod == null || typeof propagationMod !== "object")
|
||||
throw UnexpectedRenderError;
|
||||
const Content = createComponent({
|
||||
factory(result, baseProps, slots) {
|
||||
let styles = "", links = "", scripts = "";
|
||||
if (Array.isArray(collectedStyles)) {
|
||||
styles = collectedStyles.map((style) => {
|
||||
return renderUniqueStylesheet(result, {
|
||||
type: "inline",
|
||||
content: style
|
||||
});
|
||||
}).join("");
|
||||
}
|
||||
if (Array.isArray(collectedLinks)) {
|
||||
links = collectedLinks.map((link) => {
|
||||
return renderUniqueStylesheet(result, {
|
||||
type: "external",
|
||||
src: prependForwardSlash(link)
|
||||
});
|
||||
}).join("");
|
||||
}
|
||||
if (Array.isArray(collectedScripts)) {
|
||||
scripts = collectedScripts.map((script) => renderScriptElement(script)).join("");
|
||||
}
|
||||
let props = baseProps;
|
||||
if (id.endsWith("mdx")) {
|
||||
props = {
|
||||
components: propagationMod.components ?? {},
|
||||
...baseProps
|
||||
};
|
||||
}
|
||||
return createHeadAndContent(
|
||||
unescapeHTML(styles + links + scripts),
|
||||
renderTemplate`${renderComponent(
|
||||
result,
|
||||
"Content",
|
||||
propagationMod.Content,
|
||||
props,
|
||||
slots
|
||||
)}`
|
||||
);
|
||||
},
|
||||
propagation: "self"
|
||||
});
|
||||
return {
|
||||
Content,
|
||||
headings: ((_a = propagationMod.getHeadings) == null ? void 0 : _a.call(propagationMod)) ?? [],
|
||||
remarkPluginFrontmatter: propagationMod.frontmatter ?? {}
|
||||
};
|
||||
} else if (baseMod.Content && typeof baseMod.Content === "function") {
|
||||
return {
|
||||
Content: baseMod.Content,
|
||||
headings: ((_b = baseMod.getHeadings) == null ? void 0 : _b.call(baseMod)) ?? [],
|
||||
remarkPluginFrontmatter: baseMod.frontmatter ?? {}
|
||||
};
|
||||
} else {
|
||||
throw UnexpectedRenderError;
|
||||
}
|
||||
}
|
||||
function createReference({ lookupMap }) {
|
||||
return function reference(collection) {
|
||||
return zodString().transform((lookupId, ctx) => {
|
||||
const flattenedErrorPath = ctx.path.join(".");
|
||||
if (!lookupMap[collection]) {
|
||||
ctx.addIssue({
|
||||
code: ZodIssueCode.custom,
|
||||
message: `**${flattenedErrorPath}:** Reference to ${collection} invalid. Collection does not exist or is empty.`
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { type, entries } = lookupMap[collection];
|
||||
const entry = entries[lookupId];
|
||||
if (!entry) {
|
||||
ctx.addIssue({
|
||||
code: ZodIssueCode.custom,
|
||||
message: `**${flattenedErrorPath}**: Reference to ${collection} invalid. Expected ${Object.keys(
|
||||
entries
|
||||
).map((c) => JSON.stringify(c)).join(" | ")}. Received ${JSON.stringify(lookupId)}.`
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (type === "content") {
|
||||
return { slug: lookupId, collection };
|
||||
}
|
||||
return { id: lookupId, collection };
|
||||
});
|
||||
};
|
||||
}
|
||||
function isPropagatedAssetsModule(module) {
|
||||
return typeof module === "object" && module != null && "__astroPropagation" in module;
|
||||
}
|
||||
export {
|
||||
createCollectionToGlobResultMap,
|
||||
createGetCollection,
|
||||
createGetDataEntryById,
|
||||
createGetEntries,
|
||||
createGetEntry,
|
||||
createGetEntryBySlug,
|
||||
createReference
|
||||
};
|
13
node_modules/astro/dist/content/server-listeners.d.ts
generated
vendored
Normal file
13
node_modules/astro/dist/content/server-listeners.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/// <reference types="node" />
|
||||
import type fsMod from 'node:fs';
|
||||
import type { ViteDevServer } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { type LogOptions } from '../core/logger/core.js';
|
||||
interface ContentServerListenerParams {
|
||||
fs: typeof fsMod;
|
||||
logging: LogOptions;
|
||||
settings: AstroSettings;
|
||||
viteServer: ViteDevServer;
|
||||
}
|
||||
export declare function attachContentServerListeners({ viteServer, fs, logging, settings, }: ContentServerListenerParams): Promise<void>;
|
||||
export {};
|
109
node_modules/astro/dist/content/server-listeners.js
generated
vendored
Normal file
109
node_modules/astro/dist/content/server-listeners.js
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
import { bold, cyan } from "kleur/colors";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { loadTSConfig } from "../core/config/tsconfig.js";
|
||||
import { info, warn } from "../core/logger/core.js";
|
||||
import { appendForwardSlash } from "../core/path.js";
|
||||
import { createContentTypesGenerator } from "./types-generator.js";
|
||||
import { getContentPaths, globalContentConfigObserver } from "./utils.js";
|
||||
async function attachContentServerListeners({
|
||||
viteServer,
|
||||
fs,
|
||||
logging,
|
||||
settings
|
||||
}) {
|
||||
const contentPaths = getContentPaths(settings.config, fs);
|
||||
if (fs.existsSync(contentPaths.contentDir)) {
|
||||
info(
|
||||
logging,
|
||||
"content",
|
||||
`Watching ${cyan(
|
||||
contentPaths.contentDir.href.replace(settings.config.root.href, "")
|
||||
)} for changes`
|
||||
);
|
||||
const maybeTsConfigStats = getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings });
|
||||
if (maybeTsConfigStats)
|
||||
warnAllowJsIsFalse({ ...maybeTsConfigStats, logging });
|
||||
await attachListeners();
|
||||
} else {
|
||||
viteServer.watcher.on("addDir", contentDirListener);
|
||||
async function contentDirListener(dir) {
|
||||
if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) {
|
||||
info(logging, "content", `Content dir found. Watching for changes`);
|
||||
await attachListeners();
|
||||
viteServer.watcher.removeListener("addDir", contentDirListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
async function attachListeners() {
|
||||
const contentGenerator = await createContentTypesGenerator({
|
||||
fs,
|
||||
settings,
|
||||
logging,
|
||||
viteServer,
|
||||
contentConfigObserver: globalContentConfigObserver
|
||||
});
|
||||
await contentGenerator.init();
|
||||
info(logging, "content", "Types generated");
|
||||
viteServer.watcher.on("add", (entry) => {
|
||||
contentGenerator.queueEvent({ name: "add", entry });
|
||||
});
|
||||
viteServer.watcher.on(
|
||||
"addDir",
|
||||
(entry) => contentGenerator.queueEvent({ name: "addDir", entry })
|
||||
);
|
||||
viteServer.watcher.on(
|
||||
"change",
|
||||
(entry) => contentGenerator.queueEvent({ name: "change", entry })
|
||||
);
|
||||
viteServer.watcher.on("unlink", (entry) => {
|
||||
contentGenerator.queueEvent({ name: "unlink", entry });
|
||||
});
|
||||
viteServer.watcher.on(
|
||||
"unlinkDir",
|
||||
(entry) => contentGenerator.queueEvent({ name: "unlinkDir", entry })
|
||||
);
|
||||
}
|
||||
}
|
||||
function warnAllowJsIsFalse({
|
||||
logging,
|
||||
tsConfigFileName,
|
||||
contentConfigFileName
|
||||
}) {
|
||||
if (!["info", "warn"].includes(logging.level))
|
||||
warn(
|
||||
logging,
|
||||
"content",
|
||||
`Make sure you have the ${bold("allowJs")} compiler option set to ${bold(
|
||||
"true"
|
||||
)} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold(
|
||||
contentConfigFileName
|
||||
)} file.
|
||||
See ${bold("https://www.typescriptlang.org/tsconfig#allowJs")} for more information.
|
||||
`
|
||||
);
|
||||
}
|
||||
function getTSConfigStatsWhenAllowJsFalse({
|
||||
contentPaths,
|
||||
settings
|
||||
}) {
|
||||
var _a, _b;
|
||||
const isContentConfigJsFile = [".js", ".mjs"].some(
|
||||
(ext) => contentPaths.config.url.pathname.endsWith(ext)
|
||||
);
|
||||
if (!isContentConfigJsFile)
|
||||
return;
|
||||
const inputConfig = loadTSConfig(fileURLToPath(settings.config.root), false);
|
||||
const tsConfigFileName = inputConfig.exists && inputConfig.path.split(path.sep).pop();
|
||||
if (!tsConfigFileName)
|
||||
return;
|
||||
const contentConfigFileName = contentPaths.config.url.pathname.split(path.sep).pop();
|
||||
const allowJSOption = (_b = (_a = inputConfig == null ? void 0 : inputConfig.config) == null ? void 0 : _a.compilerOptions) == null ? void 0 : _b.allowJs;
|
||||
const hasAllowJs = allowJSOption === true || tsConfigFileName === "jsconfig.json" && allowJSOption !== false;
|
||||
if (hasAllowJs)
|
||||
return;
|
||||
return { tsConfigFileName, contentConfigFileName };
|
||||
}
|
||||
export {
|
||||
attachContentServerListeners
|
||||
};
|
32
node_modules/astro/dist/content/types-generator.d.ts
generated
vendored
Normal file
32
node_modules/astro/dist/content/types-generator.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/// <reference types="node" />
|
||||
import type fsMod from 'node:fs';
|
||||
import { type ViteDevServer } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { type LogOptions } from '../core/logger/core.js';
|
||||
import { type ContentObservable } from './utils.js';
|
||||
type ChokidarEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir';
|
||||
type RawContentEvent = {
|
||||
name: ChokidarEvent;
|
||||
entry: string;
|
||||
};
|
||||
type CreateContentGeneratorParams = {
|
||||
contentConfigObserver: ContentObservable;
|
||||
logging: LogOptions;
|
||||
settings: AstroSettings;
|
||||
/** This is required for loading the content config */
|
||||
viteServer: ViteDevServer;
|
||||
fs: typeof fsMod;
|
||||
};
|
||||
type EventOpts = {
|
||||
logLevel: 'info' | 'warn';
|
||||
};
|
||||
export declare function createContentTypesGenerator({ contentConfigObserver, fs, logging, settings, viteServer, }: CreateContentGeneratorParams): Promise<{
|
||||
init: () => Promise<{
|
||||
typesGenerated: true;
|
||||
} | {
|
||||
typesGenerated: false;
|
||||
reason: 'no-content-dir';
|
||||
}>;
|
||||
queueEvent: (rawEvent: RawContentEvent, opts?: EventOpts) => void;
|
||||
}>;
|
||||
export {};
|
440
node_modules/astro/dist/content/types-generator.js
generated
vendored
Normal file
440
node_modules/astro/dist/content/types-generator.js
generated
vendored
Normal file
|
@ -0,0 +1,440 @@
|
|||
import glob from "fast-glob";
|
||||
import { cyan } from "kleur/colors";
|
||||
import * as path from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { normalizePath } from "vite";
|
||||
import { AstroErrorData } from "../core/errors/errors-data.js";
|
||||
import { AstroError } from "../core/errors/errors.js";
|
||||
import { info, warn } from "../core/logger/core.js";
|
||||
import { isRelativePath } from "../core/path.js";
|
||||
import { CONTENT_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
|
||||
import {
|
||||
getContentEntryIdAndSlug,
|
||||
getContentPaths,
|
||||
getDataEntryExts,
|
||||
getDataEntryId,
|
||||
getEntryCollectionName,
|
||||
getEntryConfigByExtMap,
|
||||
getEntrySlug,
|
||||
getEntryType,
|
||||
reloadContentConfigObserver
|
||||
} from "./utils.js";
|
||||
class UnsupportedFileTypeError extends Error {
|
||||
}
|
||||
async function createContentTypesGenerator({
|
||||
contentConfigObserver,
|
||||
fs,
|
||||
logging,
|
||||
settings,
|
||||
viteServer
|
||||
}) {
|
||||
const collectionEntryMap = {};
|
||||
const contentPaths = getContentPaths(settings.config, fs);
|
||||
const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
|
||||
const contentEntryExts = [...contentEntryConfigByExt.keys()];
|
||||
const dataEntryExts = getDataEntryExts(settings);
|
||||
let events = [];
|
||||
let debounceTimeout;
|
||||
const typeTemplateContent = await fs.promises.readFile(contentPaths.typesTemplate, "utf-8");
|
||||
async function init() {
|
||||
if (!fs.existsSync(contentPaths.contentDir)) {
|
||||
return { typesGenerated: false, reason: "no-content-dir" };
|
||||
}
|
||||
events.push({
|
||||
type: { name: "add", entry: contentPaths.config.url },
|
||||
opts: { logLevel: "warn" }
|
||||
});
|
||||
const globResult = await glob("**", {
|
||||
cwd: fileURLToPath(contentPaths.contentDir),
|
||||
fs: {
|
||||
readdir: fs.readdir.bind(fs),
|
||||
readdirSync: fs.readdirSync.bind(fs)
|
||||
},
|
||||
onlyFiles: false,
|
||||
objectMode: true
|
||||
});
|
||||
for (const entry of globResult) {
|
||||
const entryURL = new URL(entry.path, contentPaths.contentDir);
|
||||
if (entryURL.href.startsWith(contentPaths.config.url.href))
|
||||
continue;
|
||||
if (entry.dirent.isFile()) {
|
||||
events.push({
|
||||
type: { name: "add", entry: entryURL },
|
||||
opts: { logLevel: "warn" }
|
||||
});
|
||||
} else if (entry.dirent.isDirectory()) {
|
||||
events.push({ type: { name: "addDir", entry: entryURL }, opts: { logLevel: "warn" } });
|
||||
}
|
||||
}
|
||||
await runEvents();
|
||||
return { typesGenerated: true };
|
||||
}
|
||||
async function handleEvent(event, opts) {
|
||||
const logLevel = (opts == null ? void 0 : opts.logLevel) ?? "info";
|
||||
if (event.name === "addDir" || event.name === "unlinkDir") {
|
||||
const collection2 = normalizePath(
|
||||
path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry))
|
||||
);
|
||||
const collectionKey2 = JSON.stringify(collection2);
|
||||
const isCollectionEvent = collection2.split("/").length === 1;
|
||||
if (!isCollectionEvent)
|
||||
return { shouldGenerateTypes: false };
|
||||
switch (event.name) {
|
||||
case "addDir":
|
||||
collectionEntryMap[JSON.stringify(collection2)] = { type: "unknown", entries: {} };
|
||||
if (logLevel === "info") {
|
||||
info(logging, "content", `${cyan(collection2)} collection added`);
|
||||
}
|
||||
break;
|
||||
case "unlinkDir":
|
||||
if (collectionKey2 in collectionEntryMap) {
|
||||
delete collectionEntryMap[JSON.stringify(collection2)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return { shouldGenerateTypes: true };
|
||||
}
|
||||
const fileType = getEntryType(
|
||||
fileURLToPath(event.entry),
|
||||
contentPaths,
|
||||
contentEntryExts,
|
||||
dataEntryExts,
|
||||
settings.config.experimental.assets
|
||||
);
|
||||
if (fileType === "ignored") {
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
if (fileType === "config") {
|
||||
await reloadContentConfigObserver({ fs, settings, viteServer });
|
||||
return { shouldGenerateTypes: true };
|
||||
}
|
||||
if (fileType === "unsupported") {
|
||||
if (event.name === "unlink") {
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
const { id: id2 } = getContentEntryIdAndSlug({
|
||||
entry: event.entry,
|
||||
contentDir: contentPaths.contentDir,
|
||||
collection: ""
|
||||
});
|
||||
return {
|
||||
shouldGenerateTypes: false,
|
||||
error: new UnsupportedFileTypeError(id2)
|
||||
};
|
||||
}
|
||||
const { entry } = event;
|
||||
const { contentDir } = contentPaths;
|
||||
const collection = getEntryCollectionName({ entry, contentDir });
|
||||
if (collection === void 0) {
|
||||
if (["info", "warn"].includes(logLevel)) {
|
||||
warn(
|
||||
logging,
|
||||
"content",
|
||||
`${cyan(
|
||||
normalizePath(
|
||||
path.relative(fileURLToPath(contentPaths.contentDir), fileURLToPath(event.entry))
|
||||
)
|
||||
)} must be nested in a collection directory. Skipping.`
|
||||
);
|
||||
}
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
if (fileType === "data") {
|
||||
const id2 = getDataEntryId({ entry, contentDir, collection });
|
||||
const collectionKey2 = JSON.stringify(collection);
|
||||
const entryKey2 = JSON.stringify(id2);
|
||||
switch (event.name) {
|
||||
case "add":
|
||||
if (!(collectionKey2 in collectionEntryMap)) {
|
||||
collectionEntryMap[collectionKey2] = { type: "data", entries: {} };
|
||||
}
|
||||
const collectionInfo2 = collectionEntryMap[collectionKey2];
|
||||
if (collectionInfo2.type === "content") {
|
||||
viteServer.ws.send({
|
||||
type: "error",
|
||||
err: new AstroError({
|
||||
...AstroErrorData.MixedContentDataCollectionError,
|
||||
message: AstroErrorData.MixedContentDataCollectionError.message(collectionKey2),
|
||||
location: { file: entry.pathname }
|
||||
})
|
||||
});
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
if (!(entryKey2 in collectionEntryMap[collectionKey2])) {
|
||||
collectionEntryMap[collectionKey2] = {
|
||||
type: "data",
|
||||
entries: { ...collectionInfo2.entries, [entryKey2]: {} }
|
||||
};
|
||||
}
|
||||
return { shouldGenerateTypes: true };
|
||||
case "unlink":
|
||||
if (collectionKey2 in collectionEntryMap && entryKey2 in collectionEntryMap[collectionKey2].entries) {
|
||||
delete collectionEntryMap[collectionKey2].entries[entryKey2];
|
||||
}
|
||||
return { shouldGenerateTypes: true };
|
||||
case "change":
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
}
|
||||
const contentEntryType = contentEntryConfigByExt.get(path.extname(event.entry.pathname));
|
||||
if (!contentEntryType)
|
||||
return { shouldGenerateTypes: false };
|
||||
const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ entry, contentDir, collection });
|
||||
const collectionKey = JSON.stringify(collection);
|
||||
if (!(collectionKey in collectionEntryMap)) {
|
||||
collectionEntryMap[collectionKey] = { type: "content", entries: {} };
|
||||
}
|
||||
const collectionInfo = collectionEntryMap[collectionKey];
|
||||
if (collectionInfo.type === "data") {
|
||||
viteServer.ws.send({
|
||||
type: "error",
|
||||
err: new AstroError({
|
||||
...AstroErrorData.MixedContentDataCollectionError,
|
||||
message: AstroErrorData.MixedContentDataCollectionError.message(collectionKey),
|
||||
location: { file: entry.pathname }
|
||||
})
|
||||
});
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
const entryKey = JSON.stringify(id);
|
||||
switch (event.name) {
|
||||
case "add":
|
||||
const addedSlug = await getEntrySlug({
|
||||
generatedSlug,
|
||||
id,
|
||||
collection,
|
||||
fileUrl: event.entry,
|
||||
contentEntryType,
|
||||
fs
|
||||
});
|
||||
if (!(entryKey in collectionEntryMap[collectionKey].entries)) {
|
||||
collectionEntryMap[collectionKey] = {
|
||||
type: "content",
|
||||
entries: { ...collectionInfo.entries, [entryKey]: { slug: addedSlug } }
|
||||
};
|
||||
}
|
||||
return { shouldGenerateTypes: true };
|
||||
case "unlink":
|
||||
if (collectionKey in collectionEntryMap && entryKey in collectionEntryMap[collectionKey].entries) {
|
||||
delete collectionEntryMap[collectionKey].entries[entryKey];
|
||||
}
|
||||
return { shouldGenerateTypes: true };
|
||||
case "change":
|
||||
const changedSlug = await getEntrySlug({
|
||||
generatedSlug,
|
||||
id,
|
||||
collection,
|
||||
fileUrl: event.entry,
|
||||
contentEntryType,
|
||||
fs
|
||||
});
|
||||
const entryMetadata = collectionInfo.entries[entryKey];
|
||||
if ((entryMetadata == null ? void 0 : entryMetadata.slug) !== changedSlug) {
|
||||
collectionInfo.entries[entryKey].slug = changedSlug;
|
||||
return { shouldGenerateTypes: true };
|
||||
}
|
||||
return { shouldGenerateTypes: false };
|
||||
}
|
||||
}
|
||||
function queueEvent(rawEvent, opts) {
|
||||
const event = {
|
||||
type: {
|
||||
entry: pathToFileURL(rawEvent.entry),
|
||||
name: rawEvent.name
|
||||
},
|
||||
opts
|
||||
};
|
||||
if (!event.type.entry.pathname.startsWith(contentPaths.contentDir.pathname))
|
||||
return;
|
||||
events.push(event);
|
||||
debounceTimeout && clearTimeout(debounceTimeout);
|
||||
const runEventsSafe = async () => {
|
||||
try {
|
||||
await runEvents(opts);
|
||||
} catch {
|
||||
}
|
||||
};
|
||||
debounceTimeout = setTimeout(
|
||||
runEventsSafe,
|
||||
50
|
||||
/* debounce to batch chokidar events */
|
||||
);
|
||||
}
|
||||
async function runEvents(opts) {
|
||||
const logLevel = (opts == null ? void 0 : opts.logLevel) ?? "info";
|
||||
const eventResponses = [];
|
||||
for (const event of events) {
|
||||
const response = await handleEvent(event.type, event.opts);
|
||||
eventResponses.push(response);
|
||||
}
|
||||
events = [];
|
||||
let unsupportedFiles = [];
|
||||
for (const response of eventResponses) {
|
||||
if (response.error instanceof UnsupportedFileTypeError) {
|
||||
unsupportedFiles.push(response.error.message);
|
||||
}
|
||||
}
|
||||
if (unsupportedFiles.length > 0 && ["info", "warn"].includes(logLevel)) {
|
||||
warn(
|
||||
logging,
|
||||
"content",
|
||||
`Unsupported file types found. Prefix with an underscore (\`_\`) to ignore:
|
||||
- ${unsupportedFiles.join(
|
||||
"\n"
|
||||
)}`
|
||||
);
|
||||
}
|
||||
const observable = contentConfigObserver.get();
|
||||
if (eventResponses.some((r) => r.shouldGenerateTypes)) {
|
||||
await writeContentFiles({
|
||||
fs,
|
||||
collectionEntryMap,
|
||||
contentPaths,
|
||||
typeTemplateContent,
|
||||
contentConfig: observable.status === "loaded" ? observable.config : void 0,
|
||||
contentEntryTypes: settings.contentEntryTypes,
|
||||
viteServer
|
||||
});
|
||||
invalidateVirtualMod(viteServer);
|
||||
if (observable.status === "loaded" && ["info", "warn"].includes(logLevel)) {
|
||||
warnNonexistentCollections({
|
||||
logging,
|
||||
contentConfig: observable.config,
|
||||
collectionEntryMap
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return { init, queueEvent };
|
||||
}
|
||||
function invalidateVirtualMod(viteServer) {
|
||||
const virtualMod = viteServer.moduleGraph.getModuleById("\0" + VIRTUAL_MODULE_ID);
|
||||
if (!virtualMod)
|
||||
return;
|
||||
viteServer.moduleGraph.invalidateModule(virtualMod);
|
||||
}
|
||||
async function writeContentFiles({
|
||||
fs,
|
||||
contentPaths,
|
||||
collectionEntryMap,
|
||||
typeTemplateContent,
|
||||
contentEntryTypes,
|
||||
contentConfig,
|
||||
viteServer
|
||||
}) {
|
||||
let contentTypesStr = "";
|
||||
let dataTypesStr = "";
|
||||
for (const collectionKey of Object.keys(collectionEntryMap).sort()) {
|
||||
const collectionConfig = contentConfig == null ? void 0 : contentConfig.collections[JSON.parse(collectionKey)];
|
||||
const collection = collectionEntryMap[collectionKey];
|
||||
if ((collectionConfig == null ? void 0 : collectionConfig.type) && collection.type !== "unknown" && collection.type !== collectionConfig.type) {
|
||||
viteServer.ws.send({
|
||||
type: "error",
|
||||
err: new AstroError({
|
||||
...AstroErrorData.ContentCollectionTypeMismatchError,
|
||||
message: AstroErrorData.ContentCollectionTypeMismatchError.message(
|
||||
collectionKey,
|
||||
collection.type,
|
||||
collectionConfig.type
|
||||
),
|
||||
hint: collection.type === "data" ? "Try adding `type: 'data'` to your collection config." : void 0,
|
||||
location: {
|
||||
file: ""
|
||||
/** required for error overlay `ws` messages */
|
||||
}
|
||||
})
|
||||
});
|
||||
return;
|
||||
}
|
||||
const resolvedType = 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 == null ? void 0 : collectionConfig.type) ?? "data"
|
||||
) : collection.type;
|
||||
switch (resolvedType) {
|
||||
case "content":
|
||||
contentTypesStr += `${collectionKey}: {
|
||||
`;
|
||||
for (const entryKey of Object.keys(collection.entries).sort()) {
|
||||
const entryMetadata = collection.entries[entryKey];
|
||||
const dataType = (collectionConfig == null ? void 0 : collectionConfig.schema) ? `InferEntrySchema<${collectionKey}>` : "any";
|
||||
const renderType = `{ render(): Render[${JSON.stringify(
|
||||
path.extname(JSON.parse(entryKey))
|
||||
)}] }`;
|
||||
const slugType = JSON.stringify(entryMetadata.slug);
|
||||
contentTypesStr += `${entryKey}: {
|
||||
id: ${entryKey};
|
||||
slug: ${slugType};
|
||||
body: string;
|
||||
collection: ${collectionKey};
|
||||
data: ${dataType}
|
||||
} & ${renderType};
|
||||
`;
|
||||
}
|
||||
contentTypesStr += `};
|
||||
`;
|
||||
break;
|
||||
case "data":
|
||||
dataTypesStr += `${collectionKey}: {
|
||||
`;
|
||||
for (const entryKey of Object.keys(collection.entries).sort()) {
|
||||
const dataType = (collectionConfig == null ? void 0 : collectionConfig.schema) ? `InferEntrySchema<${collectionKey}>` : "any";
|
||||
dataTypesStr += `${entryKey}: {
|
||||
id: ${entryKey};
|
||||
collection: ${collectionKey};
|
||||
data: ${dataType}
|
||||
};
|
||||
`;
|
||||
}
|
||||
dataTypesStr += `};
|
||||
`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!fs.existsSync(contentPaths.cacheDir)) {
|
||||
fs.mkdirSync(contentPaths.cacheDir, { recursive: true });
|
||||
}
|
||||
let configPathRelativeToCacheDir = normalizePath(
|
||||
path.relative(contentPaths.cacheDir.pathname, contentPaths.config.url.pathname)
|
||||
);
|
||||
if (!isRelativePath(configPathRelativeToCacheDir))
|
||||
configPathRelativeToCacheDir = "./" + configPathRelativeToCacheDir;
|
||||
if (configPathRelativeToCacheDir.endsWith(".ts")) {
|
||||
configPathRelativeToCacheDir = configPathRelativeToCacheDir.replace(/\.ts$/, "");
|
||||
}
|
||||
for (const contentEntryType of contentEntryTypes) {
|
||||
if (contentEntryType.contentModuleTypes) {
|
||||
typeTemplateContent = contentEntryType.contentModuleTypes + "\n" + typeTemplateContent;
|
||||
}
|
||||
}
|
||||
typeTemplateContent = typeTemplateContent.replace("// @@CONTENT_ENTRY_MAP@@", contentTypesStr);
|
||||
typeTemplateContent = typeTemplateContent.replace("// @@DATA_ENTRY_MAP@@", dataTypesStr);
|
||||
typeTemplateContent = typeTemplateContent.replace(
|
||||
"'@@CONTENT_CONFIG_TYPE@@'",
|
||||
contentConfig ? `typeof import(${JSON.stringify(configPathRelativeToCacheDir)})` : "never"
|
||||
);
|
||||
await fs.promises.writeFile(
|
||||
new URL(CONTENT_TYPES_FILE, contentPaths.cacheDir),
|
||||
typeTemplateContent
|
||||
);
|
||||
}
|
||||
function warnNonexistentCollections({
|
||||
contentConfig,
|
||||
collectionEntryMap,
|
||||
logging
|
||||
}) {
|
||||
for (const configuredCollection in contentConfig.collections) {
|
||||
if (!collectionEntryMap[JSON.stringify(configuredCollection)]) {
|
||||
warn(
|
||||
logging,
|
||||
"content",
|
||||
`The ${JSON.stringify(
|
||||
configuredCollection
|
||||
)} collection does not have an associated folder in your \`content\` directory. Make sure the folder exists, or check your content config for typos.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
createContentTypesGenerator
|
||||
};
|
186
node_modules/astro/dist/content/utils.d.ts
generated
vendored
Normal file
186
node_modules/astro/dist/content/utils.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
/// <reference types="node" />
|
||||
import matter from 'gray-matter';
|
||||
import fsMod from 'node:fs';
|
||||
import type { PluginContext } from 'rollup';
|
||||
import { type ViteDevServer } from 'vite';
|
||||
import { z } from 'zod';
|
||||
import type { AstroConfig, AstroSettings, ContentEntryType, DataEntryType } from '../@types/astro.js';
|
||||
import { CONTENT_FLAGS } from './consts.js';
|
||||
/**
|
||||
* Amap from a collection + slug to the local file path.
|
||||
* This is used internally to resolve entry imports when using `getEntry()`.
|
||||
* @see `content-module.template.mjs`
|
||||
*/
|
||||
export type ContentLookupMap = {
|
||||
[collectionName: string]: {
|
||||
type: 'content' | 'data';
|
||||
entries: {
|
||||
[lookupId: string]: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
export declare const collectionConfigParser: z.ZodUnion<[z.ZodObject<{
|
||||
type: z.ZodDefault<z.ZodOptional<z.ZodLiteral<"content">>>;
|
||||
schema: z.ZodOptional<z.ZodAny>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
schema?: any;
|
||||
type: "content";
|
||||
}, {
|
||||
type?: "content" | undefined;
|
||||
schema?: any;
|
||||
}>, z.ZodObject<{
|
||||
type: z.ZodLiteral<"data">;
|
||||
schema: z.ZodOptional<z.ZodAny>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}, {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}>]>;
|
||||
export declare function getDotAstroTypeReference({ root, srcDir }: {
|
||||
root: URL;
|
||||
srcDir: URL;
|
||||
}): string;
|
||||
export declare const contentConfigParser: z.ZodObject<{
|
||||
collections: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
||||
type: z.ZodDefault<z.ZodOptional<z.ZodLiteral<"content">>>;
|
||||
schema: z.ZodOptional<z.ZodAny>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
schema?: any;
|
||||
type: "content";
|
||||
}, {
|
||||
type?: "content" | undefined;
|
||||
schema?: any;
|
||||
}>, z.ZodObject<{
|
||||
type: z.ZodLiteral<"data">;
|
||||
schema: z.ZodOptional<z.ZodAny>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}, {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}>]>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
collections: Record<string, {
|
||||
schema?: any;
|
||||
type: "content";
|
||||
} | {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}>;
|
||||
}, {
|
||||
collections: Record<string, {
|
||||
type?: "content" | undefined;
|
||||
schema?: any;
|
||||
} | {
|
||||
schema?: any;
|
||||
type: "data";
|
||||
}>;
|
||||
}>;
|
||||
export type CollectionConfig = z.infer<typeof collectionConfigParser>;
|
||||
export type ContentConfig = z.infer<typeof contentConfigParser>;
|
||||
type EntryInternal = {
|
||||
rawData: string | undefined;
|
||||
filePath: string;
|
||||
};
|
||||
export declare const msg: {
|
||||
collectionConfigMissing: (collection: string) => string;
|
||||
};
|
||||
export declare function parseEntrySlug({ id, collection, generatedSlug, frontmatterSlug, }: {
|
||||
id: string;
|
||||
collection: string;
|
||||
generatedSlug: string;
|
||||
frontmatterSlug?: unknown;
|
||||
}): string;
|
||||
export declare function getEntryData(entry: {
|
||||
id: string;
|
||||
collection: string;
|
||||
unvalidatedData: Record<string, unknown>;
|
||||
_internal: EntryInternal;
|
||||
}, collectionConfig: CollectionConfig, pluginContext: PluginContext, config: AstroConfig): Promise<any>;
|
||||
export declare function getContentEntryExts(settings: Pick<AstroSettings, 'contentEntryTypes'>): string[];
|
||||
export declare function getDataEntryExts(settings: Pick<AstroSettings, 'dataEntryTypes'>): string[];
|
||||
export declare function getEntryConfigByExtMap<TEntryType extends ContentEntryType | DataEntryType>(entryTypes: TEntryType[]): Map<string, TEntryType>;
|
||||
export declare function getEntryCollectionName({ contentDir, entry, }: Pick<ContentPaths, 'contentDir'> & {
|
||||
entry: string | URL;
|
||||
}): string | undefined;
|
||||
export declare function getDataEntryId({ entry, contentDir, collection, }: Pick<ContentPaths, 'contentDir'> & {
|
||||
entry: URL;
|
||||
collection: string;
|
||||
}): string;
|
||||
export declare function getContentEntryIdAndSlug({ entry, contentDir, collection, }: Pick<ContentPaths, 'contentDir'> & {
|
||||
entry: URL;
|
||||
collection: string;
|
||||
}): {
|
||||
id: string;
|
||||
slug: string;
|
||||
};
|
||||
export declare function getEntryType(entryPath: string, paths: Pick<ContentPaths, 'config' | 'contentDir'>, contentFileExts: string[], dataFileExts: string[], experimentalAssets?: boolean): 'content' | 'data' | 'config' | 'ignored' | 'unsupported';
|
||||
export declare function hasUnderscoreBelowContentDirectoryPath(fileUrl: URL, contentDir: ContentPaths['contentDir']): boolean;
|
||||
export declare function parseFrontmatter(fileContents: string): matter.GrayMatterFile<string>;
|
||||
/**
|
||||
* The content config is loaded separately from other `src/` files.
|
||||
* This global observable lets dependent plugins (like the content flag plugin)
|
||||
* subscribe to changes during dev server updates.
|
||||
*/
|
||||
export declare const globalContentConfigObserver: ContentObservable;
|
||||
export declare function hasContentFlag(viteId: string, flag: (typeof CONTENT_FLAGS)[number]): boolean;
|
||||
export declare function loadContentConfig({ fs, settings, viteServer, }: {
|
||||
fs: typeof fsMod;
|
||||
settings: AstroSettings;
|
||||
viteServer: ViteDevServer;
|
||||
}): Promise<ContentConfig | undefined>;
|
||||
export declare function reloadContentConfigObserver({ observer, ...loadContentConfigOpts }: {
|
||||
fs: typeof fsMod;
|
||||
settings: AstroSettings;
|
||||
viteServer: ViteDevServer;
|
||||
observer?: ContentObservable;
|
||||
}): Promise<void>;
|
||||
type ContentCtx = {
|
||||
status: 'init';
|
||||
} | {
|
||||
status: 'loading';
|
||||
} | {
|
||||
status: 'does-not-exist';
|
||||
} | {
|
||||
status: 'loaded';
|
||||
config: ContentConfig;
|
||||
} | {
|
||||
status: 'error';
|
||||
error: Error;
|
||||
};
|
||||
type Observable<C> = {
|
||||
get: () => C;
|
||||
set: (ctx: C) => void;
|
||||
subscribe: (fn: (ctx: C) => void) => () => void;
|
||||
};
|
||||
export type ContentObservable = Observable<ContentCtx>;
|
||||
export declare function contentObservable(initialCtx: ContentCtx): ContentObservable;
|
||||
export type ContentPaths = {
|
||||
contentDir: URL;
|
||||
assetsDir: URL;
|
||||
cacheDir: URL;
|
||||
typesTemplate: URL;
|
||||
virtualModTemplate: URL;
|
||||
config: {
|
||||
exists: boolean;
|
||||
url: URL;
|
||||
};
|
||||
};
|
||||
export declare function getContentPaths({ srcDir, root }: Pick<AstroConfig, 'root' | 'srcDir'>, fs?: typeof fsMod): ContentPaths;
|
||||
/**
|
||||
* Check for slug in content entry frontmatter and validate the type,
|
||||
* falling back to the `generatedSlug` if none is found.
|
||||
*/
|
||||
export declare function getEntrySlug({ id, collection, generatedSlug, contentEntryType, fileUrl, fs, }: {
|
||||
fs: typeof fsMod;
|
||||
id: string;
|
||||
collection: string;
|
||||
generatedSlug: string;
|
||||
fileUrl: URL;
|
||||
contentEntryType: Pick<ContentEntryType, 'getEntryInfo'>;
|
||||
}): Promise<string>;
|
||||
export declare function getExtGlob(exts: string[]): string;
|
||||
export {};
|
362
node_modules/astro/dist/content/utils.js
generated
vendored
Normal file
362
node_modules/astro/dist/content/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,362 @@
|
|||
import { slug as githubSlug } from "github-slugger";
|
||||
import matter from "gray-matter";
|
||||
import fsMod from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { normalizePath } from "vite";
|
||||
import { z } from "zod";
|
||||
import { VALID_INPUT_FORMATS } from "../assets/consts.js";
|
||||
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
||||
import { formatYAMLException, isYAMLException } from "../core/errors/utils.js";
|
||||
import { CONTENT_TYPES_FILE } from "./consts.js";
|
||||
import { errorMap } from "./error-map.js";
|
||||
import { createImage } from "./runtime-assets.js";
|
||||
const collectionConfigParser = z.union([
|
||||
z.object({
|
||||
type: z.literal("content").optional().default("content"),
|
||||
schema: z.any().optional()
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("data"),
|
||||
schema: z.any().optional()
|
||||
})
|
||||
]);
|
||||
function getDotAstroTypeReference({ root, srcDir }) {
|
||||
const { cacheDir } = getContentPaths({ root, srcDir });
|
||||
const contentTypesRelativeToSrcDir = normalizePath(
|
||||
path.relative(fileURLToPath(srcDir), fileURLToPath(new URL(CONTENT_TYPES_FILE, cacheDir)))
|
||||
);
|
||||
return `/// <reference path=${JSON.stringify(contentTypesRelativeToSrcDir)} />`;
|
||||
}
|
||||
const contentConfigParser = z.object({
|
||||
collections: z.record(collectionConfigParser)
|
||||
});
|
||||
const msg = {
|
||||
collectionConfigMissing: (collection) => `${collection} does not have a config. We suggest adding one for type safety!`
|
||||
};
|
||||
function parseEntrySlug({
|
||||
id,
|
||||
collection,
|
||||
generatedSlug,
|
||||
frontmatterSlug
|
||||
}) {
|
||||
try {
|
||||
return z.string().default(generatedSlug).parse(frontmatterSlug);
|
||||
} catch {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.InvalidContentEntrySlugError,
|
||||
message: AstroErrorData.InvalidContentEntrySlugError.message(collection, id)
|
||||
});
|
||||
}
|
||||
}
|
||||
async function getEntryData(entry, collectionConfig, pluginContext, config) {
|
||||
let data;
|
||||
if (collectionConfig.type === "data") {
|
||||
data = entry.unvalidatedData;
|
||||
} else {
|
||||
const { slug, ...unvalidatedData } = entry.unvalidatedData;
|
||||
data = unvalidatedData;
|
||||
}
|
||||
let schema = collectionConfig.schema;
|
||||
if (typeof schema === "function") {
|
||||
if (!config.experimental.assets) {
|
||||
throw new Error(
|
||||
"The function shape for schema can only be used when `experimental.assets` is enabled."
|
||||
);
|
||||
}
|
||||
schema = schema({
|
||||
image: createImage(pluginContext, entry._internal.filePath)
|
||||
});
|
||||
}
|
||||
if (schema) {
|
||||
if (collectionConfig.type === "content" && typeof schema === "object" && "shape" in schema && schema.shape.slug) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ContentSchemaContainsSlugError,
|
||||
message: AstroErrorData.ContentSchemaContainsSlugError.message(entry.collection)
|
||||
});
|
||||
}
|
||||
let formattedError;
|
||||
const parsed = await schema.safeParseAsync(entry.unvalidatedData, {
|
||||
errorMap(error, ctx) {
|
||||
var _a, _b;
|
||||
if (error.code === "custom" && ((_a = error.params) == null ? void 0 : _a.isHoistedAstroError)) {
|
||||
formattedError = (_b = error.params) == null ? void 0 : _b.astroError;
|
||||
}
|
||||
return errorMap(error, ctx);
|
||||
}
|
||||
});
|
||||
if (parsed.success) {
|
||||
data = parsed.data;
|
||||
} else {
|
||||
if (!formattedError) {
|
||||
formattedError = new AstroError({
|
||||
...AstroErrorData.InvalidContentEntryFrontmatterError,
|
||||
message: AstroErrorData.InvalidContentEntryFrontmatterError.message(
|
||||
entry.collection,
|
||||
entry.id,
|
||||
parsed.error
|
||||
),
|
||||
location: {
|
||||
file: entry._internal.filePath,
|
||||
line: getYAMLErrorLine(entry._internal.rawData, String(parsed.error.errors[0].path[0])),
|
||||
column: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
throw formattedError;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
function getContentEntryExts(settings) {
|
||||
return settings.contentEntryTypes.map((t) => t.extensions).flat();
|
||||
}
|
||||
function getDataEntryExts(settings) {
|
||||
return settings.dataEntryTypes.map((t) => t.extensions).flat();
|
||||
}
|
||||
function getEntryConfigByExtMap(entryTypes) {
|
||||
const map = /* @__PURE__ */ new Map();
|
||||
for (const entryType of entryTypes) {
|
||||
for (const ext of entryType.extensions) {
|
||||
map.set(ext, entryType);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function getEntryCollectionName({
|
||||
contentDir,
|
||||
entry
|
||||
}) {
|
||||
const entryPath = typeof entry === "string" ? entry : fileURLToPath(entry);
|
||||
const rawRelativePath = path.relative(fileURLToPath(contentDir), entryPath);
|
||||
const collectionName = path.dirname(rawRelativePath).split(path.sep)[0];
|
||||
const isOutsideCollection = !collectionName || collectionName === "" || collectionName === ".." || collectionName === ".";
|
||||
if (isOutsideCollection) {
|
||||
return void 0;
|
||||
}
|
||||
return collectionName;
|
||||
}
|
||||
function getDataEntryId({
|
||||
entry,
|
||||
contentDir,
|
||||
collection
|
||||
}) {
|
||||
const relativePath = getRelativeEntryPath(entry, collection, contentDir);
|
||||
const withoutFileExt = relativePath.replace(new RegExp(path.extname(relativePath) + "$"), "");
|
||||
return withoutFileExt;
|
||||
}
|
||||
function getContentEntryIdAndSlug({
|
||||
entry,
|
||||
contentDir,
|
||||
collection
|
||||
}) {
|
||||
const relativePath = getRelativeEntryPath(entry, collection, contentDir);
|
||||
const withoutFileExt = relativePath.replace(new RegExp(path.extname(relativePath) + "$"), "");
|
||||
const rawSlugSegments = withoutFileExt.split(path.sep);
|
||||
const slug = rawSlugSegments.map((segment) => githubSlug(segment)).join("/").replace(/\/index$/, "");
|
||||
const res = {
|
||||
id: normalizePath(relativePath),
|
||||
slug
|
||||
};
|
||||
return res;
|
||||
}
|
||||
function getRelativeEntryPath(entry, collection, contentDir) {
|
||||
const relativeToContent = path.relative(fileURLToPath(contentDir), fileURLToPath(entry));
|
||||
const relativeToCollection = path.relative(collection, relativeToContent);
|
||||
return relativeToCollection;
|
||||
}
|
||||
function getEntryType(entryPath, paths, contentFileExts, dataFileExts, experimentalAssets = false) {
|
||||
const { ext, base } = path.parse(entryPath);
|
||||
const fileUrl = pathToFileURL(entryPath);
|
||||
if (hasUnderscoreBelowContentDirectoryPath(fileUrl, paths.contentDir) || isOnIgnoreList(base) || experimentalAssets && isImageAsset(ext)) {
|
||||
return "ignored";
|
||||
} else if (contentFileExts.includes(ext)) {
|
||||
return "content";
|
||||
} else if (dataFileExts.includes(ext)) {
|
||||
return "data";
|
||||
} else if (fileUrl.href === paths.config.url.href) {
|
||||
return "config";
|
||||
} else {
|
||||
return "unsupported";
|
||||
}
|
||||
}
|
||||
function isOnIgnoreList(fileName) {
|
||||
return [".DS_Store"].includes(fileName);
|
||||
}
|
||||
function isImageAsset(fileExt) {
|
||||
return VALID_INPUT_FORMATS.includes(fileExt.slice(1));
|
||||
}
|
||||
function hasUnderscoreBelowContentDirectoryPath(fileUrl, contentDir) {
|
||||
const parts = fileUrl.pathname.replace(contentDir.pathname, "").split("/");
|
||||
for (const part of parts) {
|
||||
if (part.startsWith("_"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getYAMLErrorLine(rawData, objectKey) {
|
||||
if (!rawData)
|
||||
return 0;
|
||||
const indexOfObjectKey = rawData.search(
|
||||
// Match key either at the top of the file or after a newline
|
||||
// Ensures matching on top-level object keys only
|
||||
new RegExp(`(
|
||||
|^)${objectKey}`)
|
||||
);
|
||||
if (indexOfObjectKey === -1)
|
||||
return 0;
|
||||
const dataBeforeKey = rawData.substring(0, indexOfObjectKey + 1);
|
||||
const numNewlinesBeforeKey = dataBeforeKey.split("\n").length;
|
||||
return numNewlinesBeforeKey;
|
||||
}
|
||||
function parseFrontmatter(fileContents) {
|
||||
try {
|
||||
matter.clearCache();
|
||||
return matter(fileContents);
|
||||
} catch (e) {
|
||||
if (isYAMLException(e)) {
|
||||
throw formatYAMLException(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
const globalContentConfigObserver = contentObservable({ status: "init" });
|
||||
function hasContentFlag(viteId, flag) {
|
||||
const flags = new URLSearchParams(viteId.split("?")[1] ?? "");
|
||||
return flags.has(flag);
|
||||
}
|
||||
async function loadContentConfig({
|
||||
fs,
|
||||
settings,
|
||||
viteServer
|
||||
}) {
|
||||
const contentPaths = getContentPaths(settings.config, fs);
|
||||
let unparsedConfig;
|
||||
if (!contentPaths.config.exists) {
|
||||
return void 0;
|
||||
}
|
||||
const configPathname = fileURLToPath(contentPaths.config.url);
|
||||
unparsedConfig = await viteServer.ssrLoadModule(configPathname);
|
||||
const config = contentConfigParser.safeParse(unparsedConfig);
|
||||
if (config.success) {
|
||||
return config.data;
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
async function reloadContentConfigObserver({
|
||||
observer = globalContentConfigObserver,
|
||||
...loadContentConfigOpts
|
||||
}) {
|
||||
observer.set({ status: "loading" });
|
||||
try {
|
||||
const config = await loadContentConfig(loadContentConfigOpts);
|
||||
if (config) {
|
||||
observer.set({ status: "loaded", config });
|
||||
} else {
|
||||
observer.set({ status: "does-not-exist" });
|
||||
}
|
||||
} catch (e) {
|
||||
observer.set({
|
||||
status: "error",
|
||||
error: e instanceof Error ? e : new AstroError(AstroErrorData.UnknownContentCollectionError)
|
||||
});
|
||||
}
|
||||
}
|
||||
function contentObservable(initialCtx) {
|
||||
const subscribers = /* @__PURE__ */ new Set();
|
||||
let ctx = initialCtx;
|
||||
function get() {
|
||||
return ctx;
|
||||
}
|
||||
function set(_ctx) {
|
||||
ctx = _ctx;
|
||||
subscribers.forEach((fn) => fn(ctx));
|
||||
}
|
||||
function subscribe(fn) {
|
||||
subscribers.add(fn);
|
||||
return () => {
|
||||
subscribers.delete(fn);
|
||||
};
|
||||
}
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
subscribe
|
||||
};
|
||||
}
|
||||
function getContentPaths({ srcDir, root }, fs = fsMod) {
|
||||
const configStats = search(fs, srcDir);
|
||||
const pkgBase = new URL("../../", import.meta.url);
|
||||
return {
|
||||
cacheDir: new URL(".astro/", root),
|
||||
contentDir: new URL("./content/", srcDir),
|
||||
assetsDir: new URL("./assets/", srcDir),
|
||||
typesTemplate: new URL("content-types.template.d.ts", pkgBase),
|
||||
virtualModTemplate: new URL("content-module.template.mjs", pkgBase),
|
||||
config: configStats
|
||||
};
|
||||
}
|
||||
function search(fs, srcDir) {
|
||||
const paths = ["config.mjs", "config.js", "config.ts"].map(
|
||||
(p) => new URL(`./content/${p}`, srcDir)
|
||||
);
|
||||
for (const file of paths) {
|
||||
if (fs.existsSync(file)) {
|
||||
return { exists: true, url: file };
|
||||
}
|
||||
}
|
||||
return { exists: false, url: paths[0] };
|
||||
}
|
||||
async function getEntrySlug({
|
||||
id,
|
||||
collection,
|
||||
generatedSlug,
|
||||
contentEntryType,
|
||||
fileUrl,
|
||||
fs
|
||||
}) {
|
||||
let contents;
|
||||
try {
|
||||
contents = await fs.promises.readFile(fileUrl, "utf-8");
|
||||
} catch (e) {
|
||||
throw new AstroError(AstroErrorData.UnknownContentCollectionError, { cause: e });
|
||||
}
|
||||
const { slug: frontmatterSlug } = await contentEntryType.getEntryInfo({
|
||||
fileUrl,
|
||||
contents
|
||||
});
|
||||
return parseEntrySlug({ generatedSlug, frontmatterSlug, id, collection });
|
||||
}
|
||||
function getExtGlob(exts) {
|
||||
return exts.length === 1 ? (
|
||||
// Wrapping {...} breaks when there is only one extension
|
||||
exts[0]
|
||||
) : `{${exts.join(",")}}`;
|
||||
}
|
||||
export {
|
||||
collectionConfigParser,
|
||||
contentConfigParser,
|
||||
contentObservable,
|
||||
getContentEntryExts,
|
||||
getContentEntryIdAndSlug,
|
||||
getContentPaths,
|
||||
getDataEntryExts,
|
||||
getDataEntryId,
|
||||
getDotAstroTypeReference,
|
||||
getEntryCollectionName,
|
||||
getEntryConfigByExtMap,
|
||||
getEntryData,
|
||||
getEntrySlug,
|
||||
getEntryType,
|
||||
getExtGlob,
|
||||
globalContentConfigObserver,
|
||||
hasContentFlag,
|
||||
hasUnderscoreBelowContentDirectoryPath,
|
||||
loadContentConfig,
|
||||
msg,
|
||||
parseEntrySlug,
|
||||
parseFrontmatter,
|
||||
reloadContentConfigObserver
|
||||
};
|
10
node_modules/astro/dist/content/vite-plugin-content-assets.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/content/vite-plugin-content-assets.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import type { Plugin } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
import { type BuildInternals } from '../core/build/internal.js';
|
||||
import type { AstroBuildPlugin } from '../core/build/plugin.js';
|
||||
import type { StaticBuildOptions } from '../core/build/types';
|
||||
export declare function astroContentAssetPropagationPlugin({ mode, settings, }: {
|
||||
mode: string;
|
||||
settings: AstroSettings;
|
||||
}): Plugin;
|
||||
export declare function astroConfigBuildPlugin(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
|
192
node_modules/astro/dist/content/vite-plugin-content-assets.js
generated
vendored
Normal file
192
node_modules/astro/dist/content/vite-plugin-content-assets.js
generated
vendored
Normal file
|
@ -0,0 +1,192 @@
|
|||
import { extname } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
|
||||
import { getPageDataByViteID } from "../core/build/internal.js";
|
||||
import { createViteLoader } from "../core/module-loader/vite.js";
|
||||
import { joinPaths, prependForwardSlash } from "../core/path.js";
|
||||
import { getStylesForURL } from "../core/render/dev/css.js";
|
||||
import { getScriptsForURL } from "../core/render/dev/scripts.js";
|
||||
import {
|
||||
CONTENT_RENDER_FLAG,
|
||||
LINKS_PLACEHOLDER,
|
||||
PROPAGATED_ASSET_FLAG,
|
||||
SCRIPTS_PLACEHOLDER,
|
||||
STYLES_PLACEHOLDER
|
||||
} from "./consts.js";
|
||||
import { hasContentFlag } from "./utils.js";
|
||||
function astroContentAssetPropagationPlugin({
|
||||
mode,
|
||||
settings
|
||||
}) {
|
||||
let devModuleLoader;
|
||||
return {
|
||||
name: "astro:content-asset-propagation",
|
||||
enforce: "pre",
|
||||
async resolveId(id, importer, opts) {
|
||||
if (hasContentFlag(id, CONTENT_RENDER_FLAG)) {
|
||||
const base = id.split("?")[0];
|
||||
for (const { extensions, handlePropagation = true } of settings.contentEntryTypes) {
|
||||
if (handlePropagation && extensions.includes(extname(base))) {
|
||||
return this.resolve(`${base}?${PROPAGATED_ASSET_FLAG}`, importer, {
|
||||
skipSelf: true,
|
||||
...opts
|
||||
});
|
||||
}
|
||||
}
|
||||
return this.resolve(base, importer, { skipSelf: true, ...opts });
|
||||
}
|
||||
},
|
||||
configureServer(server) {
|
||||
if (mode === "dev") {
|
||||
devModuleLoader = createViteLoader(server);
|
||||
}
|
||||
},
|
||||
async transform(_, id, options) {
|
||||
var _a;
|
||||
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
|
||||
const basePath = id.split("?")[0];
|
||||
let stringifiedLinks, stringifiedStyles, stringifiedScripts;
|
||||
if ((options == null ? void 0 : options.ssr) && devModuleLoader) {
|
||||
if (!((_a = devModuleLoader.getModuleById(basePath)) == null ? void 0 : _a.ssrModule)) {
|
||||
await devModuleLoader.import(basePath);
|
||||
}
|
||||
const { stylesMap, urls } = await getStylesForURL(
|
||||
pathToFileURL(basePath),
|
||||
devModuleLoader,
|
||||
"development"
|
||||
);
|
||||
const hoistedScripts = await getScriptsForURL(
|
||||
pathToFileURL(basePath),
|
||||
settings.config.root,
|
||||
devModuleLoader
|
||||
);
|
||||
stringifiedLinks = JSON.stringify([...urls]);
|
||||
stringifiedStyles = JSON.stringify([...stylesMap.values()]);
|
||||
stringifiedScripts = JSON.stringify([...hoistedScripts]);
|
||||
} else {
|
||||
stringifiedLinks = JSON.stringify(LINKS_PLACEHOLDER);
|
||||
stringifiedStyles = JSON.stringify(STYLES_PLACEHOLDER);
|
||||
stringifiedScripts = JSON.stringify(SCRIPTS_PLACEHOLDER);
|
||||
}
|
||||
const code = `
|
||||
async function getMod() {
|
||||
return import(${JSON.stringify(basePath)});
|
||||
}
|
||||
const collectedLinks = ${stringifiedLinks};
|
||||
const collectedStyles = ${stringifiedStyles};
|
||||
const collectedScripts = ${stringifiedScripts};
|
||||
const defaultMod = { __astroPropagation: true, getMod, collectedLinks, collectedStyles, collectedScripts };
|
||||
export default defaultMod;
|
||||
`;
|
||||
return { code, map: { mappings: "" } };
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function astroConfigBuildPlugin(options, internals) {
|
||||
let ssrPluginContext = void 0;
|
||||
return {
|
||||
build: "ssr",
|
||||
hooks: {
|
||||
"build:before": ({ build }) => {
|
||||
return {
|
||||
vitePlugin: {
|
||||
name: "astro:content-build-plugin",
|
||||
generateBundle() {
|
||||
if (build === "ssr") {
|
||||
ssrPluginContext = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
"build:post": ({ ssrOutputs, clientOutputs, mutate }) => {
|
||||
var _a, _b;
|
||||
const outputs = ssrOutputs.flatMap((o) => o.output);
|
||||
const prependBase = (src) => {
|
||||
if (options.settings.config.build.assetsPrefix) {
|
||||
return joinPaths(options.settings.config.build.assetsPrefix, src);
|
||||
} else {
|
||||
return prependForwardSlash(joinPaths(options.settings.config.base, src));
|
||||
}
|
||||
};
|
||||
for (const chunk of outputs) {
|
||||
if (chunk.type === "chunk" && (chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER))) {
|
||||
let entryStyles = /* @__PURE__ */ new Set();
|
||||
let entryLinks = /* @__PURE__ */ new Set();
|
||||
let entryScripts = /* @__PURE__ */ new Set();
|
||||
for (const id of Object.keys(chunk.modules)) {
|
||||
for (const [pageInfo] of walkParentInfos(id, ssrPluginContext)) {
|
||||
if (moduleIsTopLevelPage(pageInfo)) {
|
||||
const pageViteID = pageInfo.id;
|
||||
const pageData = getPageDataByViteID(internals, pageViteID);
|
||||
if (!pageData)
|
||||
continue;
|
||||
const _entryCss = (_a = pageData.propagatedStyles) == null ? void 0 : _a.get(id);
|
||||
const _entryScripts = (_b = pageData.propagatedScripts) == null ? void 0 : _b.get(id);
|
||||
if (_entryCss) {
|
||||
for (const value of _entryCss) {
|
||||
if (value.type === "inline")
|
||||
entryStyles.add(value.content);
|
||||
if (value.type === "external")
|
||||
entryLinks.add(value.src);
|
||||
}
|
||||
}
|
||||
if (_entryScripts) {
|
||||
for (const value of _entryScripts) {
|
||||
entryScripts.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let newCode = chunk.code;
|
||||
if (entryStyles.size) {
|
||||
newCode = newCode.replace(
|
||||
JSON.stringify(STYLES_PLACEHOLDER),
|
||||
JSON.stringify(Array.from(entryStyles))
|
||||
);
|
||||
}
|
||||
if (entryLinks.size) {
|
||||
newCode = newCode.replace(
|
||||
JSON.stringify(LINKS_PLACEHOLDER),
|
||||
JSON.stringify(Array.from(entryLinks).map(prependBase))
|
||||
);
|
||||
}
|
||||
if (entryScripts.size) {
|
||||
const entryFileNames = /* @__PURE__ */ new Set();
|
||||
for (const output of clientOutputs) {
|
||||
for (const clientChunk of output.output) {
|
||||
if (clientChunk.type !== "chunk")
|
||||
continue;
|
||||
for (const [id] of Object.entries(clientChunk.modules)) {
|
||||
if (entryScripts.has(id)) {
|
||||
entryFileNames.add(clientChunk.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
newCode = newCode.replace(
|
||||
JSON.stringify(SCRIPTS_PLACEHOLDER),
|
||||
JSON.stringify(
|
||||
[...entryFileNames].map((src) => ({
|
||||
props: {
|
||||
src: prependBase(src),
|
||||
type: "module"
|
||||
},
|
||||
children: ""
|
||||
}))
|
||||
)
|
||||
);
|
||||
}
|
||||
mutate(chunk, "server", newCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
astroConfigBuildPlugin,
|
||||
astroContentAssetPropagationPlugin
|
||||
};
|
8
node_modules/astro/dist/content/vite-plugin-content-imports.d.ts
generated
vendored
Normal file
8
node_modules/astro/dist/content/vite-plugin-content-imports.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/// <reference types="node" />
|
||||
import type fsMod from 'node:fs';
|
||||
import type { Plugin } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
export declare function astroContentImportPlugin({ fs, settings, }: {
|
||||
fs: typeof fsMod;
|
||||
settings: AstroSettings;
|
||||
}): Plugin[];
|
287
node_modules/astro/dist/content/vite-plugin-content-imports.js
generated
vendored
Normal file
287
node_modules/astro/dist/content/vite-plugin-content-imports.js
generated
vendored
Normal file
|
@ -0,0 +1,287 @@
|
|||
import * as devalue from "devalue";
|
||||
import { extname } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { AstroErrorData } from "../core/errors/errors-data.js";
|
||||
import { AstroError } from "../core/errors/errors.js";
|
||||
import { escapeViteEnvReferences } from "../vite-plugin-utils/index.js";
|
||||
import { CONTENT_FLAG, DATA_FLAG } from "./consts.js";
|
||||
import {
|
||||
getContentEntryExts,
|
||||
getContentEntryIdAndSlug,
|
||||
getContentPaths,
|
||||
getDataEntryExts,
|
||||
getDataEntryId,
|
||||
getEntryCollectionName,
|
||||
getEntryConfigByExtMap,
|
||||
getEntryData,
|
||||
getEntryType,
|
||||
globalContentConfigObserver,
|
||||
hasContentFlag,
|
||||
parseEntrySlug,
|
||||
reloadContentConfigObserver
|
||||
} from "./utils.js";
|
||||
function getContentRendererByViteId(viteId, settings) {
|
||||
let ext = viteId.split(".").pop();
|
||||
if (!ext)
|
||||
return void 0;
|
||||
for (const contentEntryType of settings.contentEntryTypes) {
|
||||
if (Boolean(contentEntryType.getRenderModule) && contentEntryType.extensions.includes("." + ext)) {
|
||||
return contentEntryType.getRenderModule;
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
const CHOKIDAR_MODIFIED_EVENTS = ["add", "unlink", "change"];
|
||||
const COLLECTION_TYPES_TO_INVALIDATE_ON = ["data", "content", "config"];
|
||||
function astroContentImportPlugin({
|
||||
fs,
|
||||
settings
|
||||
}) {
|
||||
const contentPaths = getContentPaths(settings.config, fs);
|
||||
const contentEntryExts = getContentEntryExts(settings);
|
||||
const dataEntryExts = getDataEntryExts(settings);
|
||||
const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
|
||||
const dataEntryConfigByExt = getEntryConfigByExtMap(settings.dataEntryTypes);
|
||||
const { contentDir } = contentPaths;
|
||||
const plugins = [
|
||||
{
|
||||
name: "astro:content-imports",
|
||||
async transform(_, viteId) {
|
||||
if (hasContentFlag(viteId, DATA_FLAG)) {
|
||||
const fileId = viteId.split("?")[0] ?? viteId;
|
||||
const { id, data, collection, _internal } = await getDataEntryModule({
|
||||
fileId,
|
||||
entryConfigByExt: dataEntryConfigByExt,
|
||||
contentDir,
|
||||
config: settings.config,
|
||||
fs,
|
||||
pluginContext: this
|
||||
});
|
||||
const code = escapeViteEnvReferences(`
|
||||
export const id = ${JSON.stringify(id)};
|
||||
export const collection = ${JSON.stringify(collection)};
|
||||
export const data = ${stringifyEntryData(data)};
|
||||
export const _internal = {
|
||||
type: 'data',
|
||||
filePath: ${JSON.stringify(_internal.filePath)},
|
||||
rawData: ${JSON.stringify(_internal.rawData)},
|
||||
};
|
||||
`);
|
||||
return code;
|
||||
} else if (hasContentFlag(viteId, CONTENT_FLAG)) {
|
||||
const fileId = viteId.split("?")[0];
|
||||
const { id, slug, collection, body, data, _internal } = await getContentEntryModule({
|
||||
fileId,
|
||||
entryConfigByExt: contentEntryConfigByExt,
|
||||
contentDir,
|
||||
config: settings.config,
|
||||
fs,
|
||||
pluginContext: this
|
||||
});
|
||||
const code = escapeViteEnvReferences(`
|
||||
export const id = ${JSON.stringify(id)};
|
||||
export const collection = ${JSON.stringify(collection)};
|
||||
export const slug = ${JSON.stringify(slug)};
|
||||
export const body = ${JSON.stringify(body)};
|
||||
export const data = ${stringifyEntryData(data)};
|
||||
export const _internal = {
|
||||
type: 'content',
|
||||
filePath: ${JSON.stringify(_internal.filePath)},
|
||||
rawData: ${JSON.stringify(_internal.rawData)},
|
||||
};`);
|
||||
return { code, map: { mappings: "" } };
|
||||
}
|
||||
},
|
||||
configureServer(viteServer) {
|
||||
viteServer.watcher.on("all", async (event, entry) => {
|
||||
if (CHOKIDAR_MODIFIED_EVENTS.includes(event)) {
|
||||
const entryType = getEntryType(
|
||||
entry,
|
||||
contentPaths,
|
||||
contentEntryExts,
|
||||
dataEntryExts,
|
||||
settings.config.experimental.assets
|
||||
);
|
||||
if (!COLLECTION_TYPES_TO_INVALIDATE_ON.includes(entryType))
|
||||
return;
|
||||
if (entryType === "content" || entryType === "data") {
|
||||
await reloadContentConfigObserver({ fs, settings, viteServer });
|
||||
}
|
||||
for (const modUrl of viteServer.moduleGraph.urlToModuleMap.keys()) {
|
||||
if (hasContentFlag(modUrl, CONTENT_FLAG) || hasContentFlag(modUrl, DATA_FLAG) || Boolean(getContentRendererByViteId(modUrl, settings))) {
|
||||
const mod = await viteServer.moduleGraph.getModuleByUrl(modUrl);
|
||||
if (mod) {
|
||||
viteServer.moduleGraph.invalidateModule(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
if (settings.contentEntryTypes.some((t) => t.getRenderModule)) {
|
||||
plugins.push({
|
||||
name: "astro:content-render-imports",
|
||||
async transform(contents, viteId) {
|
||||
const contentRenderer = getContentRendererByViteId(viteId, settings);
|
||||
if (!contentRenderer)
|
||||
return;
|
||||
const fileId = viteId.split("?")[0];
|
||||
return contentRenderer.bind(this)({ viteId, contents, fileUrl: pathToFileURL(fileId) });
|
||||
}
|
||||
});
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
async function getContentEntryModule(params) {
|
||||
const { fileId, contentDir, pluginContext, config } = params;
|
||||
const { collectionConfig, entryConfig, entry, rawContents, collection } = await getEntryModuleBaseInfo(params);
|
||||
const {
|
||||
rawData,
|
||||
data: unvalidatedData,
|
||||
body,
|
||||
slug: frontmatterSlug
|
||||
} = await entryConfig.getEntryInfo({
|
||||
fileUrl: pathToFileURL(fileId),
|
||||
contents: rawContents
|
||||
});
|
||||
const _internal = { filePath: fileId, rawData };
|
||||
const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ entry, contentDir, collection });
|
||||
const slug = parseEntrySlug({
|
||||
id,
|
||||
collection,
|
||||
generatedSlug,
|
||||
frontmatterSlug
|
||||
});
|
||||
const data = collectionConfig ? await getEntryData(
|
||||
{ id, collection, _internal, unvalidatedData },
|
||||
collectionConfig,
|
||||
pluginContext,
|
||||
config
|
||||
) : unvalidatedData;
|
||||
const contentEntryModule = {
|
||||
id,
|
||||
slug,
|
||||
collection,
|
||||
data,
|
||||
body,
|
||||
_internal
|
||||
};
|
||||
return contentEntryModule;
|
||||
}
|
||||
async function getDataEntryModule(params) {
|
||||
const { fileId, contentDir, pluginContext, config } = params;
|
||||
const { collectionConfig, entryConfig, entry, rawContents, collection } = await getEntryModuleBaseInfo(params);
|
||||
const { rawData = "", data: unvalidatedData } = await entryConfig.getEntryInfo({
|
||||
fileUrl: pathToFileURL(fileId),
|
||||
contents: rawContents
|
||||
});
|
||||
const _internal = { filePath: fileId, rawData };
|
||||
const id = getDataEntryId({ entry, contentDir, collection });
|
||||
const data = collectionConfig ? await getEntryData(
|
||||
{ id, collection, _internal, unvalidatedData },
|
||||
collectionConfig,
|
||||
pluginContext,
|
||||
config
|
||||
) : unvalidatedData;
|
||||
const dataEntryModule = {
|
||||
id,
|
||||
collection,
|
||||
data,
|
||||
_internal
|
||||
};
|
||||
return dataEntryModule;
|
||||
}
|
||||
async function getEntryModuleBaseInfo({
|
||||
fileId,
|
||||
entryConfigByExt,
|
||||
contentDir,
|
||||
fs
|
||||
}) {
|
||||
const contentConfig = await getContentConfigFromGlobal();
|
||||
let rawContents;
|
||||
try {
|
||||
rawContents = await fs.promises.readFile(fileId, "utf-8");
|
||||
} catch (e) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: `Unexpected error reading entry ${JSON.stringify(fileId)}.`,
|
||||
stack: e instanceof Error ? e.stack : void 0
|
||||
});
|
||||
}
|
||||
const fileExt = extname(fileId);
|
||||
const entryConfig = entryConfigByExt.get(fileExt);
|
||||
if (!entryConfig) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: `No parser found for data entry ${JSON.stringify(
|
||||
fileId
|
||||
)}. Did you apply an integration for this file type?`
|
||||
});
|
||||
}
|
||||
const entry = pathToFileURL(fileId);
|
||||
const collection = getEntryCollectionName({ entry, contentDir });
|
||||
if (collection === void 0)
|
||||
throw new AstroError(AstroErrorData.UnknownContentCollectionError);
|
||||
const collectionConfig = contentConfig == null ? void 0 : contentConfig.collections[collection];
|
||||
return {
|
||||
collectionConfig,
|
||||
entry,
|
||||
entryConfig,
|
||||
collection,
|
||||
rawContents
|
||||
};
|
||||
}
|
||||
async function getContentConfigFromGlobal() {
|
||||
const observable = globalContentConfigObserver.get();
|
||||
if (observable.status === "init") {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: "Content config failed to load."
|
||||
});
|
||||
}
|
||||
if (observable.status === "error") {
|
||||
throw observable.error;
|
||||
}
|
||||
let contentConfig = observable.status === "loaded" ? observable.config : void 0;
|
||||
if (observable.status === "loading") {
|
||||
contentConfig = await new Promise((resolve) => {
|
||||
const unsubscribe = globalContentConfigObserver.subscribe((ctx) => {
|
||||
if (ctx.status === "loaded") {
|
||||
resolve(ctx.config);
|
||||
unsubscribe();
|
||||
}
|
||||
if (ctx.status === "error") {
|
||||
resolve(void 0);
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return contentConfig;
|
||||
}
|
||||
function stringifyEntryData(data) {
|
||||
try {
|
||||
return devalue.uneval(data, (value) => {
|
||||
if (value instanceof URL) {
|
||||
return `new URL(${JSON.stringify(value.href)})`;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.UnsupportedConfigTransformError,
|
||||
message: AstroErrorData.UnsupportedConfigTransformError.message(e.message),
|
||||
stack: e.stack
|
||||
});
|
||||
} else {
|
||||
throw new AstroError({
|
||||
message: "Unexpected error processing content collection data."
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
astroContentImportPlugin
|
||||
};
|
22
node_modules/astro/dist/content/vite-plugin-content-virtual-mod.d.ts
generated
vendored
Normal file
22
node_modules/astro/dist/content/vite-plugin-content-virtual-mod.d.ts
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/// <reference types="node" />
|
||||
import fsMod from 'node:fs';
|
||||
import type { Plugin } from 'vite';
|
||||
import type { AstroSettings, ContentEntryType } from '../@types/astro.js';
|
||||
import { type ContentPaths } from './utils.js';
|
||||
interface AstroContentVirtualModPluginParams {
|
||||
settings: AstroSettings;
|
||||
}
|
||||
export declare function astroContentVirtualModPlugin({ settings, }: AstroContentVirtualModPluginParams): Plugin;
|
||||
/**
|
||||
* Generate a map from a collection + slug to the local file path.
|
||||
* This is used internally to resolve entry imports when using `getEntry()`.
|
||||
* @see `content-module.template.mjs`
|
||||
*/
|
||||
export declare function getStringifiedLookupMap({ contentPaths, contentEntryConfigByExt, dataEntryExts, root, fs, }: {
|
||||
contentEntryConfigByExt: Map<string, ContentEntryType>;
|
||||
dataEntryExts: string[];
|
||||
contentPaths: Pick<ContentPaths, 'contentDir' | 'config'>;
|
||||
root: URL;
|
||||
fs: typeof fsMod;
|
||||
}): Promise<string>;
|
||||
export {};
|
178
node_modules/astro/dist/content/vite-plugin-content-virtual-mod.js
generated
vendored
Normal file
178
node_modules/astro/dist/content/vite-plugin-content-virtual-mod.js
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
import glob from "fast-glob";
|
||||
import fsMod from "node:fs";
|
||||
import { extname } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import pLimit from "p-limit";
|
||||
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
||||
import { appendForwardSlash } from "../core/path.js";
|
||||
import { rootRelativePath } from "../core/util.js";
|
||||
import { VIRTUAL_MODULE_ID } from "./consts.js";
|
||||
import {
|
||||
getContentEntryIdAndSlug,
|
||||
getContentPaths,
|
||||
getDataEntryExts,
|
||||
getDataEntryId,
|
||||
getEntryCollectionName,
|
||||
getEntryConfigByExtMap,
|
||||
getEntrySlug,
|
||||
getEntryType,
|
||||
getExtGlob
|
||||
} from "./utils.js";
|
||||
function astroContentVirtualModPlugin({
|
||||
settings
|
||||
}) {
|
||||
const contentPaths = getContentPaths(settings.config);
|
||||
const relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir);
|
||||
const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
|
||||
const contentEntryExts = [...contentEntryConfigByExt.keys()];
|
||||
const dataEntryExts = getDataEntryExts(settings);
|
||||
const virtualModContents = fsMod.readFileSync(contentPaths.virtualModTemplate, "utf-8").replace(
|
||||
"@@COLLECTION_NAME_BY_REFERENCE_KEY@@",
|
||||
new URL("reference-map.json", contentPaths.cacheDir).pathname
|
||||
).replace("@@CONTENT_DIR@@", relContentDir).replace(
|
||||
"'@@CONTENT_ENTRY_GLOB_PATH@@'",
|
||||
JSON.stringify(globWithUnderscoresIgnored(relContentDir, contentEntryExts))
|
||||
).replace(
|
||||
"'@@DATA_ENTRY_GLOB_PATH@@'",
|
||||
JSON.stringify(globWithUnderscoresIgnored(relContentDir, dataEntryExts))
|
||||
).replace(
|
||||
"'@@RENDER_ENTRY_GLOB_PATH@@'",
|
||||
JSON.stringify(
|
||||
globWithUnderscoresIgnored(
|
||||
relContentDir,
|
||||
/** Note: data collections excluded */
|
||||
contentEntryExts
|
||||
)
|
||||
)
|
||||
);
|
||||
const astroContentVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
|
||||
return {
|
||||
name: "astro-content-virtual-mod-plugin",
|
||||
resolveId(id) {
|
||||
if (id === VIRTUAL_MODULE_ID) {
|
||||
return astroContentVirtualModuleId;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id === astroContentVirtualModuleId) {
|
||||
const stringifiedLookupMap = await getStringifiedLookupMap({
|
||||
fs: fsMod,
|
||||
contentPaths,
|
||||
contentEntryConfigByExt,
|
||||
dataEntryExts,
|
||||
root: settings.config.root
|
||||
});
|
||||
return {
|
||||
code: virtualModContents.replace(
|
||||
"/* @@LOOKUP_MAP_ASSIGNMENT@@ */",
|
||||
`lookupMap = ${stringifiedLookupMap};`
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
async function getStringifiedLookupMap({
|
||||
contentPaths,
|
||||
contentEntryConfigByExt,
|
||||
dataEntryExts,
|
||||
root,
|
||||
fs
|
||||
}) {
|
||||
const { contentDir } = contentPaths;
|
||||
const relContentDir = rootRelativePath(root, contentDir, false);
|
||||
const contentEntryExts = [...contentEntryConfigByExt.keys()];
|
||||
let lookupMap = {};
|
||||
const contentGlob = await glob(
|
||||
`${relContentDir}**/*${getExtGlob([...dataEntryExts, ...contentEntryExts])}`,
|
||||
{
|
||||
absolute: true,
|
||||
cwd: fileURLToPath(root),
|
||||
fs: {
|
||||
readdir: fs.readdir.bind(fs),
|
||||
readdirSync: fs.readdirSync.bind(fs)
|
||||
}
|
||||
}
|
||||
);
|
||||
const limit = pLimit(10);
|
||||
const promises = [];
|
||||
for (const filePath of contentGlob) {
|
||||
promises.push(
|
||||
limit(async () => {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const entryType = getEntryType(filePath, contentPaths, contentEntryExts, dataEntryExts);
|
||||
if (entryType !== "content" && entryType !== "data")
|
||||
return;
|
||||
const collection = getEntryCollectionName({ contentDir, entry: pathToFileURL(filePath) });
|
||||
if (!collection)
|
||||
throw UnexpectedLookupMapError;
|
||||
if (((_a = lookupMap[collection]) == null ? void 0 : _a.type) && lookupMap[collection].type !== entryType) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.MixedContentDataCollectionError,
|
||||
message: AstroErrorData.MixedContentDataCollectionError.message(collection)
|
||||
});
|
||||
}
|
||||
if (entryType === "content") {
|
||||
const contentEntryType = contentEntryConfigByExt.get(extname(filePath));
|
||||
if (!contentEntryType)
|
||||
throw UnexpectedLookupMapError;
|
||||
const { id, slug: generatedSlug } = await getContentEntryIdAndSlug({
|
||||
entry: pathToFileURL(filePath),
|
||||
contentDir,
|
||||
collection
|
||||
});
|
||||
const slug = await getEntrySlug({
|
||||
id,
|
||||
collection,
|
||||
generatedSlug,
|
||||
fs,
|
||||
fileUrl: pathToFileURL(filePath),
|
||||
contentEntryType
|
||||
});
|
||||
if ((_c = (_b = lookupMap[collection]) == null ? void 0 : _b.entries) == null ? void 0 : _c[slug]) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.DuplicateContentEntrySlugError,
|
||||
message: AstroErrorData.DuplicateContentEntrySlugError.message(collection, slug),
|
||||
hint: slug !== generatedSlug ? `Check the \`slug\` frontmatter property in **${id}**.` : void 0
|
||||
});
|
||||
}
|
||||
lookupMap[collection] = {
|
||||
type: "content",
|
||||
entries: {
|
||||
...(_d = lookupMap[collection]) == null ? void 0 : _d.entries,
|
||||
[slug]: rootRelativePath(root, filePath)
|
||||
}
|
||||
};
|
||||
} else {
|
||||
const id = getDataEntryId({ entry: pathToFileURL(filePath), contentDir, collection });
|
||||
lookupMap[collection] = {
|
||||
type: "data",
|
||||
entries: {
|
||||
...(_e = lookupMap[collection]) == null ? void 0 : _e.entries,
|
||||
[id]: rootRelativePath(root, filePath)
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
return JSON.stringify(lookupMap);
|
||||
}
|
||||
const UnexpectedLookupMapError = new AstroError({
|
||||
...AstroErrorData.UnknownContentCollectionError,
|
||||
message: `Unexpected error while parsing content entry IDs and slugs.`
|
||||
});
|
||||
function globWithUnderscoresIgnored(relContentDir, exts) {
|
||||
const extGlob = getExtGlob(exts);
|
||||
const contentDir = appendForwardSlash(relContentDir);
|
||||
return [
|
||||
`${contentDir}**/*${extGlob}`,
|
||||
`!${contentDir}**/_*/**${extGlob}`,
|
||||
`!${contentDir}**/_*${extGlob}`
|
||||
];
|
||||
}
|
||||
export {
|
||||
astroContentVirtualModPlugin,
|
||||
getStringifiedLookupMap
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue