- Delete auto-generated .nixpacks folder - Delete .docker folder - Easypanel should use root Dockerfile only - This prevents confusion with multiple Dockerfile locations
470 lines
14 KiB
JavaScript
470 lines
14 KiB
JavaScript
import { escape } from 'html-escaper';
|
|
import { Traverse } from 'neotraverse/modern';
|
|
import pLimit from 'p-limit';
|
|
import { z } from 'zod';
|
|
import { removeBase, isRemotePath, prependForwardSlash } from '@astrojs/internal-helpers/path';
|
|
import { A as AstroError, R as RenderUndefinedEntryError, c as createComponent, u as unescapeHTML, a as renderTemplate, U as UnknownContentCollectionError, e as renderUniqueStylesheet, f as renderScriptElement, g as createHeadAndContent, r as renderComponent } from './astro/server_D-JZF3a4.mjs';
|
|
import 'piccolore';
|
|
import * as devalue from 'devalue';
|
|
|
|
const CONTENT_IMAGE_FLAG = "astroContentImageFlag";
|
|
const IMAGE_IMPORT_PREFIX = "__ASTRO_IMAGE_";
|
|
|
|
const VALID_INPUT_FORMATS = [
|
|
"jpeg",
|
|
"jpg",
|
|
"png",
|
|
"tiff",
|
|
"webp",
|
|
"gif",
|
|
"svg",
|
|
"avif"
|
|
];
|
|
const VALID_SUPPORTED_FORMATS = [
|
|
"jpeg",
|
|
"jpg",
|
|
"png",
|
|
"tiff",
|
|
"webp",
|
|
"gif",
|
|
"svg",
|
|
"avif"
|
|
];
|
|
const DEFAULT_OUTPUT_FORMAT = "webp";
|
|
const DEFAULT_HASH_PROPS = [
|
|
"src",
|
|
"width",
|
|
"height",
|
|
"format",
|
|
"quality",
|
|
"fit",
|
|
"position",
|
|
"background"
|
|
];
|
|
|
|
function imageSrcToImportId(imageSrc, filePath) {
|
|
imageSrc = removeBase(imageSrc, IMAGE_IMPORT_PREFIX);
|
|
if (isRemotePath(imageSrc)) {
|
|
return;
|
|
}
|
|
const ext = imageSrc.split(".").at(-1)?.toLowerCase();
|
|
if (!ext || !VALID_INPUT_FORMATS.includes(ext)) {
|
|
return;
|
|
}
|
|
const params = new URLSearchParams(CONTENT_IMAGE_FLAG);
|
|
if (filePath) {
|
|
params.set("importer", filePath);
|
|
}
|
|
return `${imageSrc}?${params.toString()}`;
|
|
}
|
|
|
|
class ImmutableDataStore {
|
|
_collections = /* @__PURE__ */ new Map();
|
|
constructor() {
|
|
this._collections = /* @__PURE__ */ new Map();
|
|
}
|
|
get(collectionName, key) {
|
|
return this._collections.get(collectionName)?.get(String(key));
|
|
}
|
|
entries(collectionName) {
|
|
const collection = this._collections.get(collectionName) ?? /* @__PURE__ */ new Map();
|
|
return [...collection.entries()];
|
|
}
|
|
values(collectionName) {
|
|
const collection = this._collections.get(collectionName) ?? /* @__PURE__ */ new Map();
|
|
return [...collection.values()];
|
|
}
|
|
keys(collectionName) {
|
|
const collection = this._collections.get(collectionName) ?? /* @__PURE__ */ new Map();
|
|
return [...collection.keys()];
|
|
}
|
|
has(collectionName, key) {
|
|
const collection = this._collections.get(collectionName);
|
|
if (collection) {
|
|
return collection.has(String(key));
|
|
}
|
|
return false;
|
|
}
|
|
hasCollection(collectionName) {
|
|
return this._collections.has(collectionName);
|
|
}
|
|
collections() {
|
|
return this._collections;
|
|
}
|
|
/**
|
|
* Attempts to load a DataStore from the virtual module.
|
|
* This only works in Vite.
|
|
*/
|
|
static async fromModule() {
|
|
try {
|
|
const data = await import('./_astro_data-layer-content_NX5tLOlp.mjs');
|
|
if (data.default instanceof Map) {
|
|
return ImmutableDataStore.fromMap(data.default);
|
|
}
|
|
const map = devalue.unflatten(data.default);
|
|
return ImmutableDataStore.fromMap(map);
|
|
} catch {
|
|
}
|
|
return new ImmutableDataStore();
|
|
}
|
|
static async fromMap(data) {
|
|
const store = new ImmutableDataStore();
|
|
store._collections = data;
|
|
return store;
|
|
}
|
|
}
|
|
function dataStoreSingleton() {
|
|
let instance = void 0;
|
|
return {
|
|
get: async () => {
|
|
if (!instance) {
|
|
instance = ImmutableDataStore.fromModule();
|
|
}
|
|
return instance;
|
|
},
|
|
set: (store) => {
|
|
instance = store;
|
|
}
|
|
};
|
|
}
|
|
const globalDataStore = dataStoreSingleton();
|
|
|
|
const __vite_import_meta_env__ = {"ASSETS_PREFIX": undefined, "BASE_URL": "/", "DEV": false, "MODE": "production", "PROD": true, "SITE": undefined, "SSR": true};
|
|
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;
|
|
}
|
|
z.object({
|
|
tags: z.array(z.string()).optional(),
|
|
lastModified: z.date().optional()
|
|
});
|
|
function createGetCollection({
|
|
contentCollectionToEntryMap,
|
|
dataCollectionToEntryMap,
|
|
getRenderEntryImport,
|
|
cacheEntriesByCollection,
|
|
liveCollections
|
|
}) {
|
|
return async function getCollection(collection, filter) {
|
|
if (collection in liveCollections) {
|
|
throw new AstroError({
|
|
...UnknownContentCollectionError,
|
|
message: `Collection "${collection}" is a live collection. Use getLiveCollection() instead of getCollection().`
|
|
});
|
|
}
|
|
const hasFilter = typeof filter === "function";
|
|
const store = await globalDataStore.get();
|
|
let type;
|
|
if (collection in contentCollectionToEntryMap) {
|
|
type = "content";
|
|
} else if (collection in dataCollectionToEntryMap) {
|
|
type = "data";
|
|
} else if (store.hasCollection(collection)) {
|
|
const { default: imageAssetMap } = await import('./content-assets_DleWbedO.mjs');
|
|
const result = [];
|
|
for (const rawEntry of store.values(collection)) {
|
|
const data = updateImageReferencesInData(rawEntry.data, rawEntry.filePath, imageAssetMap);
|
|
let entry = {
|
|
...rawEntry,
|
|
data,
|
|
collection
|
|
};
|
|
if (entry.legacyId) {
|
|
entry = emulateLegacyEntry(entry);
|
|
}
|
|
if (hasFilter && !filter(entry)) {
|
|
continue;
|
|
}
|
|
result.push(entry);
|
|
}
|
|
return result;
|
|
} else {
|
|
console.warn(
|
|
`The collection ${JSON.stringify(
|
|
collection
|
|
)} does not exist or is empty. Please check your content config file for errors.`
|
|
);
|
|
return [];
|
|
}
|
|
const lazyImports = Object.values(
|
|
type === "content" ? contentCollectionToEntryMap[collection] : dataCollectionToEntryMap[collection]
|
|
);
|
|
let entries = [];
|
|
if (!Object.assign(__vite_import_meta_env__, { _: process.env._ })?.DEV && cacheEntriesByCollection.has(collection)) {
|
|
entries = cacheEntriesByCollection.get(collection);
|
|
} else {
|
|
const limit = pLimit(10);
|
|
entries = await Promise.all(
|
|
lazyImports.map(
|
|
(lazyImport) => limit(async () => {
|
|
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 (hasFilter) {
|
|
return entries.filter(filter);
|
|
} else {
|
|
return entries.slice();
|
|
}
|
|
};
|
|
}
|
|
function emulateLegacyEntry({ legacyId, ...entry }) {
|
|
const legacyEntry = {
|
|
...entry,
|
|
id: legacyId,
|
|
slug: entry.id
|
|
};
|
|
return {
|
|
...legacyEntry,
|
|
// Define separately so the render function isn't included in the object passed to `renderEntry()`
|
|
render: () => renderEntry(legacyEntry)
|
|
};
|
|
}
|
|
const CONTENT_LAYER_IMAGE_REGEX = /__ASTRO_IMAGE_="([^"]+)"/g;
|
|
async function updateImageReferencesInBody(html, fileName) {
|
|
const { default: imageAssetMap } = await import('./content-assets_DleWbedO.mjs');
|
|
const imageObjects = /* @__PURE__ */ new Map();
|
|
const { getImage } = await import('./_astro_assets_CWrzoUoo.mjs').then(n => n._);
|
|
for (const [_full, imagePath] of html.matchAll(CONTENT_LAYER_IMAGE_REGEX)) {
|
|
try {
|
|
const decodedImagePath = JSON.parse(imagePath.replaceAll(""", '"'));
|
|
let image;
|
|
if (URL.canParse(decodedImagePath.src)) {
|
|
image = await getImage(decodedImagePath);
|
|
} else {
|
|
const id = imageSrcToImportId(decodedImagePath.src, fileName);
|
|
const imported = imageAssetMap.get(id);
|
|
if (!id || imageObjects.has(id) || !imported) {
|
|
continue;
|
|
}
|
|
image = await getImage({ ...decodedImagePath, src: imported });
|
|
}
|
|
imageObjects.set(imagePath, image);
|
|
} catch {
|
|
throw new Error(`Failed to parse image reference: ${imagePath}`);
|
|
}
|
|
}
|
|
return html.replaceAll(CONTENT_LAYER_IMAGE_REGEX, (full, imagePath) => {
|
|
const image = imageObjects.get(imagePath);
|
|
if (!image) {
|
|
return full;
|
|
}
|
|
const { index, ...attributes } = image.attributes;
|
|
return Object.entries({
|
|
...attributes,
|
|
src: image.src,
|
|
srcset: image.srcSet.attribute,
|
|
// This attribute is used by the toolbar audit
|
|
...Object.assign(__vite_import_meta_env__, { _: process.env._ }).DEV ? { "data-image-component": "true" } : {}
|
|
}).map(([key, value]) => value ? `${key}="${escape(value)}"` : "").join(" ");
|
|
});
|
|
}
|
|
function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
|
return new Traverse(data).map(function(ctx, val) {
|
|
if (typeof val === "string" && val.startsWith(IMAGE_IMPORT_PREFIX)) {
|
|
const src = val.replace(IMAGE_IMPORT_PREFIX, "");
|
|
const id = imageSrcToImportId(src, fileName);
|
|
if (!id) {
|
|
ctx.update(src);
|
|
return;
|
|
}
|
|
const imported = imageAssetMap?.get(id);
|
|
if (imported) {
|
|
ctx.update(imported);
|
|
} else {
|
|
ctx.update(src);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
async function renderEntry(entry) {
|
|
if (!entry) {
|
|
throw new AstroError(RenderUndefinedEntryError);
|
|
}
|
|
if ("render" in entry && !("legacyId" in entry)) {
|
|
return entry.render();
|
|
}
|
|
if (entry.deferredRender) {
|
|
try {
|
|
const { default: contentModules } = await import('./content-modules_Dz-S_Wwv.mjs');
|
|
const renderEntryImport = contentModules.get(entry.filePath);
|
|
return render({
|
|
collection: "",
|
|
id: entry.id,
|
|
renderEntryImport
|
|
});
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
const html = entry?.rendered?.metadata?.imagePaths?.length && entry.filePath ? await updateImageReferencesInBody(entry.rendered.html, entry.filePath) : entry?.rendered?.html;
|
|
const Content = createComponent(() => renderTemplate`${unescapeHTML(html)}`);
|
|
return {
|
|
Content,
|
|
headings: entry?.rendered?.metadata?.headings ?? [],
|
|
remarkPluginFrontmatter: entry?.rendered?.metadata?.frontmatter ?? {}
|
|
};
|
|
}
|
|
async function render({
|
|
collection,
|
|
id,
|
|
renderEntryImport
|
|
}) {
|
|
const UnexpectedRenderError = new AstroError({
|
|
...UnknownContentCollectionError,
|
|
message: `Unexpected error while rendering ${String(collection)} → ${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: isRemotePath(link) ? link : 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: propagationMod.getHeadings?.() ?? [],
|
|
remarkPluginFrontmatter: propagationMod.frontmatter ?? {}
|
|
};
|
|
} else if (baseMod.Content && typeof baseMod.Content === "function") {
|
|
return {
|
|
Content: baseMod.Content,
|
|
headings: baseMod.getHeadings?.() ?? [],
|
|
remarkPluginFrontmatter: baseMod.frontmatter ?? {}
|
|
};
|
|
} else {
|
|
throw UnexpectedRenderError;
|
|
}
|
|
}
|
|
function isPropagatedAssetsModule(module) {
|
|
return typeof module === "object" && module != null && "__astroPropagation" in module;
|
|
}
|
|
|
|
// astro-head-inject
|
|
|
|
const liveCollections = {};
|
|
|
|
const contentDir = '/src/content/';
|
|
|
|
const contentEntryGlob = "";
|
|
const contentCollectionToEntryMap = createCollectionToGlobResultMap({
|
|
globResult: contentEntryGlob,
|
|
contentDir,
|
|
});
|
|
|
|
const dataEntryGlob = "";
|
|
const dataCollectionToEntryMap = createCollectionToGlobResultMap({
|
|
globResult: dataEntryGlob,
|
|
contentDir,
|
|
});
|
|
createCollectionToGlobResultMap({
|
|
globResult: { ...contentEntryGlob, ...dataEntryGlob },
|
|
contentDir,
|
|
});
|
|
|
|
let lookupMap = {};
|
|
lookupMap = {};
|
|
|
|
new Set(Object.keys(lookupMap));
|
|
|
|
function createGlobLookup(glob) {
|
|
return async (collection, lookupId) => {
|
|
const filePath = lookupMap[collection]?.entries[lookupId];
|
|
|
|
if (!filePath) return undefined;
|
|
return glob[collection][filePath];
|
|
};
|
|
}
|
|
|
|
const renderEntryGlob = "";
|
|
const collectionToRenderEntryMap = createCollectionToGlobResultMap({
|
|
globResult: renderEntryGlob,
|
|
contentDir,
|
|
});
|
|
|
|
const cacheEntriesByCollection = new Map();
|
|
const getCollection = createGetCollection({
|
|
contentCollectionToEntryMap,
|
|
dataCollectionToEntryMap,
|
|
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
|
|
cacheEntriesByCollection,
|
|
liveCollections,
|
|
});
|
|
|
|
export { DEFAULT_OUTPUT_FORMAT as D, VALID_SUPPORTED_FORMATS as V, DEFAULT_HASH_PROPS as a, getCollection as g, renderEntry as r };
|