AutoRest core module that generates client libraries for accessing RESTful web services from OpenAPI specifications.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
AutoRest Core provides a comprehensive event-driven messaging system for structured logging, error reporting, and multi-channel communication throughout the code generation process. This system enables detailed monitoring, debugging, and integration with external tools.
Core message interface for all communication within AutoRest.
/**
* Represents a message generated during AutoRest processing
*/
interface Message {
/** The channel/severity level of the message */
Channel: Channel;
/** The main message text */
Text: string;
/** Message key for categorization (optional) */
Key?: Iterable<string>;
/** Additional details or context (optional) */
Details?: any;
/** Source location information (optional) */
Source?: Array<SourceLocation>;
/** Text range information (optional) */
Range?: Iterable<Range>;
/** Plugin that generated the message (optional) */
Plugin?: string;
/** Pre-formatted message text (optional) */
FormattedMessage?: string;
}Enumeration of all available message channels for categorizing messages by severity and type.
/**
* Available message channels for categorizing messages
*/
enum Channel {
/** General information messages */
Information = "information",
/** Warning messages that don't stop processing */
Warning = "warning",
/** Error messages indicating processing failures */
Error = "error",
/** Debug messages for troubleshooting */
Debug = "debug",
/** Verbose output for detailed logging */
Verbose = "verbose",
/** Fatal errors that stop processing */
Fatal = "fatal",
/** Hints and suggestions for improvement */
Hint = "hint",
/** File-related messages */
File = "file",
/** Configuration-related messages */
Configuration = "configuration"
}Usage Examples:
import { AutoRest, Channel } from "@microsoft.azure/autorest-core";
const autorest = new AutoRest();
// Listen to all messages
autorest.Message.Subscribe((sender, message) => {
const timestamp = new Date().toISOString();
const prefix = `[${timestamp}] ${message.Channel.toUpperCase()}:`;
switch (message.Channel) {
case Channel.Error:
case Channel.Fatal:
console.error(`${prefix} ${message.Text}`);
if (message.Details) {
console.error("Details:", message.Details);
}
break;
case Channel.Warning:
console.warn(`${prefix} ${message.Text}`);
break;
case Channel.Information:
console.log(`${prefix} ${message.Text}`);
break;
case Channel.Debug:
case Channel.Verbose:
if (process.env.DEBUG) {
console.log(`${prefix} ${message.Text}`);
}
break;
case Channel.Hint:
console.log(`💡 ${prefix} ${message.Text}`);
break;
case Channel.File:
console.log(`📁 ${prefix} ${message.Text}`);
break;
case Channel.Configuration:
console.log(`⚙️ ${prefix} ${message.Text}`);
break;
}
// Log source location if available
if (message.Source && message.Source.length > 0) {
message.Source.forEach(source => {
console.log(` at ${source.document}:${source.Position.line}:${source.Position.column}`);
});
}
});Interface for generated file artifacts.
/**
* Represents a generated file artifact
*/
interface Artifact {
/** URI of the generated file */
uri: string;
/** Type/category of the generated file */
type: string;
/** Content of the generated file */
content: string;
}
/**
* Message specific to file artifacts with source mapping information
*/
interface ArtifactMessage extends Message {
/** Artifact details with optional source map */
Details: Artifact & {
/** Source map for generated content (optional) */
sourceMap?: Mappings | RawSourceMap
};
}Usage Examples:
import { AutoRest } from "@microsoft.azure/autorest-core";
const autorest = new AutoRest();
// Track generated files
const generatedFiles: Map<string, Artifact> = new Map();
autorest.GeneratedFile.Subscribe((sender, artifact) => {
generatedFiles.set(artifact.uri, artifact);
console.log(`Generated ${artifact.type}: ${artifact.uri}`);
console.log(`Content size: ${artifact.content.length} bytes`);
// Save file if needed
if (artifact.type === "client") {
const fileName = artifact.uri.split('/').pop();
console.log(`Main client file: ${fileName}`);
}
});
// Monitor all outputs after processing
autorest.Finished.Subscribe((sender, result) => {
console.log(`\nGeneration Summary:`);
console.log(`Total files generated: ${generatedFiles.size}`);
const typeCount = new Map<string, number>();
generatedFiles.forEach(artifact => {
const count = typeCount.get(artifact.type) || 0;
typeCount.set(artifact.type, count + 1);
});
typeCount.forEach((count, type) => {
console.log(` ${type}: ${count} files`);
});
});Interfaces for tracking source locations and ranges in messages.
/**
* Represents a location in a source document
*/
interface SourceLocation {
/** The source document identifier */
document: string;
/** Enhanced position within the document with additional metadata */
Position: EnhancedPosition;
}
/**
* Represents a text range in a document
*/
interface Range {
/** The source document identifier */
document: string;
/** Start position of the range */
start: Position;
/** End position of the range */
end: Position;
}
/**
* Represents a position in a text document (from source-map library)
*/
interface Position {
/** Line number (1-based) */
line: number;
/** Column number (0-based) */
column: number;
}
/**
* Enhanced position with additional metadata
*/
type EnhancedPosition = Position & {
/** JSONPath to the element */
path?: JsonPath;
/** Length of the element */
length?: number;
/** Offset to the value within the element */
valueOffset?: number;
/** Length of the value */
valueLength?: number;
}Usage Example:
// Example of how source location information appears in messages
autorest.Message.Subscribe((sender, message) => {
if (message.Channel === Channel.Error && message.Source) {
console.error(`Error: ${message.Text}`);
message.Source.forEach(location => {
console.error(` in ${location.document} at line ${location.Position.line}, column ${location.Position.column}`);
});
if (message.Range) {
for (const range of message.Range) {
console.error(` Range: ${range.start.line}:${range.start.column} - ${range.end.line}:${range.end.column}`);
}
}
}
});You can create sophisticated message handling logic:
import { AutoRest, Channel, Message } from "@microsoft.azure/autorest-core";
class MessageProcessor {
private errorCount = 0;
private warningCount = 0;
private debugMessages: Message[] = [];
constructor(private autorest: AutoRest) {
this.autorest.Message.Subscribe(this.handleMessage.bind(this));
}
private handleMessage(sender: AutoRest, message: Message): void {
// Count messages by type
switch (message.Channel) {
case Channel.Error:
case Channel.Fatal:
this.errorCount++;
this.logError(message);
break;
case Channel.Warning:
this.warningCount++;
this.logWarning(message);
break;
case Channel.Debug:
this.debugMessages.push(message);
break;
}
}
private logError(message: Message): void {
console.error(`❌ Error: ${message.Text}`);
if (message.Details) {
console.error("Details:", JSON.stringify(message.Details, null, 2));
}
}
private logWarning(message: Message): void {
console.warn(`⚠️ Warning: ${message.Text}`);
}
getSummary(): { errors: number; warnings: number; debugCount: number } {
return {
errors: this.errorCount,
warnings: this.warningCount,
debugCount: this.debugMessages.length
};
}
exportDebugLog(): string {
return this.debugMessages
.map(msg => `[${msg.Channel}] ${msg.Text}`)
.join('\n');
}
}
// Usage
const autorest = new AutoRest();
const processor = new MessageProcessor(autorest);
// ... configure and run autorest ...
const summary = processor.getSummary();
console.log(`Processing completed with ${summary.errors} errors and ${summary.warnings} warnings`);The message system can be integrated with external logging and monitoring tools:
import { AutoRest, Channel, Message } from "@microsoft.azure/autorest-core";
interface LogEntry {
timestamp: string;
level: string;
message: string;
source?: string;
details?: any;
}
class StructuredLogger {
private logs: LogEntry[] = [];
constructor(autorest: AutoRest) {
autorest.Message.Subscribe(this.logMessage.bind(this));
}
private logMessage(sender: AutoRest, message: Message): void {
const entry: LogEntry = {
timestamp: new Date().toISOString(),
level: this.mapChannelToLevel(message.Channel),
message: message.Text
};
if (message.Source && message.Source.length > 0) {
entry.source = `${message.Source[0].document}:${message.Source[0].Position.line}`;
}
if (message.Details) {
entry.details = message.Details;
}
this.logs.push(entry);
// Send to external logging service
this.sendToExternalLogger(entry);
}
private mapChannelToLevel(channel: Channel): string {
switch (channel) {
case Channel.Fatal:
case Channel.Error:
return "error";
case Channel.Warning:
return "warn";
case Channel.Information:
return "info";
case Channel.Debug:
case Channel.Verbose:
return "debug";
default:
return "info";
}
}
private sendToExternalLogger(entry: LogEntry): void {
// Integration with external logging service
// e.g., send to Elasticsearch, CloudWatch, etc.
}
exportLogs(): LogEntry[] {
return [...this.logs];
}
}