astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
148 lines (147 loc) • 5.07 kB
JavaScript
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { parseYaml } from "@astrojs/internal-helpers/yaml";
import * as toml from "smol-toml";
import { getContentPaths } from "../../content/index.js";
import createPreferences from "../../preferences/index.js";
import { markdownContentEntryType } from "../../vite-plugin-markdown/content-entry-type.js";
import { getDefaultClientDirectives } from "../client-directive/index.js";
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from "./../constants.js";
import { AstroError, AstroErrorData } from "../errors/index.js";
import { formatTOMLError, formatYAMLParseError, isTOMLError, isYAMLParseError } from "../errors/utils.js";
import { AstroTimer } from "./timer.js";
import { loadTSConfig } from "./tsconfig.js";
export function createBaseSettings(config, logLevel) {
const { contentDir } = getContentPaths(config, undefined, config.legacy?.collectionsBackwardsCompat);
const dotAstroDir = new URL(".astro/", config.root);
const preferences = createPreferences(config, dotAstroDir);
return {
config,
preferences,
tsConfig: undefined,
tsConfigPath: undefined,
adapter: undefined,
prerenderer: undefined,
injectedRoutes: [],
resolvedInjectedRoutes: [],
pageExtensions: [
".astro",
".html",
...SUPPORTED_MARKDOWN_FILE_EXTENSIONS
],
contentEntryTypes: [markdownContentEntryType],
dataEntryTypes: [
{
extensions: [".json"],
getEntryInfo({ contents, fileUrl }) {
if (contents === undefined || contents === "") return { data: {} };
const pathRelToContentDir = path.relative(fileURLToPath(contentDir), fileURLToPath(fileUrl));
let data;
try {
data = JSON.parse(contents);
} catch (e) {
throw new AstroError({
...AstroErrorData.DataCollectionEntryParseError,
message: AstroErrorData.DataCollectionEntryParseError.message(pathRelToContentDir, e instanceof Error ? e.message : "contains invalid JSON."),
location: { file: fileUrl.pathname },
stack: e instanceof Error ? e.stack : undefined
});
}
if (data == null || typeof data !== "object") {
throw new AstroError({
...AstroErrorData.DataCollectionEntryParseError,
message: AstroErrorData.DataCollectionEntryParseError.message(pathRelToContentDir, "data is not an object."),
location: { file: fileUrl.pathname }
});
}
return { data };
}
},
{
extensions: [".yaml", ".yml"],
getEntryInfo({ contents, fileUrl }) {
try {
const data = parseYaml(contents);
const rawData = contents;
return {
data,
rawData
};
} catch (e) {
const pathRelToContentDir = path.relative(fileURLToPath(contentDir), fileURLToPath(fileUrl));
const formattedError = isYAMLParseError(e) ? formatYAMLParseError(e) : new Error("contains invalid YAML.");
throw new AstroError({
...AstroErrorData.DataCollectionEntryParseError,
message: AstroErrorData.DataCollectionEntryParseError.message(pathRelToContentDir, formattedError.message),
stack: formattedError.stack,
location: "loc" in formattedError ? {
file: fileUrl.pathname,
...formattedError.loc
} : { file: fileUrl.pathname }
});
}
}
},
{
extensions: [".toml"],
getEntryInfo({ contents, fileUrl }) {
try {
const data = toml.parse(contents);
const rawData = contents;
return {
data,
rawData
};
} catch (e) {
const pathRelToContentDir = path.relative(fileURLToPath(contentDir), fileURLToPath(fileUrl));
const formattedError = isTOMLError(e) ? formatTOMLError(e) : new Error("contains invalid TOML.");
throw new AstroError({
...AstroErrorData.DataCollectionEntryParseError,
message: AstroErrorData.DataCollectionEntryParseError.message(pathRelToContentDir, formattedError.message),
stack: formattedError.stack,
location: "loc" in formattedError ? {
file: fileUrl.pathname,
...formattedError.loc
} : { file: fileUrl.pathname }
});
}
}
}
],
renderers: [],
scripts: [],
clientDirectives: getDefaultClientDirectives(),
middlewares: {
pre: [],
post: []
},
watchFiles: [],
devToolbarApps: [],
timer: new AstroTimer(),
dotAstroDir,
latestAstroVersion: undefined,
injectedTypes: [],
buildOutput: undefined,
injectedCsp: {
fontResources: new Set(),
styleHashes: []
},
logLevel: logLevel ?? "info",
fontsHttpServer: null
};
}
export async function createSettings(config, logLevel, cwd) {
const tsconfig = await loadTSConfig(cwd);
const settings = createBaseSettings(config, logLevel);
let watchFiles = [];
if (cwd) {
watchFiles.push(fileURLToPath(new URL("./package.json", pathToFileURL(cwd))));
}
if (!tsconfig.error) {
watchFiles.push(...tsconfig.sources);
settings.tsConfig = tsconfig.tsconfig;
settings.tsConfigPath = tsconfig.tsconfigFile;
}
settings.watchFiles = watchFiles;
return settings;
}