refactor: internal refactor to use the Logger (#8227)

This commit is contained in:
Emanuele Stoppa 2023-08-25 15:57:47 +01:00 committed by GitHub
parent 2c07656c8d
commit f91acd8fca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 529 additions and 620 deletions

View file

@ -20,7 +20,7 @@ import type { AstroConfigType } from '../core/config';
import type { AstroTimer } from '../core/config/timer';
import type { AstroCookies } from '../core/cookies';
import type { ResponseWithEncoding } from '../core/endpoint/index.js';
import type { AstroIntegrationLogger, LogOptions, LoggerLevel } from '../core/logger/core';
import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger/core';
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
@ -1399,7 +1399,7 @@ export interface AstroInlineOnlyConfig {
/**
* @internal for testing only, use `logLevel` instead.
*/
logging?: LogOptions;
logger?: Logger;
}
export type ContentEntryModule = {
@ -2067,7 +2067,7 @@ export type AstroMiddlewareInstance<R> = {
export interface AstroPluginOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}
export type RouteType = 'page' | 'endpoint' | 'redirect';

View file

@ -1,13 +1,12 @@
import fs, { readFileSync } from 'node:fs';
import { basename, join } from 'node:path/posix';
import type { StaticBuildOptions } from '../../core/build/types.js';
import { warn } from '../../core/logger/core.js';
import { prependForwardSlash } from '../../core/path.js';
import { isServerLikeOutput } from '../../prerender/utils.js';
import { getConfiguredImageService, isESMImportedImage } from '../internal.js';
import type { LocalImageService } from '../services/service.js';
import type { ImageMetadata, ImageTransform } from '../types.js';
import { loadRemoteImage, type RemoteCacheEntry } from './remote.js';
import type { BuildPipeline } from '../../core/build/buildPipeline';
interface GenerationDataUncached {
cached: false;
@ -24,19 +23,20 @@ interface GenerationDataCached {
type GenerationData = GenerationDataUncached | GenerationDataCached;
export async function generateImage(
buildOpts: StaticBuildOptions,
pipeline: BuildPipeline,
options: ImageTransform,
filepath: string
): Promise<GenerationData | undefined> {
const config = pipeline.getConfig();
const logger = pipeline.getLogger();
let useCache = true;
const assetsCacheDir = new URL('assets/', buildOpts.settings.config.cacheDir);
const assetsCacheDir = new URL('assets/', config.cacheDir);
// Ensure that the cache directory exists
try {
await fs.promises.mkdir(assetsCacheDir, { recursive: true });
} catch (err) {
warn(
buildOpts.logging,
logger.warn(
'astro:assets',
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${err}`
);
@ -44,12 +44,12 @@ export async function generateImage(
}
let serverRoot: URL, clientRoot: URL;
if (isServerLikeOutput(buildOpts.settings.config)) {
serverRoot = buildOpts.settings.config.build.server;
clientRoot = buildOpts.settings.config.build.client;
if (isServerLikeOutput(config)) {
serverRoot = config.build.server;
clientRoot = config.build.client;
} else {
serverRoot = buildOpts.settings.config.outDir;
clientRoot = buildOpts.settings.config.outDir;
serverRoot = config.outDir;
clientRoot = config.outDir;
}
const isLocalImage = isESMImportedImage(options.src);
@ -105,10 +105,7 @@ export async function generateImage(
if (isLocalImage) {
imageData = await fs.promises.readFile(
new URL(
'.' +
prependForwardSlash(
join(buildOpts.settings.config.build.assets, basename(originalImagePath))
),
'.' + prependForwardSlash(join(config.build.assets, basename(originalImagePath))),
serverRoot
)
);
@ -120,11 +117,7 @@ export async function generateImage(
const imageService = (await getConfiguredImageService()) as LocalImageService;
resultData.data = (
await imageService.transform(
imageData,
{ ...options, src: originalImagePath },
buildOpts.settings.config.image
)
await imageService.transform(imageData, { ...options, src: originalImagePath }, config.image)
).data;
try {
@ -143,8 +136,7 @@ export async function generateImage(
}
}
} catch (e) {
warn(
buildOpts.logging,
logger.warn(
'astro:assets',
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${e}`
);

View file

@ -16,14 +16,14 @@ import {
updateTSConfigForFramework,
type frameworkWithTSSettings,
} from '../../core/config/tsconfig.js';
import { debug, info, type LogOptions } from '../../core/logger/core.js';
import type { Logger } from '../../core/logger/core.js';
import * as msg from '../../core/messages.js';
import { printHelp } from '../../core/messages.js';
import { appendForwardSlash } from '../../core/path.js';
import { apply as applyPolyfill } from '../../core/polyfill.js';
import { parseNpmName } from '../../core/util.js';
import { eventCliSession, telemetry } from '../../events/index.js';
import { createLoggingFromFlags } from '../flags.js';
import { createLoggerFromFlags } from '../flags.js';
import { generate, parse, t, visit } from './babel.js';
import { ensureImport } from './imports.js';
import { wrapDefaultExport } from './wrapper.js';
@ -130,10 +130,10 @@ export async function add(names: string[], { flags }: AddOptions) {
// Some packages might have a common alias! We normalize those here.
const cwd = flags.root;
const logging = createLoggingFromFlags(flags);
const logger = createLoggerFromFlags(flags);
const integrationNames = names.map((name) => (ALIASES.has(name) ? ALIASES.get(name)! : name));
const integrations = await validateIntegrations(integrationNames);
let installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logging });
let installResult = await tryToInstallIntegrations({ integrations, cwd, flags, logger });
const rootPath = resolveRoot(cwd);
const root = pathToFileURL(rootPath);
// Append forward slash to compute relative paths
@ -144,7 +144,8 @@ export async function add(names: string[], { flags }: AddOptions) {
if (integrations.find((integration) => integration.id === 'tailwind')) {
await setupIntegrationConfig({
root,
logging,
logger,
flags,
integrationName: 'Tailwind',
possibleConfigFiles: [
@ -159,7 +160,7 @@ export async function add(names: string[], { flags }: AddOptions) {
if (integrations.find((integration) => integration.id === 'svelte')) {
await setupIntegrationConfig({
root,
logging,
logger,
flags,
integrationName: 'Svelte',
possibleConfigFiles: ['./svelte.config.js', './svelte.config.cjs', './svelte.config.mjs'],
@ -175,7 +176,7 @@ export async function add(names: string[], { flags }: AddOptions) {
) {
await setupIntegrationConfig({
root,
logging,
logger,
flags,
integrationName: 'Lit',
possibleConfigFiles: ['./.npmrc'],
@ -186,8 +187,7 @@ export async function add(names: string[], { flags }: AddOptions) {
break;
}
case UpdateResult.cancelled: {
info(
logging,
logger.info(
null,
msg.cancelled(
`Dependencies ${bold('NOT')} installed.`,
@ -209,9 +209,9 @@ export async function add(names: string[], { flags }: AddOptions) {
let configURL = rawConfigPath ? pathToFileURL(rawConfigPath) : undefined;
if (configURL) {
debug('add', `Found config at ${configURL}`);
logger.debug('add', `Found config at ${configURL}`);
} else {
info(logging, 'add', `Unable to locate a config file, generating one for you.`);
logger.info('add', `Unable to locate a config file, generating one for you.`);
configURL = new URL('./astro.config.mjs', root);
await fs.writeFile(fileURLToPath(configURL), ASTRO_CONFIG_STUB, { encoding: 'utf-8' });
}
@ -220,7 +220,7 @@ export async function add(names: string[], { flags }: AddOptions) {
try {
ast = await parseAstroConfig(configURL);
debug('add', 'Parsed astro config');
logger.debug('add', 'Parsed astro config');
const defineConfig = t.identifier('defineConfig');
ensureImport(
@ -232,7 +232,7 @@ export async function add(names: string[], { flags }: AddOptions) {
);
wrapDefaultExport(ast, defineConfig);
debug('add', 'Astro config ensured `defineConfig`');
logger.debug('add', 'Astro config ensured `defineConfig`');
for (const integration of integrations) {
if (isAdapter(integration)) {
@ -240,8 +240,7 @@ export async function add(names: string[], { flags }: AddOptions) {
if (officialExportName) {
await setAdapter(ast, integration, officialExportName);
} else {
info(
logging,
logger.info(
null,
`\n ${magenta(
`Check our deployment docs for ${bold(
@ -253,10 +252,10 @@ export async function add(names: string[], { flags }: AddOptions) {
} else {
await addIntegration(ast, integration);
}
debug('add', `Astro config added integration ${integration.id}`);
logger.debug('add', `Astro config added integration ${integration.id}`);
}
} catch (err) {
debug('add', 'Error parsing/modifying astro config: ', err);
logger.debug('add', 'Error parsing/modifying astro config: ', err);
throw createPrettyError(err as Error);
}
@ -268,18 +267,18 @@ export async function add(names: string[], { flags }: AddOptions) {
configURL,
ast,
flags,
logging,
logger,
logAdapterInstructions: integrations.some(isAdapter),
});
} catch (err) {
debug('add', 'Error updating astro config', err);
logger.debug('add', 'Error updating astro config', err);
throw createPrettyError(err as Error);
}
}
switch (configResult) {
case UpdateResult.cancelled: {
info(logging, null, msg.cancelled(`Your configuration has ${bold('NOT')} been updated.`));
logger.info(null, msg.cancelled(`Your configuration has ${bold('NOT')} been updated.`));
break;
}
case UpdateResult.none: {
@ -293,18 +292,17 @@ export async function add(names: string[], { flags }: AddOptions) {
(integration) => !deps.includes(integration.packageName)
);
if (missingDeps.length === 0) {
info(logging, null, msg.success(`Configuration up-to-date.`));
logger.info(null, msg.success(`Configuration up-to-date.`));
break;
}
}
info(logging, null, msg.success(`Configuration up-to-date.`));
logger.info(null, msg.success(`Configuration up-to-date.`));
break;
}
default: {
const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n');
info(
logging,
logger.info(
null,
msg.success(
`Added the following integration${
@ -315,15 +313,14 @@ export async function add(names: string[], { flags }: AddOptions) {
}
}
const updateTSConfigResult = await updateTSConfig(cwd, logging, integrations, flags);
const updateTSConfigResult = await updateTSConfig(cwd, logger, integrations, flags);
switch (updateTSConfigResult) {
case UpdateResult.none: {
break;
}
case UpdateResult.cancelled: {
info(
logging,
logger.info(
null,
msg.cancelled(`Your TypeScript configuration has ${bold('NOT')} been updated.`)
);
@ -335,7 +332,7 @@ export async function add(names: string[], { flags }: AddOptions) {
);
}
default:
info(logging, null, msg.success(`Successfully updated TypeScript settings`));
logger.info(null, msg.success(`Successfully updated TypeScript settings`));
}
}
@ -529,13 +526,13 @@ async function updateAstroConfig({
configURL,
ast,
flags,
logging,
logger,
logAdapterInstructions,
}: {
configURL: URL;
ast: t.File;
flags: yargs.Arguments;
logging: LogOptions;
logger: Logger;
logAdapterInstructions: boolean;
}): Promise<UpdateResult> {
const input = await fs.readFile(fileURLToPath(configURL), { encoding: 'utf-8' });
@ -562,15 +559,13 @@ async function updateAstroConfig({
title: configURL.pathname.split('/').pop(),
})}\n`;
info(
logging,
logger.info(
null,
`\n ${magenta('Astro will make the following changes to your config file:')}\n${message}`
);
if (logAdapterInstructions) {
info(
logging,
logger.info(
null,
magenta(
` For complete deployment options, visit\n ${bold(
@ -582,7 +577,7 @@ async function updateAstroConfig({
if (await askToContinue({ flags })) {
await fs.writeFile(fileURLToPath(configURL), output, { encoding: 'utf-8' });
debug('add', `Updated astro config`);
logger.debug('add', `Updated astro config`);
return UpdateResult.updated;
} else {
return UpdateResult.cancelled;
@ -598,13 +593,15 @@ interface InstallCommand {
async function getInstallIntegrationsCommand({
integrations,
logger,
cwd = process.cwd(),
}: {
integrations: IntegrationInfo[];
logger: Logger;
cwd?: string;
}): Promise<InstallCommand | null> {
const pm = await preferredPM(cwd);
debug('add', `package manager: ${JSON.stringify(pm)}`);
logger.debug('add', `package manager: ${JSON.stringify(pm)}`);
if (!pm) return null;
let dependencies = integrations
@ -644,14 +641,14 @@ async function tryToInstallIntegrations({
integrations,
cwd,
flags,
logging,
logger,
}: {
integrations: IntegrationInfo[];
cwd?: string;
flags: yargs.Arguments;
logging: LogOptions;
logger: Logger;
}): Promise<UpdateResult> {
const installCommand = await getInstallIntegrationsCommand({ integrations, cwd });
const installCommand = await getInstallIntegrationsCommand({ integrations, cwd, logger });
const inheritedFlags = Object.entries(flags)
.map(([flag]) => {
@ -677,8 +674,7 @@ async function tryToInstallIntegrations({
padding: 0.5,
borderStyle: 'round',
})}\n`;
info(
logging,
logger.info(
null,
`\n ${magenta('Astro will run the following command:')}\n ${dim(
'If you skip this step, you can always run it yourself later'
@ -702,7 +698,7 @@ async function tryToInstallIntegrations({
return UpdateResult.updated;
} catch (err) {
spinner.fail();
debug('add', 'Error installing dependencies', err);
logger.debug('add', 'Error installing dependencies', err);
// eslint-disable-next-line no-console
console.error('\n', (err as any).stdout, '\n');
return UpdateResult.failure;
@ -829,7 +825,7 @@ export async function validateIntegrations(integrations: string[]): Promise<Inte
async function updateTSConfig(
cwd = process.cwd(),
logging: LogOptions,
logger: Logger,
integrationsInfo: IntegrationInfo[],
flags: yargs.Arguments
): Promise<UpdateResult> {
@ -852,7 +848,7 @@ async function updateTSConfig(
}
if (inputConfig.reason === 'not-found') {
debug('add', "Couldn't find tsconfig.json or jsconfig.json, generating one");
logger.debug('add', "Couldn't find tsconfig.json or jsconfig.json, generating one");
}
const outputConfig = updateTSConfigForFramework(
@ -875,8 +871,7 @@ async function updateTSConfig(
title: configFileName,
})}\n`;
info(
logging,
logger.info(
null,
`\n ${magenta(`Astro will make the following changes to your ${configFileName}:`)}\n${message}`
);
@ -890,8 +885,7 @@ async function updateTSConfig(
integrations.filter((integration) => conflictingIntegrations.includes(integration)).length > 0;
if (hasConflictingIntegrations) {
info(
logging,
logger.info(
null,
red(
` ${bold(
@ -907,7 +901,7 @@ async function updateTSConfig(
await fs.writeFile(inputConfig?.path ?? path.join(cwd, 'tsconfig.json'), output, {
encoding: 'utf-8',
});
debug('add', `Updated ${configFileName} file`);
logger.debug('add', `Updated ${configFileName} file`);
return UpdateResult.updated;
} else {
return UpdateResult.cancelled;
@ -971,13 +965,14 @@ function getDiffContent(input: string, output: string): string | null {
async function setupIntegrationConfig(opts: {
root: URL;
logging: LogOptions;
logger: Logger;
flags: yargs.Arguments;
integrationName: string;
possibleConfigFiles: string[];
defaultConfigFile: string;
defaultConfigContent: string;
}) {
const logger = opts.logger;
const possibleConfigFiles = opts.possibleConfigFiles.map((p) =>
fileURLToPath(new URL(p, opts.root))
);
@ -989,8 +984,7 @@ async function setupIntegrationConfig(opts: {
}
}
if (!alreadyConfigured) {
info(
opts.logging,
logger.info(
null,
`\n ${magenta(`Astro will generate a minimal ${bold(opts.defaultConfigFile)} file.`)}\n`
);
@ -1002,9 +996,9 @@ async function setupIntegrationConfig(opts: {
encoding: 'utf-8',
}
);
debug('add', `Generated default ${opts.defaultConfigFile} file`);
logger.debug('add', `Generated default ${opts.defaultConfigFile} file`);
}
} else {
debug('add', `Using existing ${opts.integrationName} configuration`);
logger.debug('add', `Using existing ${opts.integrationName} configuration`);
}
}

View file

@ -1,23 +1,21 @@
import path from 'node:path';
import type { Arguments } from 'yargs-parser';
import { error, info } from '../../core/logger/core.js';
import { createLoggingFromFlags, flagsToAstroInlineConfig } from '../flags.js';
import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js';
import { getPackage } from '../install-package.js';
export async function check(flags: Arguments) {
const logging = createLoggingFromFlags(flags);
const logger = createLoggerFromFlags(flags);
const getPackageOpts = { skipAsk: flags.yes || flags.y, cwd: flags.root };
const checkPackage = await getPackage<typeof import('@astrojs/check')>(
'@astrojs/check',
logging,
logger,
getPackageOpts,
['typescript']
);
const typescript = await getPackage('typescript', logging, getPackageOpts);
const typescript = await getPackage('typescript', logger, getPackageOpts);
if (!checkPackage || !typescript) {
error(
logging,
logger.error(
'check',
'The `@astrojs/check` and `typescript` packages are required for this command to work. Please manually install them into your project and try again.'
);
@ -38,6 +36,6 @@ export async function check(flags: Arguments) {
const config = parseArgsAsCheckConfig(process.argv);
info(logging, 'check', `Getting diagnostics for Astro files in ${path.resolve(config.root)}...`);
logger.info('check', `Getting diagnostics for Astro files in ${path.resolve(config.root)}...`);
return await checker(config);
}

View file

@ -1,6 +1,6 @@
import type { Arguments as Flags } from 'yargs-parser';
import type { AstroInlineConfig } from '../@types/astro.js';
import type { LogOptions } from '../core/logger/core.js';
import { Logger, type LogOptions } from '../core/logger/core.js';
import { nodeLogDestination } from '../core/logger/node.js';
export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig {
@ -30,7 +30,7 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig {
* The `logging` is usually created from an `AstroInlineConfig`, but some flows like `add`
* doesn't read the AstroConfig directly, so we create a `logging` object from the CLI flags instead.
*/
export function createLoggingFromFlags(flags: Flags): LogOptions {
export function createLoggerFromFlags(flags: Flags): Logger {
const logging: LogOptions = {
dest: nodeLogDestination,
level: 'info',
@ -42,5 +42,5 @@ export function createLoggingFromFlags(flags: Flags): LogOptions {
logging.level = 'silent';
}
return logging;
return new Logger(logging);
}

View file

@ -5,7 +5,7 @@ import { createRequire } from 'node:module';
import ora from 'ora';
import prompts from 'prompts';
import whichPm from 'which-pm';
import { debug, info, type LogOptions } from '../core/logger/core.js';
import { type Logger } from '../core/logger/core.js';
type GetPackageOptions = {
skipAsk?: boolean;
@ -14,7 +14,7 @@ type GetPackageOptions = {
export async function getPackage<T>(
packageName: string,
logging: LogOptions,
logger: Logger,
options: GetPackageOptions,
otherDeps: string[] = []
): Promise<T | undefined> {
@ -27,12 +27,11 @@ export async function getPackage<T>(
// The `require.resolve` is required as to avoid Node caching the failed `import`
packageImport = await import(packageName);
} catch (e) {
info(
logging,
logger.info(
'',
`To continue, Astro requires the following dependency to be installed: ${bold(packageName)}.`
);
const result = await installPackage([packageName, ...otherDeps], options, logging);
const result = await installPackage([packageName, ...otherDeps], options, logger);
if (result) {
packageImport = await import(packageName);
@ -60,7 +59,7 @@ function getInstallCommand(packages: string[], packageManager: string) {
async function installPackage(
packageNames: string[],
options: GetPackageOptions,
logging: LogOptions
logger: Logger
): Promise<boolean> {
const cwd = options.cwd ?? process.cwd();
const packageManager = (await whichPm(cwd)).name ?? 'npm';
@ -79,8 +78,7 @@ async function installPackage(
padding: 0.5,
borderStyle: 'round',
})}\n`;
info(
logging,
logger.info(
null,
`\n ${magenta('Astro will run the following command:')}\n ${dim(
'If you skip this step, you can always run it yourself later'
@ -113,7 +111,7 @@ async function installPackage(
return true;
} catch (err) {
debug('add', 'Error installing dependencies', err);
logger.debug('add', 'Error installing dependencies', err);
spinner.fail();
return false;

View file

@ -1,6 +1,6 @@
import type { UserConfig } from 'vite';
import type { AstroUserConfig } from '../@types/astro';
import type { LogOptions } from '../core/logger/core';
import { Logger } from '../core/logger/core';
export function defineConfig(config: AstroUserConfig) {
return config;
@ -30,24 +30,24 @@ export function getViteConfig(inlineConfig: UserConfig) {
import('../integrations/index.js'),
import('./vite-plugin-content-listen.js'),
]);
const logging: LogOptions = {
const logger = new Logger({
dest: nodeLogDestination,
level: 'info',
};
});
const { astroConfig: config } = await resolveConfig({}, cmd);
const settings = createSettings(config, inlineConfig.root);
await runHookConfigSetup({ settings, command: cmd, logging });
await runHookConfigSetup({ settings, command: cmd, logger });
const viteConfig = await createVite(
{
mode,
plugins: [
// Initialize the content listener
astroContentListenPlugin({ settings, logging, fs }),
astroContentListenPlugin({ settings, logger, fs }),
],
},
{ settings, logging: logging, mode }
{ settings, logger, mode }
);
await runHookConfigDone({ settings, logging });
await runHookConfigDone({ settings, logger });
return mergeConfig(viteConfig, inlineConfig);
};
}

View file

@ -2,7 +2,7 @@ import type fsMod from 'node:fs';
import type { Plugin, ViteDevServer } from 'vite';
import type { AstroSettings } from '../@types/astro';
import { attachContentServerListeners } from '../content/server-listeners.js';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
/**
* Listen for Astro content directory changes and generate types.
@ -14,11 +14,11 @@ import type { LogOptions } from '../core/logger/core.js';
*/
export function astroContentListenPlugin({
settings,
logging,
logger,
fs,
}: {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
fs: typeof fsMod;
}): Plugin {
let server: ViteDevServer;
@ -33,7 +33,7 @@ export function astroContentListenPlugin({
await attachContentServerListeners({
fs: fs,
settings,
logging,
logger,
viteServer: server,
});
},

View file

@ -5,14 +5,14 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
import type { ViteDevServer } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import { loadTSConfig } from '../core/config/tsconfig.js';
import { info, warn, type LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import { appendForwardSlash } from '../core/path.js';
import { createContentTypesGenerator } from './types-generator.js';
import { getContentPaths, globalContentConfigObserver, type ContentPaths } from './utils.js';
interface ContentServerListenerParams {
fs: typeof fsMod;
logging: LogOptions;
logger: Logger;
settings: AstroSettings;
viteServer: ViteDevServer;
}
@ -20,27 +20,26 @@ interface ContentServerListenerParams {
export async function attachContentServerListeners({
viteServer,
fs,
logging,
logger,
settings,
}: ContentServerListenerParams) {
const contentPaths = getContentPaths(settings.config, fs);
if (fs.existsSync(contentPaths.contentDir)) {
info(
logging,
logger.info(
'content',
`Watching ${cyan(
contentPaths.contentDir.href.replace(settings.config.root.href, '')
)} for changes`
);
const maybeTsConfigStats = getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings });
if (maybeTsConfigStats) warnAllowJsIsFalse({ ...maybeTsConfigStats, logging });
if (maybeTsConfigStats) warnAllowJsIsFalse({ ...maybeTsConfigStats, logger });
await attachListeners();
} else {
viteServer.watcher.on('addDir', contentDirListener);
async function contentDirListener(dir: string) {
if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) {
info(logging, 'content', `Content dir found. Watching for changes`);
logger.info('content', `Content dir found. Watching for changes`);
await attachListeners();
viteServer.watcher.removeListener('addDir', contentDirListener);
}
@ -51,12 +50,12 @@ export async function attachContentServerListeners({
const contentGenerator = await createContentTypesGenerator({
fs,
settings,
logging,
logger,
viteServer,
contentConfigObserver: globalContentConfigObserver,
});
await contentGenerator.init();
info(logging, 'content', 'Types generated');
logger.info('content', 'Types generated');
viteServer.watcher.on('add', (entry) => {
contentGenerator.queueEvent({ name: 'add', entry });
@ -77,26 +76,24 @@ export async function attachContentServerListeners({
}
function warnAllowJsIsFalse({
logging,
logger,
tsConfigFileName,
contentConfigFileName,
}: {
logging: LogOptions;
logger: Logger;
tsConfigFileName: string;
contentConfigFileName: string;
}) {
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.
logger.warn(
'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({

View file

@ -7,7 +7,6 @@ import { normalizePath, type ViteDevServer } from 'vite';
import type { AstroSettings, ContentEntryType } from '../@types/astro.js';
import { AstroError } from '../core/errors/errors.js';
import { AstroErrorData } from '../core/errors/index.js';
import { info, warn, type LogOptions } from '../core/logger/core.js';
import { isRelativePath } from '../core/path.js';
import { CONTENT_TYPES_FILE, VIRTUAL_MODULE_ID } from './consts.js';
import {
@ -24,6 +23,7 @@ import {
type ContentObservable,
type ContentPaths,
} from './utils.js';
import type { Logger } from '../core/logger/core';
type ChokidarEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir';
type RawContentEvent = { name: ChokidarEvent; entry: string };
@ -49,7 +49,7 @@ type CollectionEntryMap = {
type CreateContentGeneratorParams = {
contentConfigObserver: ContentObservable;
logging: LogOptions;
logger: Logger;
settings: AstroSettings;
/** This is required for loading the content config */
viteServer: ViteDevServer;
@ -68,7 +68,7 @@ class UnsupportedFileTypeError extends Error {}
export async function createContentTypesGenerator({
contentConfigObserver,
fs,
logging,
logger,
settings,
viteServer,
}: CreateContentGeneratorParams) {
@ -140,7 +140,7 @@ export async function createContentTypesGenerator({
case 'addDir':
collectionEntryMap[JSON.stringify(collection)] = { type: 'unknown', entries: {} };
if (logLevel === 'info') {
info(logging, 'content', `${cyan(collection)} collection added`);
logger.info('content', `${cyan(collection)} collection added`);
}
break;
case 'unlinkDir':
@ -186,8 +186,7 @@ export async function createContentTypesGenerator({
const collection = getEntryCollectionName({ entry, contentDir });
if (collection === undefined) {
if (['info', 'warn'].includes(logLevel)) {
warn(
logging,
logger.warn(
'content',
`${cyan(
normalizePath(
@ -350,8 +349,7 @@ export async function createContentTypesGenerator({
}
}
if (unsupportedFiles.length > 0 && ['info', 'warn'].includes(logLevel)) {
warn(
logging,
logger.warn(
'content',
`Unsupported file types found. Prefix with an underscore (\`_\`) to ignore:\n- ${unsupportedFiles.join(
'\n'
@ -372,7 +370,7 @@ export async function createContentTypesGenerator({
invalidateVirtualMod(viteServer);
if (observable.status === 'loaded' && ['info', 'warn'].includes(logLevel)) {
warnNonexistentCollections({
logging,
logger,
contentConfig: observable.config,
collectionEntryMap,
});
@ -505,16 +503,15 @@ async function writeContentFiles({
function warnNonexistentCollections({
contentConfig,
collectionEntryMap,
logging,
logger,
}: {
contentConfig: ContentConfig;
collectionEntryMap: CollectionEntryMap;
logging: LogOptions;
logger: Logger;
}) {
for (const configuredCollection in contentConfig.collections) {
if (!collectionEntryMap[JSON.stringify(configuredCollection)]) {
warn(
logging,
logger.warn(
'content',
`The ${JSON.stringify(
configuredCollection

View file

@ -9,7 +9,7 @@ import type {
import type { SinglePageBuiltModule } from '../build/types';
import { getSetCookiesFromResponse } from '../cookies/index.js';
import { consoleLogDestination } from '../logger/console.js';
import { error, warn, type LogOptions } from '../logger/core.js';
import { Logger } from '../logger/core.js';
import {
collapseDuplicateSlashes,
prependForwardSlash,
@ -50,10 +50,10 @@ export class App {
#manifest: SSRManifest;
#manifestData: ManifestData;
#routeDataToRouteInfo: Map<RouteData, RouteInfo>;
#logging: LogOptions = {
#logger = new Logger({
dest: consoleLogDestination,
level: 'info',
};
});
#baseWithoutTrailingSlash: string;
#pipeline: SSRRoutePipeline;
#onRequest: MiddlewareEndpointHandler | undefined;
@ -83,7 +83,7 @@ export class App {
#createEnvironment(streaming = false) {
return createEnvironment({
adapterName: this.#manifest.adapterName,
logging: this.#logging,
logger: this.#logger,
mode: 'production',
compressHTML: this.#manifest.compressHTML,
renderers: this.#manifest.renderers,
@ -103,7 +103,7 @@ export class App {
}
}
},
routeCache: new RouteCache(this.#logging),
routeCache: new RouteCache(this.#logger),
site: this.#manifest.site,
ssr: true,
streaming,
@ -138,7 +138,7 @@ export class App {
const middleware = await import(this.#manifest.middlewareEntryPoint);
this.#pipeline.setMiddlewareFunction(middleware.onRequest as MiddlewareEndpointHandler);
} catch (e) {
warn(this.#logging, 'SSR', "Couldn't load the middleware entry point");
this.#logger.warn('SSR', "Couldn't load the middleware entry point");
}
}
this.#middlewareLoaded = true;
@ -178,7 +178,7 @@ export class App {
if (err instanceof EndpointNotFoundError) {
return this.#renderError(request, { status: 404, response: err.originalResponse });
} else {
error(this.#logging, 'ssr', err.stack || err.message || String(err));
this.#logger.error('ssr', err.stack || err.message || String(err));
return this.#renderError(request, { status: 500 });
}
}

View file

@ -10,6 +10,7 @@ import { ASTRO_PAGE_RESOLVED_MODULE_ID } from './plugins/plugin-pages.js';
import { RESOLVED_SPLIT_MODULE_ID } from './plugins/plugin-ssr.js';
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from './plugins/util.js';
import type { PageBuildData, StaticBuildOptions } from './types';
import { Logger } from '../logger/core.js';
/**
* This pipeline is responsible to gather the files emitted by the SSR build and generate the pages by executing these files.
@ -28,7 +29,7 @@ export class BuildPipeline extends Pipeline {
super(
createEnvironment({
adapterName: manifest.adapterName,
logging: staticBuildOptions.logging,
logger: staticBuildOptions.logger,
mode: staticBuildOptions.mode,
renderers: manifest.renderers,
clientDirectives: manifest.clientDirectives,
@ -84,6 +85,10 @@ export class BuildPipeline extends Pipeline {
}
}
getLogger(): Logger {
return this.getEnvironment().logger;
}
/**
* The SSR build emits two important files:
* - dist/server/manifest.mjs

View file

@ -32,7 +32,6 @@ import { runHookBuildGenerated } from '../../integrations/index.js';
import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js';
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { Logger, debug, info } from '../logger/core.js';
import { RedirectSinglePageBuiltModule, getRedirectLocationOrThrow } from '../redirects/index.js';
import { createRenderContext } from '../render/index.js';
import { callGetStaticPaths } from '../render/route-cache.js';
@ -120,7 +119,6 @@ export function chunkIsPage(
}
export async function generatePages(opts: StaticBuildOptions, internals: BuildInternals) {
const logger = new Logger(opts.logging);
const timer = performance.now();
const ssr = isServerLikeOutput(opts.settings.config);
let manifest: SSRManifest;
@ -136,12 +134,13 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
renderers.renderers as SSRLoadedRenderer[]
);
}
const buildPipeline = new BuildPipeline(opts, internals, manifest);
await buildPipeline.retrieveMiddlewareFunction();
const pipeline = new BuildPipeline(opts, internals, manifest);
await pipeline.retrieveMiddlewareFunction();
const outFolder = ssr
? opts.settings.config.build.server
: getOutDirWithinCwd(opts.settings.config.outDir);
const logger = pipeline.getLogger();
// HACK! `astro:assets` relies on a global to know if its running in dev, prod, ssr, ssg, full moon
// If we don't delete it here, it's technically not impossible (albeit improbable) for it to leak
if (ssr && !hasPrerenderedPages(internals)) {
@ -150,9 +149,9 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
}
const verb = ssr ? 'prerendering' : 'generating';
info(opts.logging, null, `\n${bgGreen(black(` ${verb} static routes `))}`);
logger.info(null, `\n${bgGreen(black(` ${verb} static routes `))}`);
const builtPaths = new Set<string>();
const pagesToGenerate = buildPipeline.retrieveRoutesToGenerate();
const pagesToGenerate = pipeline.retrieveRoutesToGenerate();
if (ssr) {
for (const [pageData, filePath] of pagesToGenerate) {
if (pageData.route.prerender) {
@ -166,7 +165,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
// forcing to use undefined, so we fail in an expected way if the module is not even there.
const ssrEntry = ssrEntryPage?.manifest?.pageModule;
if (ssrEntry) {
await generatePage(pageData, ssrEntry, builtPaths, buildPipeline, logger);
await generatePage(pageData, ssrEntry, builtPaths, pipeline);
} else {
throw new Error(
`Unable to find the manifest for the module ${ssrEntryURLPage.toString()}. This is unexpected and likely a bug in Astro, please report.`
@ -174,46 +173,47 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
}
} else {
const ssrEntry = ssrEntryPage as SinglePageBuiltModule;
await generatePage(pageData, ssrEntry, builtPaths, buildPipeline, logger);
await generatePage(pageData, ssrEntry, builtPaths, pipeline);
}
}
if (pageData.route.type === 'redirect') {
const entry = await getEntryForRedirectRoute(pageData.route, internals, outFolder);
await generatePage(pageData, entry, builtPaths, buildPipeline, logger);
await generatePage(pageData, entry, builtPaths, pipeline);
}
}
} else {
for (const [pageData, filePath] of pagesToGenerate) {
if (pageData.route.type === 'redirect') {
const entry = await getEntryForRedirectRoute(pageData.route, internals, outFolder);
await generatePage(pageData, entry, builtPaths, buildPipeline, logger);
await generatePage(pageData, entry, builtPaths, pipeline);
} else {
const ssrEntryURLPage = createEntryURL(filePath, outFolder);
const entry: SinglePageBuiltModule = await import(ssrEntryURLPage.toString());
await generatePage(pageData, entry, builtPaths, buildPipeline, logger);
await generatePage(pageData, entry, builtPaths, pipeline);
}
}
}
info(opts.logging, null, `\n${bgGreen(black(` generating optimized images `))}`);
logger.info(null, `\n${bgGreen(black(` generating optimized images `))}`);
for (const imageData of getStaticImageList()) {
await generateImage(opts, imageData[1].options, imageData[1].path);
await generateImage(pipeline, imageData[1].options, imageData[1].path);
}
delete globalThis?.astroAsset?.addStaticImage;
await runHookBuildGenerated({
config: opts.settings.config,
logging: opts.logging,
logger: pipeline.getLogger(),
});
info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
logger.info(null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
}
async function generateImage(opts: StaticBuildOptions, transform: ImageTransform, path: string) {
async function generateImage(pipeline: BuildPipeline, transform: ImageTransform, path: string) {
const logger = pipeline.getLogger();
let timeStart = performance.now();
const generationData = await generateImageInternal(opts, transform, path);
const generationData = await generateImageInternal(pipeline, transform, path);
if (!generationData) {
return;
@ -225,18 +225,17 @@ async function generateImage(opts: StaticBuildOptions, transform: ImageTransform
const statsText = generationData.cached
? `(reused cache entry)`
: `(before: ${generationData.weight.before}kb, after: ${generationData.weight.after}kb)`;
info(opts.logging, null, ` ${green('▶')} ${path} ${dim(statsText)} ${dim(timeIncrease)}`);
logger.info(null, ` ${green('▶')} ${path} ${dim(statsText)} ${dim(timeIncrease)}`);
}
async function generatePage(
pageData: PageBuildData,
ssrEntry: SinglePageBuiltModule,
builtPaths: Set<string>,
pipeline: BuildPipeline,
logger: Logger
pipeline: BuildPipeline
) {
let timeStart = performance.now();
const logger = pipeline.getLogger();
const pageInfo = getPageDataByComponent(pipeline.getInternals(), pageData.route.component);
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
@ -281,12 +280,7 @@ async function generatePage(
}
// Get paths for the route, calling getStaticPaths if needed.
const paths = await getPathsForRoute(
pageData,
pageModule,
pipeline.getStaticBuildOptions(),
builtPaths
);
const paths = await getPathsForRoute(pageData, pageModule, pipeline, builtPaths);
let prevTimeEnd = timeStart;
for (let i = 0; i < paths.length; i++) {
@ -305,9 +299,11 @@ async function generatePage(
async function getPathsForRoute(
pageData: PageBuildData,
mod: ComponentInstance,
opts: StaticBuildOptions,
pipeline: BuildPipeline,
builtPaths: Set<string>
): Promise<Array<string>> {
const opts = pipeline.getStaticBuildOptions();
const logger = pipeline.getLogger();
let paths: Array<string> = [];
if (pageData.route.pathname) {
paths.push(pageData.route.pathname);
@ -318,15 +314,15 @@ async function getPathsForRoute(
mod,
route,
routeCache: opts.routeCache,
logging: opts.logging,
logger,
ssr: isServerLikeOutput(opts.settings.config),
}).catch((err) => {
debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
logger.debug('build', `├── ${colors.bold(colors.red('✗'))} ${route.component}`);
throw err;
});
const label = staticPaths.length === 1 ? 'page' : 'pages';
debug(
logger.debug(
'build',
`├── ${colors.bold(colors.green('✔'))} ${route.component}${colors.magenta(
`[${staticPaths.length} ${label}]`
@ -473,7 +469,7 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli
addPageName(pathname, pipeline.getStaticBuildOptions());
}
debug('build', `Generating: ${pathname}`);
pipeline.getEnvironment().logger.debug('build', `Generating: ${pathname}`);
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
const links = new Set<never>();
@ -520,7 +516,7 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli
request: createRequest({
url,
headers: new Headers(),
logging: pipeline.getStaticBuildOptions().logging,
logger: pipeline.getLogger(),
ssr,
}),
componentMetadata: manifest.componentMetadata,

View file

@ -21,10 +21,10 @@ import {
} from '../../integrations/index.js';
import { isServerLikeOutput } from '../../prerender/utils.js';
import { resolveConfig } from '../config/config.js';
import { createNodeLogging } from '../config/logging.js';
import { createNodeLogger } from '../config/logging.js';
import { createSettings } from '../config/settings.js';
import { createVite } from '../create-vite.js';
import { debug, info, levels, timerMessage, warn, type LogOptions } from '../logger/core.js';
import { levels, timerMessage, Logger } from '../logger/core.js';
import { apply as applyPolyfill } from '../polyfill.js';
import { RouteCache } from '../render/route-cache.js';
import { createRouteManifest } from '../routing/index.js';
@ -55,7 +55,7 @@ export default async function build(
options?: BuildOptions
): Promise<void> {
applyPolyfill();
const logging = createNodeLogging(inlineConfig);
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig, 'build');
telemetry.record(eventCliSession('build', userConfig));
@ -63,20 +63,20 @@ export default async function build(
const builder = new AstroBuilder(settings, {
...options,
logging,
logger,
mode: inlineConfig.mode,
});
await builder.run();
}
interface AstroBuilderOptions extends BuildOptions {
logging: LogOptions;
logger: Logger;
mode?: RuntimeMode;
}
class AstroBuilder {
private settings: AstroSettings;
private logging: LogOptions;
private logger: Logger;
private mode: RuntimeMode = 'production';
private origin: string;
private routeCache: RouteCache;
@ -89,9 +89,9 @@ class AstroBuilder {
this.mode = options.mode;
}
this.settings = settings;
this.logging = options.logging;
this.logger = options.logger;
this.teardownCompiler = options.teardownCompiler ?? true;
this.routeCache = new RouteCache(this.logging);
this.routeCache = new RouteCache(this.logger);
this.origin = settings.config.site
? new URL(settings.config.site).origin
: `http://localhost:${settings.config.server.port}`;
@ -101,20 +101,20 @@ class AstroBuilder {
/** Setup Vite and run any async setup logic that couldn't run inside of the constructor. */
private async setup() {
debug('build', 'Initial setup...');
const { logging } = this;
this.logger.debug('build', 'Initial setup...');
const { logger } = this;
this.timer.init = performance.now();
this.settings = await runHookConfigSetup({
settings: this.settings,
command: 'build',
logging,
logger: logger,
});
if (isServerLikeOutput(this.settings.config)) {
this.settings = injectImageEndpoint(this.settings);
}
this.manifest = createRouteManifest({ settings: this.settings }, this.logging);
this.manifest = createRouteManifest({ settings: this.settings }, this.logger);
const viteConfig = await createVite(
{
@ -124,12 +124,12 @@ class AstroBuilder {
middlewareMode: true,
},
},
{ settings: this.settings, logging, mode: 'build', command: 'build' }
{ settings: this.settings, logger: this.logger, mode: 'build', command: 'build' }
);
await runHookConfigDone({ settings: this.settings, logging });
await runHookConfigDone({ settings: this.settings, logger: logger });
const { syncInternal } = await import('../sync/index.js');
const syncRet = await syncInternal(this.settings, { logging, fs });
const syncRet = await syncInternal(this.settings, { logger: logger, fs });
if (syncRet !== 0) {
return process.exit(syncRet);
}
@ -139,22 +139,22 @@ class AstroBuilder {
/** Run the build logic. build() is marked private because usage should go through ".run()" */
private async build({ viteConfig }: { viteConfig: vite.InlineConfig }) {
await runHookBuildStart({ config: this.settings.config, logging: this.logging });
await runHookBuildStart({ config: this.settings.config, logging: this.logger });
this.validateConfig();
info(this.logging, 'build', `output target: ${colors.green(this.settings.config.output)}`);
this.logger.info('build', `output target: ${colors.green(this.settings.config.output)}`);
if (this.settings.adapter) {
info(this.logging, 'build', `deploy adapter: ${colors.green(this.settings.adapter.name)}`);
this.logger.info('build', `deploy adapter: ${colors.green(this.settings.adapter.name)}`);
}
info(this.logging, 'build', 'Collecting build info...');
this.logger.info('build', 'Collecting build info...');
this.timer.loadStart = performance.now();
const { assets, allPages } = await collectPagesData({
settings: this.settings,
logging: this.logging,
logger: this.logger,
manifest: this.manifest,
});
debug('build', timerMessage('All pages loaded', this.timer.loadStart));
this.logger.debug('build', timerMessage('All pages loaded', this.timer.loadStart));
// The names of each pages
const pageNames: string[] = [];
@ -162,8 +162,7 @@ class AstroBuilder {
// Bundle the assets in your final build: This currently takes the HTML output
// of every page (stored in memory) and bundles the assets pointed to on those pages.
this.timer.buildStart = performance.now();
info(
this.logging,
this.logger.info(
'build',
colors.dim(`Completed in ${getTimeStat(this.timer.init, performance.now())}.`)
);
@ -171,7 +170,7 @@ class AstroBuilder {
const opts: StaticBuildOptions = {
allPages,
settings: this.settings,
logging: this.logging,
logger: this.logger,
manifest: this.manifest,
mode: this.mode,
origin: this.origin,
@ -193,19 +192,19 @@ class AstroBuilder {
fs.writeFileSync(filePath, assets[k], 'utf8');
delete assets[k]; // free up memory
});
debug('build', timerMessage('Additional assets copied', this.timer.assetsStart));
this.logger.debug('build', timerMessage('Additional assets copied', this.timer.assetsStart));
// You're done! Time to clean up.
await runHookBuildDone({
config: this.settings.config,
pages: pageNames,
routes: Object.values(allPages).map((pd) => pd.route),
logging: this.logging,
logging: this.logger,
});
if (this.logging.level && levels[this.logging.level] <= levels['info']) {
if (this.logger.level && levels[this.logger.level()] <= levels['info']) {
await this.printStats({
logging: this.logging,
logger: this.logger,
timeStart: this.timer.init,
pageCount: pageNames.length,
buildMode: this.settings.config.output,
@ -238,8 +237,7 @@ class AstroBuilder {
if (config.build.split === true) {
if (config.output === 'static') {
warn(
this.logging,
this.logger.warn(
'configuration',
'The option `build.split` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.'
);
@ -247,8 +245,7 @@ class AstroBuilder {
}
if (config.build.excludeMiddleware === true) {
if (config.output === 'static') {
warn(
this.logging,
this.logger.warn(
'configuration',
'The option `build.excludeMiddleware` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.'
);
@ -266,12 +263,12 @@ class AstroBuilder {
/** Stats */
private async printStats({
logging,
logger,
timeStart,
pageCount,
buildMode,
}: {
logging: LogOptions;
logger: Logger;
timeStart: number;
pageCount: number;
buildMode: AstroConfig['output'];
@ -285,7 +282,7 @@ class AstroBuilder {
messages = ['Server built in', colors.bold(total)];
}
info(logging, 'build', messages.join(' '));
info(logging, 'build', `${colors.bold('Complete!')}`);
logger.info('build', messages.join(' '));
logger.info('build', `${colors.bold('Complete!')}`);
}
}

View file

@ -1,6 +1,5 @@
import type { AstroSettings, ManifestData } from '../../@types/astro';
import type { LogOptions } from '../logger/core';
import { info } from '../logger/core.js';
import type { Logger } from '../logger/core';
import type { AllPagesData } from './types';
import * as colors from 'kleur/colors';
@ -8,7 +7,7 @@ import { debug } from '../logger/core.js';
export interface CollectPagesDataOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
manifest: ManifestData;
}
@ -27,7 +26,7 @@ export async function collectPagesData(
const allPages: AllPagesData = {};
const builtPaths = new Set<string>();
const dataCollectionLogTimeout = setInterval(() => {
info(opts.logging, 'build', 'The data collection step may take longer for larger projects...');
opts.logger.info('build', 'The data collection step may take longer for larger projects...');
clearInterval(dataCollectionLogTimeout);
}, 30000);
@ -39,8 +38,7 @@ export async function collectPagesData(
// static route:
if (route.pathname) {
const routeCollectionLogTimeout = setInterval(() => {
info(
opts.logging,
opts.logger.info(
'build',
`${colors.bold(
route.component

View file

@ -100,7 +100,7 @@ export function pluginManifest(
await runHookBuildSsr({
config: options.settings.config,
manifest,
logging: options.logging,
logger: options.logger,
entryPoints: internals.entryPoints,
middlewareEntryPoint: shouldPassMiddlewareEntryPoint
? internals.middlewareEntryPoint

View file

@ -19,7 +19,6 @@ import { runHookBuildSetup } from '../../integrations/index.js';
import { getOutputDirectory, isServerLikeOutput } from '../../prerender/utils.js';
import { PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { info } from '../logger/core.js';
import { routeIsRedirect } from '../redirects/index.js';
import { getOutDirWithinCwd } from './common.js';
import { generatePages } from './generate.js';
@ -80,9 +79,9 @@ export async function viteBuild(opts: StaticBuildOptions) {
// Build your project (SSR application code, assets, client JS, etc.)
const ssrTime = performance.now();
info(opts.logging, 'build', `Building ${settings.config.output} entrypoints...`);
opts.logger.info('build', `Building ${settings.config.output} entrypoints...`);
const ssrOutput = await ssrBuild(opts, internals, pageInput, container);
info(opts.logging, 'build', dim(`Completed in ${getTimeStat(ssrTime, performance.now())}.`));
opts.logger.info('build', dim(`Completed in ${getTimeStat(ssrTime, performance.now())}.`));
settings.timer.end('SSR build');
settings.timer.start('Client build');
@ -132,7 +131,7 @@ export async function staticBuild(opts: StaticBuildOptions, internals: BuildInte
settings.timer.start('Server generate');
await generatePages(opts, internals);
await cleanStaticOutput(opts, internals);
info(opts.logging, null, `\n${bgMagenta(black(' finalizing server assets '))}\n`);
opts.logger.info(null, `\n${bgMagenta(black(' finalizing server assets '))}\n`);
await ssrMoveAssets(opts);
settings.timer.end('Server generate');
return;
@ -214,7 +213,7 @@ async function ssrBuild(
pages: internals.pagesByComponent,
vite: viteBuildConfig,
target: 'server',
logging: opts.logging,
logger: opts.logger,
});
return await vite.build(updatedViteBuildConfig);
@ -242,7 +241,7 @@ async function clientBuild(
}
const { lastVitePlugins, vitePlugins } = container.runBeforeHook('client', input);
info(opts.logging, null, `\n${bgGreen(black(' building client '))}`);
opts.logger.info(null, `\n${bgGreen(black(' building client '))}`);
const viteBuildConfig: vite.InlineConfig = {
...viteConfig,
@ -276,11 +275,11 @@ async function clientBuild(
pages: internals.pagesByComponent,
vite: viteBuildConfig,
target: 'client',
logging: opts.logging,
logger: opts.logger,
});
const buildResult = await vite.build(viteBuildConfig);
info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
opts.logger.info(null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`));
return buildResult;
}
@ -403,7 +402,7 @@ async function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles = false
}
async function ssrMoveAssets(opts: StaticBuildOptions) {
info(opts.logging, 'build', 'Rearranging server assets...');
opts.logger.info('build', 'Rearranging server assets...');
const serverRoot =
opts.settings.config.output === 'static'
? opts.settings.config.build.client

View file

@ -8,7 +8,7 @@ import type {
RuntimeMode,
SSRLoadedRenderer,
} from '../../@types/astro';
import type { LogOptions } from '../logger/core';
import type { Logger } from '../logger/core';
import type { RouteCache } from '../render/route-cache';
export type ComponentPath = string;
@ -34,7 +34,7 @@ export type AllPagesData = Record<ComponentPath, PageBuildData>;
export interface StaticBuildOptions {
allPages: AllPagesData;
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
manifest: ManifestData;
mode: RuntimeMode;
origin: string;

View file

@ -1,5 +1,5 @@
export { resolveConfig, resolveConfigPath, resolveFlags, resolveRoot } from './config.js';
export { createNodeLogging } from './logging.js';
export { createNodeLogger } from './logging.js';
export { mergeConfig } from './merge.js';
export type { AstroConfigType } from './schema';
export { createSettings } from './settings.js';

View file

@ -1,13 +1,12 @@
import type { AstroInlineConfig } from '../../@types/astro.js';
import type { LogOptions } from '../logger/core.js';
import { Logger } from '../logger/core.js';
import { nodeLogDestination } from '../logger/node.js';
export function createNodeLogging(inlineConfig: AstroInlineConfig): LogOptions {
// For internal testing, the inline config can pass the raw `logging` object directly
if (inlineConfig.logging) return inlineConfig.logging;
export function createNodeLogger(inlineConfig: AstroInlineConfig): Logger {
if (inlineConfig.logger) return inlineConfig.logger;
return {
return new Logger({
dest: nodeLogDestination,
level: inlineConfig.logLevel ?? 'info',
};
});
}

View file

@ -1,5 +1,5 @@
import type { AstroSettings } from '../@types/astro';
import type { LogOptions } from './logger/core';
import type { Logger } from './logger/core';
import nodeFs from 'node:fs';
import { fileURLToPath } from 'node:url';
@ -32,7 +32,7 @@ import { joinPaths } from './path.js';
interface CreateViteOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
mode: 'dev' | 'build' | string;
// will be undefined when using `getViteConfig`
command?: 'dev' | 'build';
@ -66,7 +66,7 @@ const ONLY_DEV_EXTERNAL = [
/** Return a common starting point for all Vite actions */
export async function createVite(
commandConfig: vite.InlineConfig,
{ settings, logging, mode, command, fs = nodeFs }: CreateViteOptions
{ settings, logger, mode, command, fs = nodeFs }: CreateViteOptions
): Promise<vite.InlineConfig> {
const astroPkgsConfig = await crawlFrameworkPkgs({
root: fileURLToPath(settings.config.root),
@ -113,26 +113,26 @@ export async function createVite(
plugins: [
configAliasVitePlugin({ settings }),
astroLoadFallbackPlugin({ fs, root: settings.config.root }),
astroVitePlugin({ settings, logging }),
astroVitePlugin({ settings, logger }),
astroScriptsPlugin({ settings }),
// The server plugin is for dev only and having it run during the build causes
// the build to run very slow as the filewatcher is triggered often.
mode !== 'build' && vitePluginAstroServer({ settings, logging, fs }),
mode !== 'build' && vitePluginAstroServer({ settings, logger, fs }),
envVitePlugin({ settings }),
markdownVitePlugin({ settings, logging }),
markdownVitePlugin({ settings, logger }),
htmlVitePlugin(),
mdxVitePlugin({ settings, logging }),
mdxVitePlugin({ settings, logger }),
astroPostprocessVitePlugin(),
astroIntegrationsContainerPlugin({ settings, logging }),
astroIntegrationsContainerPlugin({ settings, logger }),
astroScriptsPageSSRPlugin({ settings }),
astroHeadPlugin(),
astroScannerPlugin({ settings, logging }),
astroInjectEnvTsPlugin({ settings, logging, fs }),
astroScannerPlugin({ settings, logger }),
astroInjectEnvTsPlugin({ settings, logger, fs }),
astroContentVirtualModPlugin({ settings }),
astroContentImportPlugin({ fs, settings }),
astroContentAssetPropagationPlugin({ mode, settings }),
vitePluginSSRManifest(),
astroAssetsPlugin({ settings, logging, mode }),
astroAssetsPlugin({ settings, logger, mode }),
astroTransitions({ config: settings.config }),
],
publicDir: fileURLToPath(settings.config.publicDir),

View file

@ -12,12 +12,12 @@ import {
runHookServerStart,
} from '../../integrations/index.js';
import { createVite } from '../create-vite.js';
import type { LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
import { apply as applyPolyfill } from '../polyfill.js';
export interface Container {
fs: typeof nodeFs;
logging: LogOptions;
logger: Logger;
settings: AstroSettings;
viteServer: vite.ViteDevServer;
inlineConfig: AstroInlineConfig;
@ -27,7 +27,7 @@ export interface Container {
}
export interface CreateContainerParams {
logging: LogOptions;
logger: Logger;
settings: AstroSettings;
inlineConfig?: AstroInlineConfig;
isRestart?: boolean;
@ -36,7 +36,7 @@ export interface CreateContainerParams {
export async function createContainer({
isRestart = false,
logging,
logger,
inlineConfig,
settings,
fs = nodeFs,
@ -46,7 +46,7 @@ export async function createContainer({
settings = await runHookConfigSetup({
settings,
command: 'dev',
logging,
logger: logger,
isRestart,
});
@ -73,15 +73,15 @@ export async function createContainer({
include: rendererClientEntries,
},
},
{ settings, logging, mode: 'dev', command: 'dev', fs }
{ settings, logger, mode: 'dev', command: 'dev', fs }
);
await runHookConfigDone({ settings, logging });
await runHookConfigDone({ settings, logger });
const viteServer = await vite.createServer(viteConfig);
const container: Container = {
inlineConfig: inlineConfig ?? {},
fs,
logging,
logger,
restartInFlight: false,
settings,
viteServer,
@ -97,18 +97,18 @@ export async function createContainer({
return container;
}
async function closeContainer({ viteServer, settings, logging }: Container) {
async function closeContainer({ viteServer, settings, logger }: Container) {
await viteServer.close();
await runHookServerDone({
config: settings.config,
logging,
logger,
});
}
export async function startContainer({
settings,
viteServer,
logging,
logger,
}: Container): Promise<AddressInfo> {
const { port } = settings.config.server;
await viteServer.listen(port);
@ -116,7 +116,7 @@ export async function startContainer({
await runHookServerStart({
config: settings.config,
address: devServerAddressInfo,
logging,
logger,
});
return devServerAddressInfo;

View file

@ -6,7 +6,6 @@ import type * as vite from 'vite';
import type { AstroInlineConfig } from '../../@types/astro';
import { attachContentServerListeners } from '../../content/index.js';
import { telemetry } from '../../events/index.js';
import { info, warn } from '../logger/core.js';
import * as msg from '../messages.js';
import { startContainer } from './container.js';
import { createContainerWithAutomaticRestart } from './restart.js';
@ -30,13 +29,12 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS
// Create a container which sets up the Vite server.
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
const logging = restart.container.logging;
const logger = restart.container.logger;
// Start listening to the port
const devServerAddressInfo = await startContainer(restart.container);
info(
logging,
logger.info(
null,
msg.serverStart({
startupTime: performance.now() - devStart,
@ -48,10 +46,10 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS
const currentVersion = process.env.PACKAGE_VERSION ?? '0.0.0';
if (currentVersion.includes('-')) {
warn(logging, null, msg.prerelease({ currentVersion }));
logger.warn(null, msg.prerelease({ currentVersion }));
}
if (restart.container.viteServer.config.server?.fs?.strict === false) {
warn(logging, null, msg.fsStrictWarning());
logger.warn(null, msg.fsStrictWarning());
}
await attachContentServerListeners(restart.container);

View file

@ -3,11 +3,10 @@ import { fileURLToPath } from 'node:url';
import * as vite from 'vite';
import type { AstroInlineConfig, AstroSettings } from '../../@types/astro';
import { eventCliSession, telemetry } from '../../events/index.js';
import { createNodeLogging, createSettings, resolveConfig } from '../config/index.js';
import { createNodeLogger, createSettings, resolveConfig } from '../config/index.js';
import { collectErrorMetadata } from '../errors/dev/utils.js';
import { isAstroConfigZodError } from '../errors/errors.js';
import { createSafeError } from '../errors/index.js';
import { info, error as logError } from '../logger/core.js';
import { formatErrorMessage } from '../messages.js';
import type { Container } from './container';
import { createContainer, startContainer } from './container.js';
@ -16,10 +15,10 @@ async function createRestartedContainer(
container: Container,
settings: AstroSettings
): Promise<Container> {
const { logging, fs, inlineConfig } = container;
const { logger, fs, inlineConfig } = container;
const newContainer = await createContainer({
isRestart: true,
logging,
logger: logger,
settings,
inlineConfig,
fs,
@ -60,7 +59,7 @@ export function shouldRestartContainer(
}
export async function restartContainer(container: Container): Promise<Container | Error> {
const { logging, close, settings: existingSettings } = container;
const { logger, close, settings: existingSettings } = container;
container.restartInFlight = true;
try {
@ -72,7 +71,7 @@ export async function restartContainer(container: Container): Promise<Container
const error = createSafeError(_err);
// Print all error messages except ZodErrors from AstroConfig as the pre-logged error is sufficient
if (!isAstroConfigZodError(_err)) {
logError(logging, 'config', formatErrorMessage(collectErrorMetadata(error)) + '\n');
logger.error('config', formatErrorMessage(collectErrorMetadata(error)) + '\n');
}
// Inform connected clients of the config error
container.viteServer.ws.send({
@ -83,7 +82,7 @@ export async function restartContainer(container: Container): Promise<Container
},
});
container.restartInFlight = false;
info(logging, 'astro', 'Continuing with previous valid configuration\n');
logger.error('astro', 'Continuing with previous valid configuration\n');
return error;
}
}
@ -102,13 +101,13 @@ export async function createContainerWithAutomaticRestart({
inlineConfig,
fs,
}: CreateContainerWithAutomaticRestart): Promise<Restart> {
const logging = createNodeLogging(inlineConfig ?? {});
const logger = createNodeLogger(inlineConfig ?? {});
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, 'dev', fs);
telemetry.record(eventCliSession('dev', userConfig));
const settings = createSettings(astroConfig, fileURLToPath(astroConfig.root));
const initialContainer = await createContainer({ settings, logging, inlineConfig, fs });
const initialContainer = await createContainer({ settings, logger: logger, inlineConfig, fs });
let resolveRestart: (value: Error | null) => void;
let restartComplete = new Promise<Error | null>((resolve) => {
@ -123,7 +122,7 @@ export async function createContainerWithAutomaticRestart({
};
async function handleServerRestart(logMsg: string) {
info(logging, 'astro', logMsg + '\n');
logger.info('astro', logMsg + '\n');
const container = restart.container;
const result = await restartContainer(container);
if (result instanceof Error) {

View file

@ -11,7 +11,6 @@ import { renderEndpoint } from '../../runtime/server/index.js';
import { ASTRO_VERSION } from '../constants.js';
import { AstroCookies, attachCookiesToResponse } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js';
import type { Environment, RenderContext } from '../render/index';
@ -132,23 +131,22 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>
let response;
if (onRequest) {
response = await callMiddleware<Response | EndpointOutput>(
env.logging,
env.logger,
onRequest as MiddlewareEndpointHandler,
context,
async () => {
return await renderEndpoint(mod, context, env.ssr, env.logging);
return await renderEndpoint(mod, context, env.ssr, env.logger);
}
);
} else {
response = await renderEndpoint(mod, context, env.ssr, env.logging);
response = await renderEndpoint(mod, context, env.ssr, env.logger);
}
const isEndpointSSR = env.ssr && !ctx.route?.prerender;
if (response instanceof Response) {
if (isEndpointSSR && response.headers.get('X-Astro-Encoding')) {
warn(
env.logging,
env.logger.warn(
'ssr',
'`ResponseWithEncoding` is ignored in SSR. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.'
);
@ -160,24 +158,21 @@ export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>
// The endpoint returned a simple object, convert it to a Response
// TODO: Remove in Astro 4.0
warn(
env.logging,
env.logger.warn(
'astro',
`${ctx.route.component} returns a simple object which is deprecated. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.`
);
if (isEndpointSSR) {
if (response.hasOwnProperty('headers')) {
warn(
env.logging,
env.logger.warn(
'ssr',
'Setting headers is not supported when returning an object. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.'
);
}
if (response.encoding) {
warn(
env.logging,
env.logger.warn(
'ssr',
'`encoding` is ignored in SSR. To return a charset other than UTF-8, please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.'
);

View file

@ -142,8 +142,16 @@ export class Logger {
error(label: string | null, message: string) {
error(this.options, label, message);
}
debug(label: string | null, message: string) {
debug(this.options, label, message);
debug(label: string | null, message: string, ...args: any[]) {
debug(this.options, label, message, args);
}
level() {
return this.options.level;
}
forkIntegrationLogger(label: string) {
return new AstroIntegrationLogger(this.options, label);
}
}

View file

@ -6,7 +6,6 @@ import type {
MiddlewareNext,
} from '../../@types/astro';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn } from '../logger/core.js';
import type { Environment } from '../render';
/**
@ -44,7 +43,7 @@ import type { Environment } from '../render';
* @param responseFunction A callback function that should return a promise with the response
*/
export async function callMiddleware<R>(
logging: Environment['logging'],
logger: Environment['logger'],
onRequest: MiddlewareHandler<R>,
apiContext: APIContext,
responseFunction: () => Promise<R>
@ -61,8 +60,7 @@ export async function callMiddleware<R>(
return await Promise.resolve(middlewarePromise).then(async (value) => {
if (isEndpointOutput(value)) {
warn(
logging,
logger.warn(
'middleware',
'Using simple endpoints can cause unexpected issues in the chain of middleware functions.' +
`\nIt's strongly suggested to use full ${bold('Response')} objects.`

View file

@ -116,7 +116,7 @@ export class Pipeline {
case 'redirect': {
if (onRequest) {
return await callMiddleware<Response>(
env.logging,
env.logger,
onRequest as MiddlewareResponseHandler,
apiContext,
() => {

View file

@ -5,7 +5,7 @@ import { telemetry } from '../../events/index.js';
import { eventCliSession } from '../../events/session.js';
import { runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js';
import { resolveConfig } from '../config/config.js';
import { createNodeLogging } from '../config/logging.js';
import { createNodeLogger } from '../config/logging.js';
import { createSettings } from '../config/settings.js';
import createStaticPreviewServer from './static-preview-server.js';
import { getResolvedHostForHttpServer } from './util.js';
@ -17,7 +17,7 @@ import { getResolvedHostForHttpServer } from './util.js';
* @experimental The JavaScript API is experimental
*/
export default async function preview(inlineConfig: AstroInlineConfig): Promise<PreviewServer> {
const logging = createNodeLogging(inlineConfig);
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, 'preview');
telemetry.record(eventCliSession('preview', userConfig));
@ -26,12 +26,12 @@ export default async function preview(inlineConfig: AstroInlineConfig): Promise<
const settings = await runHookConfigSetup({
settings: _settings,
command: 'preview',
logging: logging,
logger: logger,
});
await runHookConfigDone({ settings: settings, logging: logging });
await runHookConfigDone({ settings: settings, logger: logger });
if (settings.config.output === 'static') {
const server = await createStaticPreviewServer(settings, logging);
const server = await createStaticPreviewServer(settings, logger);
return server;
}
if (!settings.adapter) {

View file

@ -4,8 +4,7 @@ import { performance } from 'perf_hooks';
import enableDestroy from 'server-destroy';
import { preview, type PreviewServer as VitePreviewServer } from 'vite';
import type { AstroSettings } from '../../@types/astro';
import type { LogOptions } from '../logger/core';
import { error, info } from '../logger/core.js';
import type { Logger } from '../logger/core';
import * as msg from '../messages.js';
import { getResolvedHostForHttpServer } from './util.js';
import { vitePluginAstroPreview } from './vite-plugin-astro-preview.js';
@ -20,7 +19,7 @@ export interface PreviewServer {
export default async function createStaticPreviewServer(
settings: AstroSettings,
logging: LogOptions
logger: Logger
): Promise<PreviewServer> {
const startServerTime = performance.now();
@ -43,7 +42,7 @@ export default async function createStaticPreviewServer(
});
} catch (err) {
if (err instanceof Error) {
error(logging, 'astro', err.stack || err.message);
logger.error('astro', err.stack || err.message);
}
throw err;
}
@ -51,8 +50,7 @@ export default async function createStaticPreviewServer(
enableDestroy(previewServer.httpServer);
// Log server start URLs
info(
logging,
logger.info(
null,
msg.serverStart({
startupTime: performance.now() - startServerTime,

View file

@ -48,7 +48,7 @@ export async function createRenderContext(
route: options.route,
routeCache: options.env.routeCache,
pathname: pathname,
logging: options.env.logging,
logger: options.env.logger,
ssr: options.env.ssr,
});

View file

@ -8,7 +8,6 @@ import type {
import { renderPage as runtimeRenderPage } from '../../runtime/server/index.js';
import { attachCookiesToResponse } from '../cookies/index.js';
import { callEndpoint, createAPIContext } from '../endpoint/index.js';
import { warn } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js';
import { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from '../redirects/index.js';
import type { RenderContext } from './context.js';
@ -41,7 +40,7 @@ export async function renderPage({ mod, renderContext, env, cookies }: RenderPag
adapterName: env.adapterName,
links: renderContext.links,
styles: renderContext.styles,
logging: env.logging,
logger: env.logger,
params: renderContext.params,
pathname: renderContext.pathname,
componentMetadata: renderContext.componentMetadata,
@ -60,8 +59,7 @@ export async function renderPage({ mod, renderContext, env, cookies }: RenderPag
// TODO: Remove in Astro 4.0
if (mod.frontmatter && typeof mod.frontmatter === 'object' && 'draft' in mod.frontmatter) {
warn(
env.logging,
env.logger.warn(
'astro',
`The drafts feature is deprecated and used in ${renderContext.route.component}. You should migrate to content collections instead. See https://docs.astro.build/en/guides/content-collections/#filtering-collection-queries for more information.`
);
@ -115,7 +113,7 @@ export async function tryRenderRoute<MiddlewareReturnType = Response>(
case 'redirect': {
if (onRequest) {
return await callMiddleware<Response>(
env.logging,
env.logger,
onRequest as MiddlewareResponseHandler,
apiContext,
() => {

View file

@ -1,5 +1,5 @@
import type { RuntimeMode, SSRLoadedRenderer } from '../../@types/astro';
import type { LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
import type { RouteCache } from './route-cache.js';
/**
@ -13,7 +13,7 @@ export interface Environment {
*/
adapterName?: string;
/** logging options */
logging: LogOptions;
logger: Logger;
/** "development" or "production" */
mode: RuntimeMode;
compressHTML: boolean;

View file

@ -1,6 +1,6 @@
import type { ComponentInstance, Params, Props, RouteData } from '../../@types/astro';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
import { getParams } from '../routing/params.js';
import { RouteCache, callGetStaticPaths, findPathItemByKey } from './route-cache.js';
@ -9,12 +9,12 @@ interface GetParamsAndPropsOptions {
route?: RouteData | undefined;
routeCache: RouteCache;
pathname: string;
logging: LogOptions;
logger: Logger;
ssr: boolean;
}
export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Params, Props]> {
const { logging, mod, route, routeCache, pathname, ssr } = opts;
const { logger, mod, route, routeCache, pathname, ssr } = opts;
// If there's no route, or if there's a pathname (e.g. a static `src/pages/normal.astro` file),
// then we know for sure they don't have params and props, return a fallback value.
@ -33,11 +33,11 @@ export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise
mod,
route,
routeCache,
logging,
logger,
ssr,
});
const matchedStaticPath = findPathItemByKey(staticPaths, params, route);
const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger);
if (!matchedStaticPath && (ssr ? route.prerender : true)) {
throw new AstroError({
...AstroErrorData.NoMatchingStaticPathFound,

View file

@ -11,7 +11,7 @@ import { renderJSX } from '../../runtime/server/jsx.js';
import { chunkToString } from '../../runtime/server/render/index.js';
import { AstroCookies } from '../cookies/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { warn, type LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
const clientAddressSymbol = Symbol.for('astro.clientAddress');
const responseSentSymbol = Symbol.for('astro.responseSent');
@ -25,7 +25,7 @@ export interface CreateResultArgs {
* Value of Astro config's `output` option, true if "server" or "hybrid"
*/
ssr: boolean;
logging: LogOptions;
logger: Logger;
params: Params;
pathname: string;
renderers: SSRLoadedRenderer[];
@ -55,12 +55,12 @@ function getFunctionExpression(slot: any) {
class Slots {
#result: SSRResult;
#slots: ComponentSlots | null;
#loggingOpts: LogOptions;
#logger: Logger;
constructor(result: SSRResult, slots: ComponentSlots | null, logging: LogOptions) {
constructor(result: SSRResult, slots: ComponentSlots | null, logger: Logger) {
this.#result = result;
this.#slots = slots;
this.#loggingOpts = logging;
this.#logger = logger;
if (slots) {
for (const key of Object.keys(slots)) {
@ -90,8 +90,7 @@ class Slots {
const result = this.#result;
if (!Array.isArray(args)) {
warn(
this.#loggingOpts,
this.#logger.warn(
'Astro.slots.render',
`Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as a item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])`
);
@ -164,7 +163,7 @@ export function createResult(args: CreateResultArgs): SSRResult {
props: Record<string, any>,
slots: Record<string, any> | null
) {
const astroSlots = new Slots(result, slots, args.logging);
const astroSlots = new Slots(result, slots, args.logger);
const Astro: AstroGlobal = {
// @ts-expect-error

View file

@ -8,7 +8,7 @@ import type {
RuntimeMode,
} from '../../@types/astro';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { debug, warn, type LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
import { stringifyParams } from '../routing/params.js';
import { validateDynamicRouteModule, validateGetStaticPathsResult } from '../routing/validation.js';
@ -18,7 +18,7 @@ interface CallGetStaticPathsOptions {
mod: ComponentInstance;
route: RouteData;
routeCache: RouteCache;
logging: LogOptions;
logger: Logger;
ssr: boolean;
}
@ -26,7 +26,7 @@ export async function callGetStaticPaths({
mod,
route,
routeCache,
logging,
logger,
ssr,
}: CallGetStaticPathsOptions): Promise<GetStaticPathsResultKeyed> {
const cached = routeCache.get(route);
@ -56,7 +56,7 @@ export async function callGetStaticPaths({
},
});
validateGetStaticPathsResult(staticPaths, logging, route);
validateGetStaticPathsResult(staticPaths, logger, route);
const keyedStaticPaths = staticPaths as GetStaticPathsResultKeyed;
keyedStaticPaths.keyed = new Map<string, GetStaticPathsItem>();
@ -80,12 +80,12 @@ interface RouteCacheEntry {
* responses during dev and only ever called once during build.
*/
export class RouteCache {
private logging: LogOptions;
private logger: Logger;
private cache: Record<string, RouteCacheEntry> = {};
private mode: RuntimeMode;
constructor(logging: LogOptions, mode: RuntimeMode = 'production') {
this.logging = logging;
constructor(logger: Logger, mode: RuntimeMode = 'production') {
this.logger = logger;
this.mode = mode;
}
@ -99,8 +99,7 @@ export class RouteCache {
// Warn here so that an unexpected double-call of getStaticPaths()
// isn't invisible and developer can track down the issue.
if (this.mode === 'production' && this.cache[route.component]?.staticPaths) {
warn(
this.logging,
this.logger.warn(
'routeCache',
`Internal Warning: route cache overwritten. (${route.component})`
);
@ -116,12 +115,13 @@ export class RouteCache {
export function findPathItemByKey(
staticPaths: GetStaticPathsResultKeyed,
params: Params,
route: RouteData
route: RouteData,
logger: Logger
) {
const paramsKey = stringifyParams(params, route);
const matchedStaticPath = staticPaths.keyed.get(paramsKey);
if (matchedStaticPath) {
return matchedStaticPath;
}
debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`);
logger.debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`);
}

View file

@ -1,6 +1,5 @@
import type { IncomingHttpHeaders } from 'node:http';
import type { LogOptions } from './logger/core';
import { warn } from './logger/core.js';
import type { Logger } from './logger/core';
type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders;
type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData;
@ -11,7 +10,7 @@ export interface CreateRequestOptions {
headers: HeaderType;
method?: string;
body?: RequestBody | undefined;
logging: LogOptions;
logger: Logger;
ssr: boolean;
locals?: object | undefined;
}
@ -25,7 +24,7 @@ export function createRequest({
clientAddress,
method = 'GET',
body = undefined,
logging,
logger,
ssr,
locals,
}: CreateRequestOptions): Request {
@ -43,7 +42,7 @@ export function createRequest({
Object.defineProperties(request, {
params: {
get() {
warn(logging, 'deprecation', `Astro.request.params has been moved to Astro.params`);
logger.warn('deprecation', `Astro.request.params has been moved to Astro.params`);
return undefined;
},
},
@ -56,8 +55,7 @@ export function createRequest({
Object.defineProperty(request, 'headers', {
...headersDesc,
get() {
warn(
logging,
logger.warn(
'ssg',
`Headers are not exposed in static (SSG) output mode. To enable headers: set \`output: "server"\` in your config file.`
);

View file

@ -6,7 +6,7 @@ import type {
RouteData,
RoutePart,
} from '../../../@types/astro';
import type { LogOptions } from '../../logger/core';
import type { Logger } from '../../logger/core';
import { createRequire } from 'module';
import nodeFs from 'node:fs';
@ -14,7 +14,6 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { getPrerenderDefault } from '../../../prerender/utils.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../../constants.js';
import { warn } from '../../logger/core.js';
import { removeLeadingForwardSlash, slash } from '../../path.js';
import { resolvePages } from '../../util.js';
import { getRouteGenerator } from './generator.js';
@ -221,7 +220,7 @@ export interface CreateRouteManifestParams {
/** Create manifest of all static routes */
export function createRouteManifest(
{ settings, cwd, fsMod }: CreateRouteManifestParams,
logging: LogOptions
logger: Logger
): ManifestData {
const components: string[] = [];
const routes: RouteData[] = [];
@ -261,7 +260,7 @@ export function createRouteManifest(
if (!isDir && !validPageExtensions.has(ext) && !validEndpointExtensions.has(ext)) {
if (!foundInvalidFileExtensions.has(ext)) {
foundInvalidFileExtensions.add(ext);
warn(logging, 'astro', `Invalid file extension for Pages: ${ext}`);
logger.warn('astro', `Invalid file extension for Pages: ${ext}`);
}
return;
@ -359,7 +358,7 @@ export function createRouteManifest(
} else if (settings.injectedRoutes.length === 0) {
const pagesDirRootRelative = pages.href.slice(settings.config.root.href.length);
warn(logging, 'astro', `Missing pages directory: ${pagesDirRootRelative}`);
logger.warn('astro', `Missing pages directory: ${pagesDirRootRelative}`);
}
settings.injectedRoutes

View file

@ -1,7 +1,6 @@
import type { ComponentInstance, GetStaticPathsResult, RouteData } from '../../@types/astro';
import { AstroError, AstroErrorData } from '../errors/index.js';
import type { LogOptions } from '../logger/core';
import { warn } from '../logger/core.js';
import type { Logger } from '../logger/core';
const VALID_PARAM_TYPES = ['string', 'number', 'undefined'];
@ -40,7 +39,7 @@ export function validateDynamicRouteModule(
/** Throw error and log warnings for malformed getStaticPaths() response */
export function validateGetStaticPathsResult(
result: GetStaticPathsResult,
logging: LogOptions,
logger: Logger,
route: RouteData
) {
if (!Array.isArray(result)) {
@ -79,8 +78,7 @@ export function validateGetStaticPathsResult(
// TODO: Replace those with errors? They technically don't crash the build, but users might miss the warning. - erika, 2022-11-07
for (const [key, val] of Object.entries(pathObject.params)) {
if (!(typeof val === 'undefined' || typeof val === 'string' || typeof val === 'number')) {
warn(
logging,
logger.warn(
'getStaticPaths',
`invalid path param: ${key}. A string, number or undefined value was expected, but got \`${JSON.stringify(
val
@ -88,8 +86,7 @@ export function validateGetStaticPathsResult(
);
}
if (typeof val === 'string' && val === '') {
warn(
logging,
logger.warn(
'getStaticPaths',
`invalid path param: ${key}. \`undefined\` expected for an optional param, but got empty string.`
);

View file

@ -12,11 +12,11 @@ import { runHookConfigSetup } from '../../integrations/index.js';
import { setUpEnvTs } from '../../vite-plugin-inject-env-ts/index.js';
import { getTimeStat } from '../build/util.js';
import { resolveConfig } from '../config/config.js';
import { createNodeLogging } from '../config/logging.js';
import { createNodeLogger } from '../config/logging.js';
import { createSettings } from '../config/settings.js';
import { createVite } from '../create-vite.js';
import { AstroError, AstroErrorData, createSafeError, isAstroError } from '../errors/index.js';
import { info, type LogOptions } from '../logger/core.js';
import type { Logger } from '../logger/core.js';
export type ProcessExit = 0 | 1;
@ -28,7 +28,7 @@ export type SyncOptions = {
};
export type SyncInternalOptions = SyncOptions & {
logging: LogOptions;
logger: Logger;
};
/**
@ -41,7 +41,7 @@ export default async function sync(
inlineConfig: AstroInlineConfig,
options?: SyncOptions
): Promise<ProcessExit> {
const logging = createNodeLogging(inlineConfig);
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, 'sync');
telemetry.record(eventCliSession('sync', userConfig));
@ -49,11 +49,11 @@ export default async function sync(
const settings = await runHookConfigSetup({
settings: _settings,
logging: logging,
logger: logger,
command: 'build',
});
return await syncInternal(settings, { ...options, logging });
return await syncInternal(settings, { ...options, logger });
}
/**
@ -72,7 +72,7 @@ export default async function sync(
*/
export async function syncInternal(
settings: AstroSettings,
{ logging, fs }: SyncInternalOptions
{ logger, fs }: SyncInternalOptions
): Promise<ProcessExit> {
const timerStart = performance.now();
// Needed to load content config
@ -84,7 +84,7 @@ export async function syncInternal(
ssr: { external: [] },
logLevel: 'silent',
},
{ settings, logging, mode: 'build', command: 'build', fs }
{ settings, logger, mode: 'build', command: 'build', fs }
)
);
@ -101,7 +101,7 @@ export async function syncInternal(
try {
const contentTypesGenerator = await createContentTypesGenerator({
contentConfigObserver: globalContentConfigObserver,
logging,
logger: logger,
fs: fs ?? fsMod,
settings,
viteServer: tempViteServer,
@ -117,7 +117,7 @@ export async function syncInternal(
switch (typesResult.reason) {
case 'no-content-dir':
default:
info(logging, 'content', 'No content directory found. Skipping type generation.');
logger.info('content', 'No content directory found. Skipping type generation.');
return 0;
}
}
@ -137,8 +137,8 @@ export async function syncInternal(
await tempViteServer.close();
}
info(logging, 'content', `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`);
await setUpEnvTs({ settings, logging, fs: fs ?? fsMod });
logger.info('content', `Types generated ${dim(getTimeStat(timerStart, performance.now()))}`);
await setUpEnvTs({ settings, logger, fs: fs ?? fsMod });
return 0;
}

View file

@ -4,7 +4,7 @@ import type {
AstroFeatureMap,
SupportsKind,
} from '../@types/astro';
import { error, warn, type LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
const STABLE = 'stable';
const DEPRECATED = 'deprecated';
@ -40,7 +40,7 @@ export function validateSupportedFeatures(
adapterName: string,
featureMap: AstroFeatureMap = ALL_UNSUPPORTED,
config: AstroConfig,
logging: LogOptions
logger: Logger
): ValidationResult {
const {
assets = UNSUPPORTED_ASSETS_FEATURE,
@ -53,7 +53,7 @@ export function validateSupportedFeatures(
validationResult.staticOutput = validateSupportKind(
staticOutput,
adapterName,
logging,
logger,
'staticOutput',
() => config?.output === 'static'
);
@ -61,7 +61,7 @@ export function validateSupportedFeatures(
validationResult.hybridOutput = validateSupportKind(
hybridOutput,
adapterName,
logging,
logger,
'hybridOutput',
() => config?.output === 'hybrid'
);
@ -69,11 +69,11 @@ export function validateSupportedFeatures(
validationResult.serverOutput = validateSupportKind(
serverOutput,
adapterName,
logging,
logger,
'serverOutput',
() => config?.output === 'server'
);
validationResult.assets = validateAssetsFeature(assets, adapterName, config, logging);
validationResult.assets = validateAssetsFeature(assets, adapterName, config, logger);
return validationResult;
}
@ -81,44 +81,39 @@ export function validateSupportedFeatures(
function validateSupportKind(
supportKind: SupportsKind,
adapterName: string,
logging: LogOptions,
logger: Logger,
featureName: string,
hasCorrectConfig: () => boolean
): boolean {
if (supportKind === STABLE) {
return true;
} else if (supportKind === DEPRECATED) {
featureIsDeprecated(adapterName, logging);
featureIsDeprecated(adapterName, logger);
} else if (supportKind === EXPERIMENTAL) {
featureIsExperimental(adapterName, logging);
featureIsExperimental(adapterName, logger);
}
if (hasCorrectConfig() && supportKind === UNSUPPORTED) {
featureIsUnsupported(adapterName, logging, featureName);
featureIsUnsupported(adapterName, logger, featureName);
return false;
} else {
return true;
}
}
function featureIsUnsupported(adapterName: string, logging: LogOptions, featureName: string) {
error(
logging,
function featureIsUnsupported(adapterName: string, logger: Logger, featureName: string) {
logger.error(
`${adapterName}`,
`The feature ${featureName} is not supported by the adapter ${adapterName}.`
);
}
function featureIsExperimental(adapterName: string, logging: LogOptions) {
warn(logging, `${adapterName}`, 'The feature is experimental and subject to issues or changes.');
function featureIsExperimental(adapterName: string, logger: Logger) {
logger.warn(`${adapterName}`, 'The feature is experimental and subject to issues or changes.');
}
function featureIsDeprecated(adapterName: string, logging: LogOptions) {
warn(
logging,
`${adapterName}`,
'The feature is deprecated and will be moved in the next release.'
);
function featureIsDeprecated(adapterName: string, logger: Logger) {
logger.warn(`${adapterName}`, 'The feature is deprecated and will be moved in the next release.');
}
const SHARP_SERVICE = 'astro/assets/services/sharp';
@ -128,7 +123,7 @@ function validateAssetsFeature(
assets: AstroAssetsFeature,
adapterName: string,
config: AstroConfig,
logging: LogOptions
logger: Logger
): boolean {
const {
supportKind = UNSUPPORTED,
@ -136,8 +131,7 @@ function validateAssetsFeature(
isSquooshCompatible = false,
} = assets;
if (config?.image?.service?.entrypoint === SHARP_SERVICE && !isSharpCompatible) {
error(
logging,
logger.error(
'astro',
`The currently selected adapter \`${adapterName}\` is not compatible with the image service "Sharp".`
);
@ -145,13 +139,12 @@ function validateAssetsFeature(
}
if (config?.image?.service?.entrypoint === SQUOOSH_SERVICE && !isSquooshCompatible) {
error(
logging,
logger.error(
'astro',
`The currently selected adapter \`${adapterName}\` is not compatible with the image service "Squoosh".`
);
return false;
}
return validateSupportKind(supportKind, adapterName, logging, 'assets', () => true);
return validateSupportKind(supportKind, adapterName, logger, 'assets', () => true);
}

View file

@ -18,7 +18,7 @@ import type { SerializedSSRManifest } from '../core/app/types';
import type { PageBuildData } from '../core/build/types';
import { buildClientDirectiveEntrypoint } from '../core/client-directive/index.js';
import { mergeConfig } from '../core/config/index.js';
import { AstroIntegrationLogger, error, info, warn, type LogOptions } from '../core/logger/core.js';
import { AstroIntegrationLogger, type Logger } from '../core/logger/core.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { validateSupportedFeatures } from './astroFeaturesValidation.js';
@ -26,15 +26,15 @@ async function withTakingALongTimeMsg<T>({
name,
hookResult,
timeoutMs = 3000,
logging,
logger,
}: {
name: string;
hookResult: T | Promise<T>;
timeoutMs?: number;
logging: LogOptions;
logger: Logger;
}): Promise<T> {
const timeout = setTimeout(() => {
info(logging, 'build', `Waiting for the ${bold(name)} integration...`);
logger.info('build', `Waiting for the ${bold(name)} integration...`);
}, timeoutMs);
const result = await hookResult;
clearTimeout(timeout);
@ -44,25 +44,25 @@ async function withTakingALongTimeMsg<T>({
// Used internally to store instances of loggers.
const Loggers = new WeakMap<AstroIntegration, AstroIntegrationLogger>();
function getLogger(integration: AstroIntegration, logging: LogOptions) {
function getLogger(integration: AstroIntegration, logger: Logger) {
if (Loggers.has(integration)) {
// SAFETY: we check the existence in the if block
return Loggers.get(integration)!;
}
const logger = new AstroIntegrationLogger(logging, integration.name);
Loggers.set(integration, logger);
return logger;
const integrationLogger = logger.forkIntegrationLogger(integration.name);
Loggers.set(integration, integrationLogger);
return integrationLogger;
}
export async function runHookConfigSetup({
settings,
command,
logging,
logger,
isRestart = false,
}: {
settings: AstroSettings;
command: 'dev' | 'build' | 'preview';
logging: LogOptions;
logger: Logger;
isRestart?: boolean;
}): Promise<AstroSettings> {
// An adapter is an integration, so if one is provided push it.
@ -88,7 +88,7 @@ export async function runHookConfigSetup({
* ```
*/
if (integration.hooks?.['astro:config:setup']) {
const logger = getLogger(integration, logging);
const integrationLogger = getLogger(integration, logger);
const hooks: HookParameters<'astro:config:setup'> = {
config: updatedConfig,
@ -125,7 +125,7 @@ export async function runHookConfigSetup({
}
addedClientDirectives.set(name, buildClientDirectiveEntrypoint(name, entrypoint));
},
logger,
logger: integrationLogger,
};
// ---
@ -164,7 +164,7 @@ export async function runHookConfigSetup({
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:config:setup'](hooks),
logging,
logger,
});
// Add custom client directives to settings, waiting for compiled code by esbuild
@ -180,13 +180,12 @@ export async function runHookConfigSetup({
export async function runHookConfigDone({
settings,
logging,
logger,
}: {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}) {
for (const integration of settings.config.integrations) {
const logger = getLogger(integration, logging);
if (integration?.hooks?.['astro:config:done']) {
await withTakingALongTimeMsg({
name: integration.name,
@ -200,8 +199,7 @@ export async function runHookConfigDone({
}
if (!adapter.supportedAstroFeatures) {
// NOTE: throw an error in Astro 4.0
warn(
logging,
logger.warn(
'astro',
`The adapter ${adapter.name} doesn't provide a feature map. From Astro 3.0, an adapter can provide a feature map. Not providing a feature map will cause an error in Astro 4.0.`
);
@ -210,20 +208,18 @@ export async function runHookConfigDone({
adapter.name,
adapter.supportedAstroFeatures,
settings.config,
logging
logger
);
for (const [featureName, supported] of Object.entries(validationResult)) {
if (!supported) {
error(
logging,
logger.error(
'astro',
`The adapter ${adapter.name} doesn't support the feature ${featureName}. Your project won't be built. You should not use it.`
);
}
}
if (!validationResult.assets) {
info(
logging,
logger.info(
'astro',
`The selected adapter ${adapter.name} does not support Sharp or Squoosh for image processing. To ensure your project is still able to build, image processing has been disabled.`
);
@ -235,9 +231,9 @@ export async function runHookConfigDone({
}
settings.adapter = adapter;
},
logger,
logger: getLogger(integration, logger),
}),
logging,
logger,
});
}
}
@ -246,19 +242,21 @@ export async function runHookConfigDone({
export async function runHookServerSetup({
config,
server,
logging,
logger,
}: {
config: AstroConfig;
server: ViteDevServer;
logging: LogOptions;
logger: Logger;
}) {
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:server:setup']) {
const logger = getLogger(integration, logging);
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:setup']({ server, logger }),
logging,
hookResult: integration.hooks['astro:server:setup']({
server,
logger: getLogger(integration, logger),
}),
logger,
});
}
}
@ -267,20 +265,21 @@ export async function runHookServerSetup({
export async function runHookServerStart({
config,
address,
logging,
logger,
}: {
config: AstroConfig;
address: AddressInfo;
logging: LogOptions;
logger: Logger;
}) {
for (const integration of config.integrations) {
const logger = getLogger(integration, logging);
if (integration?.hooks?.['astro:server:start']) {
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:start']({ address, logger }),
logging,
hookResult: integration.hooks['astro:server:start']({
address,
logger: getLogger(integration, logger),
}),
logger,
});
}
}
@ -288,19 +287,19 @@ export async function runHookServerStart({
export async function runHookServerDone({
config,
logging,
logger,
}: {
config: AstroConfig;
logging: LogOptions;
logger: Logger;
}) {
for (const integration of config.integrations) {
const logger = getLogger(integration, logging);
if (integration?.hooks?.['astro:server:done']) {
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:server:done']({ logger }),
logging,
hookResult: integration.hooks['astro:server:done']({
logger: getLogger(integration, logger),
}),
logger,
});
}
}
@ -311,7 +310,7 @@ export async function runHookBuildStart({
logging,
}: {
config: AstroConfig;
logging: LogOptions;
logging: Logger;
}) {
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:start']) {
@ -320,7 +319,7 @@ export async function runHookBuildStart({
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:start']({ logger }),
logging,
logger: logging,
});
}
}
@ -331,20 +330,18 @@ export async function runHookBuildSetup({
vite,
pages,
target,
logging,
logger,
}: {
config: AstroConfig;
vite: InlineConfig;
pages: Map<string, PageBuildData>;
target: 'server' | 'client';
logging: LogOptions;
logger: Logger;
}): Promise<InlineConfig> {
let updatedConfig = vite;
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:setup']) {
const logger = getLogger(integration, logging);
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:setup']({
@ -354,9 +351,9 @@ export async function runHookBuildSetup({
updateConfig: (newConfig) => {
updatedConfig = mergeConfig(updatedConfig, newConfig);
},
logger,
logger: getLogger(integration, logger),
}),
logging,
logger,
});
}
}
@ -367,7 +364,7 @@ export async function runHookBuildSetup({
type RunHookBuildSsr = {
config: AstroConfig;
manifest: SerializedSSRManifest;
logging: LogOptions;
logger: Logger;
entryPoints: Map<RouteData, URL>;
middlewareEntryPoint: URL | undefined;
};
@ -375,23 +372,21 @@ type RunHookBuildSsr = {
export async function runHookBuildSsr({
config,
manifest,
logging,
logger,
entryPoints,
middlewareEntryPoint,
}: RunHookBuildSsr) {
for (const integration of config.integrations) {
if (integration?.hooks?.['astro:build:ssr']) {
const logger = getLogger(integration, logging);
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:ssr']({
manifest,
entryPoints,
middlewareEntryPoint,
logger,
logger: getLogger(integration, logger),
}),
logging,
logger,
});
}
}
@ -399,21 +394,22 @@ export async function runHookBuildSsr({
export async function runHookBuildGenerated({
config,
logging,
logger,
}: {
config: AstroConfig;
logging: LogOptions;
logger: Logger;
}) {
const dir = isServerLikeOutput(config) ? config.build.client : config.outDir;
for (const integration of config.integrations) {
const logger = getLogger(integration, logging);
if (integration?.hooks?.['astro:build:generated']) {
await withTakingALongTimeMsg({
name: integration.name,
hookResult: integration.hooks['astro:build:generated']({ dir, logger }),
logging,
hookResult: integration.hooks['astro:build:generated']({
dir,
logger: getLogger(integration, logger),
}),
logger,
});
}
}
@ -423,7 +419,7 @@ type RunHookBuildDone = {
config: AstroConfig;
pages: string[];
routes: RouteData[];
logging: LogOptions;
logging: Logger;
};
export async function runHookBuildDone({ config, pages, routes, logging }: RunHookBuildDone) {
@ -442,7 +438,7 @@ export async function runHookBuildDone({ config, pages, routes, logging }: RunHo
routes,
logger,
}),
logging,
logger: logging,
});
}
}

View file

@ -1,13 +1,12 @@
import type { APIContext, EndpointHandler, Params } from '../../@types/astro';
import { warn, type LogOptions } from '../../core/logger/core.js';
import type { Logger } from '../../core/logger/core.js';
function getHandlerFromModule(mod: EndpointHandler, method: string, logging: LogOptions) {
function getHandlerFromModule(mod: EndpointHandler, method: string, logger: Logger) {
const lowerCaseMethod = method.toLowerCase();
// TODO: remove in Astro 4.0
if (mod[lowerCaseMethod]) {
warn(
logging,
logger.warn(
'astro',
`Lower case endpoint names are deprecated and will not be supported in Astro 4.0. Rename the endpoint ${lowerCaseMethod} to ${method}.`
);
@ -43,12 +42,12 @@ export async function renderEndpoint(
mod: EndpointHandler,
context: APIContext,
ssr: boolean,
logging: LogOptions
logger: Logger
) {
const { request } = context;
const chosenMethod = request.method?.toUpperCase();
const handler = getHandlerFromModule(mod, chosenMethod, logging);
const handler = getHandlerFromModule(mod, chosenMethod, logger);
// TODO: remove the 'get' check in Astro 4.0
if (!ssr && ssr === false && chosenMethod && chosenMethod !== 'GET' && chosenMethod !== 'get') {
// eslint-disable-next-line no-console

View file

@ -2,14 +2,14 @@ import type * as vite from 'vite';
import type { AstroSettings } from '../@types/astro';
import * as fs from 'node:fs';
import { warn, type LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import { log404 } from './common.js';
import { writeHtmlResponse } from './response.js';
export function baseMiddleware(
settings: AstroSettings,
logging: LogOptions
logger: Logger
): vite.Connect.NextHandleFunction {
const { config } = settings;
const site = config.site ? new URL(config.base, config.site) : undefined;
@ -28,13 +28,13 @@ export function baseMiddleware(
}
if (pathname === '/' || pathname === '/index.html') {
log404(logging, pathname);
log404(logger, pathname);
const html = subpathNotUsedTemplate(devRoot, pathname);
return writeHtmlResponse(res, 404, html);
}
if (req.headers.accept?.includes('text/html')) {
log404(logging, pathname);
log404(logger, pathname);
const html = notFoundTemplate({
statusCode: 404,
title: 'Not found',
@ -49,8 +49,7 @@ export function baseMiddleware(
fs.stat(publicPath, (_err, stats) => {
if (stats) {
const expectedLocation = new URL('.' + url, devRootURL).pathname;
warn(
logging,
logger.warn(
'dev',
`Requests for items in your public folder must also include your base. ${url} should be ${expectedLocation}. Omitting the base will break in production.`
);

View file

@ -1,6 +1,6 @@
import { info, type LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import * as msg from '../core/messages.js';
export function log404(logging: LogOptions, pathname: string) {
info(logging, 'serve', msg.req({ url: pathname, statusCode: 404 }));
export function log404(logger: Logger, pathname: string) {
logger.info('serve', msg.req({ url: pathname, statusCode: 404 }));
}

View file

@ -5,8 +5,7 @@ import type {
SSRLoadedRenderer,
SSRManifest,
} from '../@types/astro';
import type { LogOptions } from '../core/logger/core';
import { Logger } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core';
import type { ModuleLoader } from '../core/module-loader';
import { Pipeline } from '../core/pipeline.js';
import type { Environment } from '../core/render';
@ -22,18 +21,18 @@ export default class DevPipeline extends Pipeline {
constructor({
manifest,
logging,
logger,
settings,
loader,
}: {
manifest: SSRManifest;
logging: LogOptions;
logger: Logger;
settings: AstroSettings;
loader: ModuleLoader;
}) {
const env = DevPipeline.createDevelopmentEnvironment(manifest, settings, logging, loader);
const env = DevPipeline.createDevelopmentEnvironment(manifest, settings, logger, loader);
super(env);
this.#devLogger = new Logger(logging);
this.#devLogger = logger;
this.#settings = settings;
this.#loader = loader;
this.setEndpointHandler(this.#handleEndpointResult);
@ -69,21 +68,20 @@ export default class DevPipeline extends Pipeline {
static createDevelopmentEnvironment(
manifest: SSRManifest,
settings: AstroSettings,
logging: LogOptions,
logger: Logger,
loader: ModuleLoader
): Environment {
const mode: RuntimeMode = 'development';
return createEnvironment({
adapterName: manifest.adapterName,
logging,
logger,
mode,
// This will be overridden in the dev server
renderers: [],
clientDirectives: manifest.clientDirectives,
compressHTML: manifest.compressHTML,
resolve: createResolve(loader, settings.config.root),
routeCache: new RouteCache(logging, mode),
routeCache: new RouteCache(logger, mode),
site: manifest.site,
ssr: isServerLikeOutput(settings.config),
streaming: true,

View file

@ -1,31 +0,0 @@
import type { AstroSettings, RuntimeMode, SSRManifest } from '../@types/astro.js';
import type { LogOptions } from '../core/logger/core.js';
import type { ModuleLoader } from '../core/module-loader';
import type { Environment } from '../core/render';
import { createEnvironment } from '../core/render/index.js';
import { RouteCache } from '../core/render/route-cache.js';
import { isServerLikeOutput } from '../prerender/utils.js';
import { createResolve } from './resolve.js';
export function createDevelopmentEnvironment(
manifest: SSRManifest,
settings: AstroSettings,
logging: LogOptions,
loader: ModuleLoader
): Environment {
const mode: RuntimeMode = 'development';
return createEnvironment({
adapterName: manifest.adapterName,
logging,
mode,
// This will be overridden in the dev server
renderers: [],
clientDirectives: manifest.clientDirectives,
compressHTML: manifest.compressHTML,
resolve: createResolve(loader, settings.config.root),
routeCache: new RouteCache(logging, mode),
site: manifest.site,
ssr: isServerLikeOutput(settings.config),
streaming: true,
});
}

View file

@ -2,7 +2,7 @@ import type fs from 'node:fs';
import type * as vite from 'vite';
import type { AstroSettings, ManifestData, SSRManifest } from '../@types/astro';
import { patchOverlay } from '../core/errors/overlay.js';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import { createViteLoader } from '../core/module-loader/index.js';
import { createRouteManifest } from '../core/routing/index.js';
import { baseMiddleware } from './base.js';
@ -12,13 +12,13 @@ import { handleRequest } from './request.js';
export interface AstroPluginOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
fs: typeof fs;
}
export default function createVitePluginAstroServer({
settings,
logging,
logger,
fs: fsMod,
}: AstroPluginOptions): vite.Plugin {
return {
@ -26,15 +26,15 @@ export default function createVitePluginAstroServer({
configureServer(viteServer) {
const loader = createViteLoader(viteServer);
const manifest = createDevelopmentManifest(settings);
const pipeline = new DevPipeline({ logging, manifest, settings, loader });
let manifestData: ManifestData = createRouteManifest({ settings, fsMod }, logging);
const pipeline = new DevPipeline({ logger, manifest, settings, loader });
let manifestData: ManifestData = createRouteManifest({ settings, fsMod }, logger);
const controller = createController({ loader });
/** rebuild the route cache + manifest, as needed. */
function rebuildManifest(needsManifestRebuild: boolean) {
pipeline.clearRouteCache();
if (needsManifestRebuild) {
manifestData = createRouteManifest({ settings }, logging);
manifestData = createRouteManifest({ settings }, logger);
}
}
// Rebuild route manifest on file change, if needed.
@ -47,7 +47,7 @@ export default function createVitePluginAstroServer({
// fix(#6067): always inject this to ensure zombie base handling is killed after restarts
viteServer.middlewares.stack.unshift({
route: '',
handle: baseMiddleware(settings, logging),
handle: baseMiddleware(settings, logger),
});
// Note that this function has a name so other middleware can find it.
viteServer.middlewares.use(async function astroDevHandler(request, response) {

View file

@ -51,7 +51,7 @@ export async function matchRoute(
pipeline: DevPipeline
): Promise<MatchedRoute | undefined> {
const env = pipeline.getEnvironment();
const { routeCache, logging } = env;
const { routeCache, logger } = env;
const matches = matchAllRoutes(pathname, manifestData);
const preloadedMatches = await getSortedPreloadedMatches({
pipeline,
@ -68,7 +68,7 @@ export async function matchRoute(
route: maybeRoute,
routeCache,
pathname: pathname,
logging,
logger,
ssr: isServerLikeOutput(pipeline.getConfig()),
});
return {
@ -106,7 +106,7 @@ export async function matchRoute(
);
}
log404(logging, pathname);
log404(logger, pathname);
const custom404 = getCustom404Route(manifestData);
if (custom404) {
@ -156,7 +156,7 @@ export async function handleRoute({
const settings = pipeline.getSettings();
const config = pipeline.getConfig();
const moduleLoader = pipeline.getModuleLoader();
const { logging } = env;
const { logger } = env;
if (!matchedRoute) {
return handle404Response(origin, incomingRequest, incomingResponse);
}
@ -171,7 +171,7 @@ export async function handleRoute({
headers: buildingToSSR ? incomingRequest.headers : new Headers(),
method: incomingRequest.method,
body,
logging,
logger,
ssr: buildingToSSR,
clientAddress: buildingToSSR ? incomingRequest.socket.remoteAddress : undefined,
locals: Reflect.get(incomingRequest, clientLocalsSymbol), // Allows adapters to pass in locals in dev mode.

View file

@ -1,12 +1,12 @@
import { transformWithEsbuild, type ESBuildTransformResult } from 'vite';
import type { AstroConfig } from '../@types/astro';
import { cachedCompilation, type CompileProps, type CompileResult } from '../core/compile/index.js';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import { getFileInfo } from '../vite-plugin-utils/index.js';
interface CachedFullCompilation {
compileProps: CompileProps;
logging: LogOptions;
logger: Logger;
}
interface FullCompileResult extends Omit<CompileResult, 'map'> {
@ -18,14 +18,14 @@ interface EnhanceCompilerErrorOptions {
id: string;
source: string;
config: AstroConfig;
logging: LogOptions;
logger: Logger;
}
const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms;
export async function cachedFullCompilation({
compileProps,
logging,
logger,
}: CachedFullCompilation): Promise<FullCompileResult> {
let transformResult: CompileResult;
let esbuildResult: ESBuildTransformResult;
@ -52,7 +52,7 @@ export async function cachedFullCompilation({
id: compileProps.filename,
source: compileProps.source,
config: compileProps.astroConfig,
logging: logging,
logger: logger,
});
throw err;
}

View file

@ -7,8 +7,7 @@ import {
isCached,
type CompileResult,
} from '../core/compile/index.js';
import type { LogOptions } from '../core/logger/core.js';
import { info } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import * as msg from '../core/messages.js';
import { isAstroScript } from './query.js';
@ -20,14 +19,15 @@ const isPkgFile = (id: string | null) => {
export interface HandleHotUpdateOptions {
config: AstroConfig;
logging: LogOptions;
logger: Logger;
compile: () => ReturnType<typeof cachedCompilation>;
source: string;
}
export async function handleHotUpdate(
ctx: HmrContext,
{ config, logging, compile, source }: HandleHotUpdateOptions
{ config, logger, compile, source }: HandleHotUpdateOptions
) {
let isStyleOnlyChange = false;
if (ctx.file.endsWith('.astro') && isCached(config, ctx.file)) {
@ -95,7 +95,7 @@ export async function handleHotUpdate(
// If only styles are changed, remove the component file from the update list
if (isStyleOnlyChange) {
info(logging, 'astro', msg.hmr({ file, style: true }));
logger.info('astro', msg.hmr({ file, style: true }));
// remove base file and hoisted scripts
return mods.filter((mod) => mod.id !== ctx.file && !mod.id?.endsWith('.ts'));
}
@ -124,9 +124,9 @@ export async function handleHotUpdate(
const isSelfAccepting = mods.every((m) => m.isSelfAccepting || m.url.endsWith('.svelte'));
if (isSelfAccepting) {
if (/astro\.config\.[cm][jt]s$/.test(file)) return mods;
info(logging, 'astro', msg.hmr({ file }));
logger.info('astro', msg.hmr({ file }));
} else {
info(logging, 'astro', msg.reload({ file }));
logger.info('astro', msg.reload({ file }));
}
return mods;

View file

@ -1,7 +1,7 @@
import type { SourceDescription } from 'rollup';
import type * as vite from 'vite';
import type { AstroSettings } from '../@types/astro';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import type { PluginMetadata as AstroPluginMetadata } from './types';
import { normalizePath } from 'vite';
@ -20,11 +20,11 @@ export type { AstroPluginMetadata };
interface AstroPluginOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}
/** Transform .astro files for Vite */
export default function astro({ settings, logging }: AstroPluginOptions): vite.Plugin[] {
export default function astro({ settings, logger }: AstroPluginOptions): vite.Plugin[] {
const { config } = settings;
let resolvedConfig: vite.ResolvedConfig;
@ -143,7 +143,7 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P
source,
};
const transformResult = await cachedFullCompilation({ compileProps, logging });
const transformResult = await cachedFullCompilation({ compileProps, logger });
for (const dep of transformResult.cssDeps) {
this.addWatchFile(dep);
@ -182,7 +182,7 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P
const compile = () => cachedCompilation(compileProps);
return handleHotUpdate(context, {
config,
logging,
logger,
compile,
source: compileProps.source,
});

View file

@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
import { normalizePath, type Plugin } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import { getContentPaths, getDotAstroTypeReference } from '../content/index.js';
import { info, type LogOptions } from '../core/logger/core.js';
import { type Logger } from '../core/logger/core.js';
export function getEnvTsPath({ srcDir }: { srcDir: URL }) {
return new URL('env.d.ts', srcDir);
@ -13,11 +13,11 @@ export function getEnvTsPath({ srcDir }: { srcDir: URL }) {
export function astroInjectEnvTsPlugin({
settings,
logging,
logger,
fs,
}: {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
fs: typeof fsMod;
}): Plugin {
return {
@ -26,18 +26,18 @@ export function astroInjectEnvTsPlugin({
// Ex. `.astro` types have been written
enforce: 'post',
async config() {
await setUpEnvTs({ settings, logging, fs });
await setUpEnvTs({ settings, logger, fs });
},
};
}
export async function setUpEnvTs({
settings,
logging,
logger,
fs,
}: {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
fs: typeof fsMod;
}) {
const envTsPath = getEnvTsPath(settings.config);
@ -57,7 +57,7 @@ export async function setUpEnvTs({
'types="astro/client"'
);
await fs.promises.writeFile(envTsPath, typesEnvContents, 'utf-8');
info(logging, 'assets', `Removed ${bold(envTsPathRelativetoRoot)} types`);
logger.info('assets', `Removed ${bold(envTsPathRelativetoRoot)} types`);
}
if (!fs.existsSync(dotAstroDir))
@ -68,7 +68,7 @@ export async function setUpEnvTs({
if (!typesEnvContents.includes(expectedTypeReference)) {
typesEnvContents = `${expectedTypeReference}\n${typesEnvContents}`;
await fs.promises.writeFile(envTsPath, typesEnvContents, 'utf-8');
info(logging, 'content', `Added ${bold(envTsPathRelativetoRoot)} types`);
logger.info('content', `Added ${bold(envTsPathRelativetoRoot)} types`);
}
} else {
// Otherwise, inject the `env.d.ts` file
@ -81,6 +81,6 @@ export async function setUpEnvTs({
await fs.promises.mkdir(settings.config.srcDir, { recursive: true });
await fs.promises.writeFile(envTsPath, referenceDefs.join('\n'), 'utf-8');
info(logging, 'astro', `Added ${bold(envTsPathRelativetoRoot)} types`);
logger.info('astro', `Added ${bold(envTsPathRelativetoRoot)} types`);
}
}

View file

@ -1,7 +1,7 @@
import type { PluginContext } from 'rollup';
import type { Plugin as VitePlugin } from 'vite';
import type { AstroSettings, InjectedRoute, ResolvedInjectedRoute } from '../@types/astro.js';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import { normalizePath } from 'vite';
import { runHookServerSetup } from '../integrations/index.js';
@ -9,16 +9,16 @@ import { runHookServerSetup } from '../integrations/index.js';
/** Connect Astro integrations into Vite, as needed. */
export default function astroIntegrationsContainerPlugin({
settings,
logging,
logger,
}: {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}): VitePlugin {
return {
name: 'astro:integration-container',
async configureServer(server) {
if (server.config.isProduction) return;
await runHookServerSetup({ config: settings.config, server, logging });
await runHookServerSetup({ config: settings.config, server, logger });
},
async buildStart() {
if (settings.injectedRoutes.length === settings.resolvedInjectedRoutes.length) return;

View file

@ -11,15 +11,14 @@ import type { Plugin } from 'vite';
import { normalizePath } from 'vite';
import type { AstroSettings } from '../@types/astro';
import { AstroError, AstroErrorData, MarkdownError } from '../core/errors/index.js';
import type { LogOptions } from '../core/logger/core.js';
import { warn } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import { isMarkdownFile, rootRelativePath } from '../core/util.js';
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
import { escapeViteEnvReferences, getFileInfo } from '../vite-plugin-utils/index.js';
interface AstroPluginOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}
function safeMatter(source: string, id: string) {
@ -57,7 +56,7 @@ const astroErrorModulePath = normalizePath(
fileURLToPath(new URL('../core/errors/index.js', import.meta.url))
);
export default function markdown({ settings, logging }: AstroPluginOptions): Plugin {
export default function markdown({ settings, logger }: AstroPluginOptions): Plugin {
return {
enforce: 'pre',
name: 'astro:markdown',
@ -101,8 +100,7 @@ export default function markdown({ settings, logging }: AstroPluginOptions): Plu
const { layout } = frontmatter;
if (frontmatter.setup) {
warn(
logging,
logger.warn(
'markdown',
`[${id}] Astro now supports MDX! Support for components in ".md" (or alternative extensions like ".markdown") files using the "setup" frontmatter is no longer enabled by default. Migrate this file to MDX.`
);

View file

@ -1,7 +1,7 @@
import type { TransformResult } from 'rollup';
import { transformWithEsbuild, type Plugin, type ResolvedConfig } from 'vite';
import type { AstroRenderer, AstroSettings } from '../@types/astro';
import type { LogOptions } from '../core/logger/core.js';
import type { Logger } from '../core/logger/core.js';
import type { PluginMetadata } from '../vite-plugin-astro/types';
import babel from '@babel/core';
@ -73,7 +73,7 @@ async function transformJSX({
interface AstroPluginJSXOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}
// Format inspired by https://github.com/vitejs/vite/blob/main/packages/vite/src/node/constants.ts#L54

View file

@ -1,25 +1,23 @@
import type { Plugin as VitePlugin } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import { type LogOptions } from '../core/logger/core.js';
import { type Logger } from '../core/logger/core.js';
import { bold } from 'kleur/colors';
import { extname } from 'node:path';
import { normalizePath } from 'vite';
import { warn } from '../core/logger/core.js';
import { isEndpoint, isPage, rootRelativePath } from '../core/util.js';
import { getPrerenderDefault, isServerLikeOutput } from '../prerender/utils.js';
import { scan } from './scan.js';
export interface AstroPluginScannerOptions {
settings: AstroSettings;
logging: LogOptions;
logger: Logger;
}
const KNOWN_FILE_EXTENSIONS = ['.astro', '.js', '.ts'];
export default function astroScannerPlugin({
settings,
logging,
logger,
}: AstroPluginScannerOptions): VitePlugin {
return {
name: 'astro:scanner',
@ -55,8 +53,7 @@ export default function astroScannerPlugin({
KNOWN_FILE_EXTENSIONS.includes(extname(filename))
) {
const reason = ` because \`output: "${settings.config.output}"\` is set`;
warn(
logging,
logger.warn(
'getStaticPaths',
`The getStaticPaths() statement in ${bold(
rootRelativePath(settings.config.root, fileURL, true)

View file

@ -6,6 +6,7 @@ import { removeDir } from '../dist/core/fs/index.js';
import testAdapter from './test-adapter.js';
import { testImageService } from './test-image-service.js';
import { loadFixture } from './test-utils.js';
import { Logger } from '../dist/core/logger/core.js';
describe('astro:image', () => {
/** @type {import('./test-utils').Fixture} */
@ -27,7 +28,7 @@ describe('astro:image', () => {
});
devServer = await fixture.startDevServer({
logging: {
logger: new Logger({
level: 'error',
dest: new Writable({
objectMode: true,
@ -36,7 +37,7 @@ describe('astro:image', () => {
callback();
},
}),
},
}),
});
});
@ -447,7 +448,7 @@ describe('astro:image', () => {
});
devServer = await fixture.startDevServer({
logging: {
logger: new Logger({
level: 'error',
dest: new Writable({
objectMode: true,
@ -456,7 +457,7 @@ describe('astro:image', () => {
callback();
},
}),
},
}),
});
});

View file

@ -1,6 +1,7 @@
import { expect } from 'chai';
import { load as cheerioLoad } from 'cheerio';
import { loadFixture } from './test-utils.js';
import { Logger } from '../dist/core/logger/core.js';
function addLeadingSlash(path) {
return path.startsWith('/') ? path : '/' + path;
@ -22,22 +23,22 @@ describe('Static build', () => {
let logs = [];
before(async () => {
/** @type {import('../src/core/logger/core').LogOptions} */
const logging = {
/** @type {import('../src/core/logger/core').Logger} */
const logger = new Logger({
dest: {
write(chunk) {
logs.push(chunk);
},
},
level: 'warn',
};
});
fixture = await loadFixture({
root: './fixtures/static-build/',
// test suite was authored when inlineStylesheets defaulted to never
build: { inlineStylesheets: 'never' },
});
await fixture.build({ logging });
await fixture.build({ logger });
});
it('Builds out .astro pages', async () => {

View file

@ -1,7 +1,7 @@
import { expect } from 'chai';
import { runHookBuildSetup } from '../../../dist/integrations/index.js';
import { validateSupportedFeatures } from '../../../dist/integrations/astroFeaturesValidation.js';
import { defaultLogging } from '../test-utils.js';
import { defaultLogger } from '../test-utils.js';
describe('Integration API', () => {
it('runHookBuildSetup should work', async () => {
@ -23,7 +23,7 @@ describe('Integration API', () => {
],
},
vite: {},
logging: {},
logger: defaultLogger,
pages: new Map(),
target: 'server',
});
@ -41,7 +41,7 @@ describe('Astro feature map', function () {
{
output: 'hybrid',
},
defaultLogging
defaultLogger
);
expect(result['hybridOutput']).to.be.true;
});
@ -53,7 +53,7 @@ describe('Astro feature map', function () {
{
output: 'hybrid',
},
defaultLogging
defaultLogger
);
expect(result['hybridOutput']).to.be.false;
});
@ -65,7 +65,7 @@ describe('Astro feature map', function () {
{
output: 'hybrid',
},
defaultLogging
defaultLogger
);
expect(result['hybridOutput']).to.be.false;
});
@ -78,7 +78,7 @@ describe('Astro feature map', function () {
{
output: 'static',
},
defaultLogging
defaultLogger
);
expect(result['staticOutput']).to.be.true;
});
@ -90,7 +90,7 @@ describe('Astro feature map', function () {
{
output: 'static',
},
defaultLogging
defaultLogger
);
expect(result['staticOutput']).to.be.false;
});
@ -103,7 +103,7 @@ describe('Astro feature map', function () {
{
output: 'hybrid',
},
defaultLogging
defaultLogger
);
expect(result['hybridOutput']).to.be.true;
});
@ -117,7 +117,7 @@ describe('Astro feature map', function () {
{
output: 'hybrid',
},
defaultLogging
defaultLogger
);
expect(result['hybridOutput']).to.be.false;
});
@ -130,7 +130,7 @@ describe('Astro feature map', function () {
{
output: 'server',
},
defaultLogging
defaultLogger
);
expect(result['serverOutput']).to.be.true;
});
@ -144,7 +144,7 @@ describe('Astro feature map', function () {
{
output: 'server',
},
defaultLogging
defaultLogger
);
expect(result['serverOutput']).to.be.false;
});
@ -167,7 +167,7 @@ describe('Astro feature map', function () {
},
},
},
defaultLogging
defaultLogger
);
expect(result['assets']).to.be.true;
});
@ -187,7 +187,7 @@ describe('Astro feature map', function () {
},
},
},
defaultLogging
defaultLogger
);
expect(result['assets']).to.be.true;
});
@ -208,7 +208,7 @@ describe('Astro feature map', function () {
},
},
},
defaultLogging
defaultLogger
);
expect(result['assets']).to.be.false;
});

View file

@ -2,7 +2,7 @@ import { expect } from 'chai';
import { fileURLToPath } from 'node:url';
import { createRouteManifest } from '../../../dist/core/routing/manifest/create.js';
import { createBasicSettings, createFs, defaultLogging } from '../test-utils.js';
import { createBasicSettings, createFs, defaultLogger } from '../test-utils.js';
const root = new URL('../../fixtures/alias/', import.meta.url);
@ -77,7 +77,7 @@ describe('routing - createRouteManifest', () => {
settings,
fsMod: fs,
},
defaultLogging
defaultLogger
);
expect(manifest.routes[0].route).to.equal('/foo');

View file

@ -2,7 +2,7 @@ import {
createBasicSettings,
createFs,
createRequestAndResponse,
defaultLogging,
defaultLogger,
} from '../test-utils.js';
import { createRouteManifest, matchAllRoutes } from '../../../dist/core/routing/index.js';
import { fileURLToPath } from 'node:url';
@ -140,19 +140,19 @@ describe('Route matching', () => {
container = await createContainer({
fs,
settings,
logging: defaultLogging,
logger: defaultLogger,
});
const loader = createViteLoader(container.viteServer);
const manifest = createDevelopmentManifest(container.settings);
pipeline = new DevPipeline({ manifest, logging: defaultLogging, settings, loader });
pipeline = new DevPipeline({ manifest, logger: defaultLogger, settings, loader });
manifestData = createRouteManifest(
{
cwd: fileURLToPath(root),
settings,
fsMod: fs,
},
defaultLogging
defaultLogger
);
});

View file

@ -2,7 +2,7 @@ import { expect } from 'chai';
import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/index.js';
import { createViteLoader } from '../../../dist/core/module-loader/index.js';
import { createBasicSettings, defaultLogging } from '../test-utils.js';
import { createBasicSettings, defaultLogger } from '../test-utils.js';
const root = new URL('../../fixtures/alias/', import.meta.url);
@ -12,7 +12,7 @@ describe('<Code />', () => {
let mod;
before(async () => {
const settings = await createBasicSettings({ root: fileURLToPath(root) });
container = await createContainer({ settings, logging: defaultLogging });
container = await createContainer({ settings, logger: defaultLogger });
const loader = createViteLoader(container.viteServer);
mod = await loader.import('astro/components/Shiki.js');
});

View file

@ -12,12 +12,13 @@ import { resolveConfig } from '../../dist/core/config/index.js';
import { createBaseSettings } from '../../dist/core/config/settings.js';
import { createContainer } from '../../dist/core/dev/container.js';
import { unixify } from './correct-path.js';
import { Logger } from '../../dist/core/logger/core.js';
/** @type {import('../../src/core/logger/core').LogOptions} */
export const defaultLogging = {
/** @type {import('../../src/core/logger/core').Logger} */
export const defaultLogger = new Logger({
dest: nodeLogDestination,
level: 'error',
};
});
/** @type {import('../../src/core/logger/core').LogOptions} */
export const silentLogging = {
@ -187,7 +188,7 @@ export function createBasicEnvironment(options = {}) {
clientDirectives: getDefaultClientDirectives(),
resolve: options.resolve ?? ((s) => Promise.resolve(s)),
routeCache: new RouteCache(options.logging, mode),
logging: options.logging ?? defaultLogging,
logger: options.logger ?? defaultLogger,
ssr: options.ssr ?? true,
streaming: options.streaming ?? true,
});
@ -223,7 +224,7 @@ export async function runInContainer(options = {}, callback) {
fs: options?.fs ?? realFS,
settings,
inlineConfig: options.inlineConfig ?? {},
logging: defaultLogging,
logger: defaultLogger,
});
try {
await callback(container);

View file

@ -8,7 +8,7 @@ import {
createBasicSettings,
createFs,
createRequestAndResponse,
defaultLogging,
defaultLogger,
} from '../test-utils.js';
import { createDevelopmentManifest } from '../../../dist/vite-plugin-astro-server/plugin.js';
import DevPipeline from '../../../dist/vite-plugin-astro-server/devPipeline.js';
@ -21,7 +21,7 @@ async function createDevPipeline(overrides = {}) {
return new DevPipeline({
manifest,
settings,
logging: defaultLogging,
logging: defaultLogger,
loader,
});
}
@ -53,7 +53,7 @@ describe('vite-plugin-astro-server', () => {
fsMod: fs,
settings: pipeline.getSettings(),
},
defaultLogging
defaultLogger
);
try {