Skip to content

Commit

Permalink
feat: pass logger to integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Jul 27, 2023
1 parent 7d7b389 commit 508a268
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 100 deletions.
126 changes: 79 additions & 47 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type { AstroCookies } from '../core/cookies';
import type { LogOptions } from '../core/logger/core';
import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
import { AstroIntegrationLogger } from '../core/logger/core';
export type {
MarkdownHeading,
MarkdownMetadata,
Expand Down Expand Up @@ -1856,56 +1857,87 @@ export interface AstroIntegration {
name: string;
/** The different hooks available to extend. */
hooks: {
'astro:config:setup'?: (options: {
config: AstroConfig;
command: 'dev' | 'build' | 'preview';
isRestart: boolean;
updateConfig: (newConfig: Record<string, any>) => void;
addRenderer: (renderer: AstroRenderer) => void;
addWatchFile: (path: URL | string) => void;
injectScript: (stage: InjectedScriptStage, content: string) => void;
injectRoute: (injectRoute: InjectedRoute) => void;
addClientDirective: (directive: ClientDirectiveConfig) => void;
// TODO: Add support for `injectElement()` for full HTML element injection, not just scripts.
// This may require some refactoring of `scripts`, `styles`, and `links` into something
// more generalized. Consider the SSR use-case as well.
// injectElement: (stage: vite.HtmlTagDescriptor, element: string) => void;
}) => void | Promise<void>;
'astro:config:done'?: (options: {
config: AstroConfig;
setAdapter: (adapter: AstroAdapter) => void;
}) => void | Promise<void>;
'astro:server:setup'?: (options: { server: vite.ViteDevServer }) => void | Promise<void>;
'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>;
'astro:server:done'?: () => void | Promise<void>;
'astro:build:ssr'?: (options: {
manifest: SerializedSSRManifest;
/**
* This maps a {@link RouteData} to an {@link URL}, this URL represents
* the physical file you should import.
*/
entryPoints: Map<RouteData, URL>;
/**
* File path of the emitted middleware
*/
middlewareEntryPoint: URL | undefined;
}) => void | Promise<void>;
'astro:build:start'?: () => void | Promise<void>;
'astro:build:setup'?: (options: {
vite: vite.InlineConfig;
pages: Map<string, PageBuildData>;
target: 'client' | 'server';
updateConfig: (newConfig: vite.InlineConfig) => void;
}) => void | Promise<void>;
'astro:build:generated'?: (options: { dir: URL }) => void | Promise<void>;
'astro:build:done'?: (options: {
pages: { pathname: string }[];
dir: URL;
routes: RouteData[];
}) => void | Promise<void>;
'astro:config:setup'?: (
options: {
config: AstroConfig;
command: 'dev' | 'build' | 'preview';
isRestart: boolean;
updateConfig: (newConfig: Record<string, any>) => void;
addRenderer: (renderer: AstroRenderer) => void;
addWatchFile: (path: URL | string) => void;
injectScript: (stage: InjectedScriptStage, content: string) => void;
injectRoute: (injectRoute: InjectedRoute) => void;
addClientDirective: (directive: ClientDirectiveConfig) => void;
// TODO: Add support for `injectElement()` for full HTML element injection, not just scripts.
// This may require some refactoring of `scripts`, `styles`, and `links` into something
// more generalized. Consider the SSR use-case as well.
// injectElement: (stage: vite.HtmlTagDescriptor, element: string) => void;
},
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:config:done'?: (
options: {
config: AstroConfig;
setAdapter: (adapter: AstroAdapter) => void;
},
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:server:setup'?: (
options: { server: vite.ViteDevServer },
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:server:start'?: (
options: { address: AddressInfo },
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:server:done'?: (bag: AstroIntegrationBag) => void | Promise<void>;
'astro:build:ssr'?: (
options: {
manifest: SerializedSSRManifest;
/**
* This maps a {@link RouteData} to an {@link URL}, this URL represents
* the physical file you should import.
*/
entryPoints: Map<RouteData, URL>;
/**
* File path of the emitted middleware
*/
middlewareEntryPoint: URL | undefined;
},
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:build:start'?: (bag: AstroIntegrationBag) => void | Promise<void>;
'astro:build:setup'?: (
options: {
vite: vite.InlineConfig;
pages: Map<string, PageBuildData>;
target: 'client' | 'server';
updateConfig: (newConfig: vite.InlineConfig) => void;
},
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:build:generated'?: (
options: { dir: URL },
bag: AstroIntegrationBag
) => void | Promise<void>;
'astro:build:done'?: (
options: {
pages: { pathname: string }[];
dir: URL;
routes: RouteData[];
},
bag: AstroIntegrationBag
) => void | Promise<void>;
};
}

/**
* A set of utilities that are passed at each hook
*/
export type AstroIntegrationBag = {
logger: AstroIntegrationLogger;
};

export type MiddlewareNext<R> = () => Promise<R>;
export type MiddlewareHandler<R> = (
context: APIContext,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/logger/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const consoleLogDestination = {

function getPrefix() {
let prefix = '';
let type = event.type;
let type = event.label;
if (type) {
// hide timestamp when type is undefined
prefix += dim(dateTimeFormat.format(new Date()) + ' ');
Expand Down
69 changes: 59 additions & 10 deletions packages/astro/src/core/logger/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ interface LogWritable<T> {
}

export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino
export type LoggerEvent = 'info' | 'warn' | 'error';

export interface LogOptions {
dest: LogWritable<LogMessage>;
Expand All @@ -29,7 +28,7 @@ export const dateTimeFormat = new Intl.DateTimeFormat([], {
});

export interface LogMessage {
type: string | null;
label: string | null;
level: LoggerLevel;
message: string;
}
Expand All @@ -43,11 +42,11 @@ export const levels: Record<LoggerLevel, number> = {
};

/** Full logging API */
export function log(opts: LogOptions, level: LoggerLevel, type: string | null, message: string) {
export function log(opts: LogOptions, level: LoggerLevel, label: string | null, message: string) {
const logLevel = opts.level;
const dest = opts.dest;
const event: LogMessage = {
type,
label,
level,
message,
};
Expand All @@ -61,18 +60,18 @@ export function log(opts: LogOptions, level: LoggerLevel, type: string | null, m
}

/** Emit a user-facing message. Useful for UI and other console messages. */
export function info(opts: LogOptions, type: string | null, message: string) {
return log(opts, 'info', type, message);
export function info(opts: LogOptions, label: string | null, message: string) {
return log(opts, 'info', label, message);
}

/** Emit a warning message. Useful for high-priority messages that aren't necessarily errors. */
export function warn(opts: LogOptions, type: string | null, message: string) {
return log(opts, 'warn', type, message);
export function warn(opts: LogOptions, label: string | null, message: string) {
return log(opts, 'warn', label, message);
}

/** Emit a error message, Useful when Astro can't recover from some error. */
export function error(opts: LogOptions, type: string | null, message: string) {
return log(opts, 'error', type, message);
export function error(opts: LogOptions, label: string | null, message: string) {
return log(opts, 'error', label, message);
}

type LogFn = typeof info | typeof warn | typeof error;
Expand Down Expand Up @@ -127,3 +126,53 @@ export function timerMessage(message: string, startTime: number = Date.now()) {
timeDiff < 750 ? `${Math.round(timeDiff)}ms` : `${(timeDiff / 1000).toFixed(1)}s`;
return `${message} ${dim(timeDisplay)}`;
}

export class Logger {
options: LogOptions;
constructor(options: LogOptions) {
this.options = options;
}

info(label: string, message: string) {
info(this.options, label, message);
}
warn(label: string, message: string) {
warn(this.options, label, message);
}
error(label: string, message: string) {
error(this.options, label, message);
}
debug(label: string, message: string) {
debug(this.options, label, message);
}
}

export class AstroIntegrationLogger {
options: LogOptions;
label: string;

constructor(logging: LogOptions, label: string) {
this.options = logging;
this.label = label;
}

/**
* Creates a new logger instances with a new label, but the same log options.
*/
fork(label: string): AstroIntegrationLogger {
return new AstroIntegrationLogger(this.options, label);
}

info(message: string) {
info(this.options, this.label, message);
}
warn(message: string) {
warn(this.options, this.label, message);
}
error(message: string) {
error(this.options, this.label, message);
}
debug(message: string) {
debug(this.options, this.label, message);
}
}
14 changes: 7 additions & 7 deletions packages/astro/src/core/logger/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ export const nodeLogDestination = new Writable({

function getPrefix() {
let prefix = '';
let type = event.type;
if (type) {
let label = event.label;
if (label) {
// hide timestamp when type is undefined
prefix += dim(dateTimeFormat.format(new Date()) + ' ');
if (event.level === 'info') {
type = bold(cyan(`[${type}]`));
label = bold(cyan(`[${label}]`));
} else if (event.level === 'warn') {
type = bold(yellow(`[${type}]`));
label = bold(yellow(`[${label}]`));
} else if (event.level === 'error') {
type = bold(red(`[${type}]`));
label = bold(red(`[${label}]`));
}

prefix += `${type} `;
prefix += `${label} `;
}
return reset(prefix);
}
Expand Down Expand Up @@ -87,7 +87,7 @@ export const nodeLogOptions: Required<LogOptions> = {
};

export interface LogMessage {
type: string | null;
label: string | null;
level: LoggerLevel;
message: string;
}
Expand Down
Loading

0 comments on commit 508a268

Please sign in to comment.