astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
84 lines (83 loc) • 4.77 kB
JavaScript
import { getImageServiceConfig } from "../assets/utils/service-config.js";
export const AdapterFeatureStability = {
STABLE: "stable",
DEPRECATED: "deprecated",
UNSUPPORTED: "unsupported",
EXPERIMENTAL: "experimental",
LIMITED: "limited"
};
/**
* Checks whether an adapter supports certain features that are enabled via Astro configuration.
*
* If a configuration is enabled and "unlocks" a feature, but the adapter doesn't support, the function
* will throw a runtime error.
*
*/
export function validateSupportedFeatures(adapterName, featureMap, settings, logger) {
const { serverOutput = AdapterFeatureStability.UNSUPPORTED, staticOutput = AdapterFeatureStability.UNSUPPORTED, hybridOutput = AdapterFeatureStability.UNSUPPORTED, i18nDomains = AdapterFeatureStability.UNSUPPORTED, envGetSecret = AdapterFeatureStability.UNSUPPORTED, sharpImageService = AdapterFeatureStability.UNSUPPORTED } = featureMap;
const validationResult = {};
validationResult.staticOutput = validateSupportKind(staticOutput, adapterName, logger, "staticOutput", () => settings.buildOutput === "static");
validationResult.hybridOutput = validateSupportKind(hybridOutput, adapterName, logger, "hybridOutput", () => settings.config.output === "static" && settings.buildOutput === "server");
validationResult.serverOutput = validateSupportKind(serverOutput, adapterName, logger, "serverOutput", () => settings.config?.output === "server" || settings.buildOutput === "server");
if (settings.config.i18n?.domains) {
validationResult.i18nDomains = validateSupportKind(i18nDomains, adapterName, logger, "i18nDomains", () => {
return settings.config?.output === "server" && !settings.config?.site;
});
}
validationResult.envGetSecret = validateSupportKind(envGetSecret, adapterName, logger, "astro:env getSecret", () => Object.keys(settings.config?.env?.schema ?? {}).length !== 0);
validationResult.sharpImageService = validateSupportKind(sharpImageService, adapterName, logger, "sharp", () => !!settings.config?.image?.service && getImageServiceConfig(settings.config.image.service, "runtime").entrypoint === "astro/assets/services/sharp");
return validationResult;
}
export function unwrapSupportKind(supportKind) {
if (!supportKind) {
return undefined;
}
return typeof supportKind === "object" ? supportKind.support : supportKind;
}
export function getSupportMessage(supportKind) {
return typeof supportKind === "object" ? supportKind.message : undefined;
}
function getSupportMessageSuppression(supportKind) {
return typeof supportKind === "object" ? supportKind.suppress : undefined;
}
function validateSupportKind(supportKind, adapterName, logger, featureName, hasCorrectConfig) {
const supportValue = unwrapSupportKind(supportKind);
const message = getSupportMessage(supportKind);
const suppress = getSupportMessageSuppression(supportKind);
if (!supportValue) {
return false;
}
if (supportValue === AdapterFeatureStability.STABLE) {
return true;
} else if (hasCorrectConfig()) {
// If the user has the relevant configuration, but the adapter doesn't support it, warn the user
logFeatureSupport(adapterName, logger, featureName, supportValue, message, suppress);
}
return false;
}
function logFeatureSupport(adapterName, logger, featureName, supportKind, adapterMessage, suppress) {
if (!suppress) {
switch (supportKind) {
case AdapterFeatureStability.STABLE: break;
case AdapterFeatureStability.DEPRECATED:
logger.warn("config", `The adapter ${adapterName} has deprecated its support for "${featureName}", and future compatibility is not guaranteed. The adapter may completely remove support for this feature without warning.`);
break;
case AdapterFeatureStability.EXPERIMENTAL:
logger.warn("config", `The adapter ${adapterName} provides experimental support for "${featureName}". You may experience issues or breaking changes until this feature is fully supported by the adapter.`);
break;
case AdapterFeatureStability.LIMITED:
logger.warn("config", `The adapter ${adapterName} has limited support for "${featureName}". Certain features may not work as expected.`);
break;
case AdapterFeatureStability.UNSUPPORTED:
logger.error("config", `The adapter ${adapterName} does not currently support the feature "${featureName}". Your project may not build correctly.`);
break;
}
}
// If the adapter specified a custom message, log it after the default message (when not suppressed)
if (adapterMessage && suppress !== "all") {
logger.warn("adapter", adapterMessage);
}
}
export function getAdapterStaticRecommendation(adapterName) {
return { "@astrojs/vercel/static": "Update your configuration to use `@astrojs/vercel/serverless` to unlock server-side rendering capabilities." }[adapterName];
}