diff --git a/.changeset/dull-beers-move.md b/.changeset/dull-beers-move.md new file mode 100644 index 000000000000..5c5679bdc9e2 --- /dev/null +++ b/.changeset/dull-beers-move.md @@ -0,0 +1,23 @@ +--- +"astro": minor +--- + +Adds an option for integration authors to suppress adapter warning/errors in `supportedAstroFeatures`. This is useful when either an warning/error isn't applicable in a specific context or the default one might conflict and confuse users. + +To do so, you can add `suppress: "all"` (to suppress both the default and custom message) or `suppress: "default"` (to only suppress the default one): +```ts +setAdapter({ + name: 'my-astro-integration', + supportedAstroFeatures: { + staticOutput: "stable", + hybridOutput: "stable", + sharpImageService: { + support: "limited", + message: "The sharp image service isn't available in the deploy environment, but will be used by prerendered pages on build.", + suppress: "default", + }, + } +}) +``` + +For more information, see the [Adapter API reference docs](https://docs.astro.build/en/reference/adapter-reference/#astro-features). diff --git a/packages/astro/src/integrations/features-validation.ts b/packages/astro/src/integrations/features-validation.ts index 0edcb7bb9139..058758627311 100644 --- a/packages/astro/src/integrations/features-validation.ts +++ b/packages/astro/src/integrations/features-validation.ts @@ -108,6 +108,10 @@ function getSupportMessage(supportKind: AdapterSupport): string | undefined { return typeof supportKind === 'object' ? supportKind.message : undefined; } +function getSupportMessageSuppression(supportKind: AdapterSupport): 'all' | 'default' | undefined { + return typeof supportKind === 'object' ? supportKind.suppress : undefined; +} + function validateSupportKind( supportKind: AdapterSupport, adapterName: string, @@ -117,6 +121,7 @@ function validateSupportKind( ): boolean { const supportValue = unwrapSupportKind(supportKind); const message = getSupportMessage(supportKind); + const suppress = getSupportMessageSuppression(supportKind); if (!supportValue) { return false; @@ -126,7 +131,7 @@ function validateSupportKind( 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); + logFeatureSupport(adapterName, logger, featureName, supportValue, message, suppress); } return false; @@ -138,38 +143,41 @@ function logFeatureSupport( featureName: string, supportKind: AdapterSupport, adapterMessage?: string, + suppress?: 'all' | 'default', ) { - 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 (!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 - if (adapterMessage) { + // If the adapter specified a custom message, log it after the default message (when not suppressed) + if (adapterMessage && suppress !== 'all') { logger.warn('adapter', adapterMessage); } } diff --git a/packages/astro/src/types/public/integrations.ts b/packages/astro/src/types/public/integrations.ts index 2d0b13e96300..6bb437f31509 100644 --- a/packages/astro/src/types/public/integrations.ts +++ b/packages/astro/src/types/public/integrations.ts @@ -67,6 +67,15 @@ export type AdapterSupportsKind = export type AdapterSupportWithMessage = { support: Exclude; message: string; + /** + * Determines if a feature support warning/error in the adapter should be suppressed: + * - `"default"`: Suppresses the default warning/error message. + * - `"all"`: Suppresses both the custom and the default warning/error message. + * + * This is useful when the warning/error might not be applicable in certain contexts, + * or the default message might cause confusion and conflict with a custom one. + */ + suppress?: 'all' | 'default'; }; export type AdapterSupport = AdapterSupportsKind | AdapterSupportWithMessage; diff --git a/packages/astro/test/fixtures/feature-support-message-suppresion/astro.config.mjs b/packages/astro/test/fixtures/feature-support-message-suppresion/astro.config.mjs new file mode 100644 index 000000000000..a28113763aff --- /dev/null +++ b/packages/astro/test/fixtures/feature-support-message-suppresion/astro.config.mjs @@ -0,0 +1,29 @@ +import { defineConfig } from 'astro/config'; +export default defineConfig({ + integrations: [ + { + name: 'astro-test-feature-support-message-suppression', + hooks: { + 'astro:config:done': ({ setAdapter }) => { + setAdapter({ + name: 'astro-test-feature-support-message-suppression', + supportedAstroFeatures: { + staticOutput: "stable", + hybridOutput: "stable", + serverOutput: { + support: "experimental", + message: "This should be logged.", + suppress: "default", + }, + sharpImageService: { + support: 'limited', + message: 'This shouldn\'t be logged.', + suppress: "all", + }, + } + }) + }, + }, + }, + ], +}); diff --git a/packages/astro/test/fixtures/feature-support-message-suppresion/package.json b/packages/astro/test/fixtures/feature-support-message-suppresion/package.json new file mode 100644 index 000000000000..f34355172460 --- /dev/null +++ b/packages/astro/test/fixtures/feature-support-message-suppresion/package.json @@ -0,0 +1,15 @@ +{ + "name": "@test/feature-support-message-suppresion", + "type": "module", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/feature-support-message-suppresion/src/pages/index.astro b/packages/astro/test/fixtures/feature-support-message-suppresion/src/pages/index.astro new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6457aedc5ac4..3e627fd964e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3086,6 +3086,12 @@ importers: specifier: workspace:* version: link:../../.. + packages/astro/test/fixtures/feature-support-message-suppresion: + dependencies: + astro: + specifier: workspace:* + version: link:../../.. + packages/astro/test/fixtures/fetch: dependencies: '@astrojs/preact':