@remotex-labs/xjet 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bash.js.map CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/providers/stack.provider.ts", "../src/modules/symlinks/services/inject.service.ts", "../src/services/framework.service.ts", "../src/errors/base.error.ts", "../src/errors/uncaught.error.ts", "../src/providers/cli.provider.ts", "../src/components/banner.component.ts", "../src/providers/configuration.provider.ts", "../src/configuration/default.configuration.ts", "../src/configuration/parse.configuration.ts", "../src/services/vm.service.ts", "../src/errors/vm-runtime.error.ts", "../src/services/transpiler.service.ts", "../src/errors/xjet.error.ts", "../src/errors/esbuild.error.ts", "../src/services/suites.service.ts", "../src/services/watch.service.ts", "../src/providers/specs.provider.ts", "../src/components/glob.component.ts", "../src/providers/import-resolver.provider.ts", "../src/modules/messages/services/reports.service.ts", "../src/modules/messages/constants/report.constant.ts", "../src/modules/messages/reports/json.reporter.ts", "../src/modules/messages/abstract/report.abstract.ts", "../src/modules/messages/reports/junit.reporter.ts", "../src/modules/messages/reports/console.report.ts", "../src/modules/messages/reports/constants/console.constant.ts", "../src/modules/messages/services/message.service.ts", "../src/modules/targets/services/local.service.ts", "../src/modules/targets/abstract/target.abstract.ts", "../src/modules/packets/packets.module.ts", "../src/modules/packets/schema/packet.schema.ts", "../src/modules/packets/constants/packet-schema.constants.ts", "../src/services/queue.service.ts", "../src/modules/targets/services/external.service.ts", "../src/errors/timeout.error.ts", "../src/modules/shared/services/timer.service.ts", "../src/components/timeout.component.ts", "../src/bash.ts"],
4
- "sourceRoot": "https://github.com/remotex-lab/xJet/tree/v1.4.0/",
5
- "sourcesContent": ["/**\n * Import will remove at compile time\n */\n\nimport type { StackInterface, StackContextInterface } from '@providers/interfaces/stack-provider.interface';\nimport type { StackMetadataInterface, StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { dirname, join, relative } from 'path';\nimport { inject } from '@symlinks/symlinks.module';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { FrameworkService } from '@services/framework.service';\nimport { Bias, type SourceOptionsInterface } from '@remotex-labs/xmap';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\nimport { parseErrorStack, type StackFrameInterface } from '@remotex-labs/xmap/parser.component';\nimport { formatErrorCode, type PositionWithCodeInterface } from '@remotex-labs/xmap/formatter.component';\n\n/**\n * Regular expression to match multiple consecutive spaces.\n *\n * @remarks\n * Used to normalize spacing in formatted strings by replacing sequences\n * of two or more spaces with a single space.\n *\n * @since 1.0.0\n */\n\nconst MULTIPLE_SPACES = /\\s{2,}/g;\n\n/**\n * Regular expression to detect HTTP or HTTPS URLs.\n *\n * @remarks\n * Used to identify URL-based source paths in stack traces or source maps.\n *\n * @since 1.0.0\n */\n\nconst URL_PATTERN = /^https?:\\/\\//;\n\n/**\n * Regular expression to detect HTTP or HTTPS URLs.\n *\n * @remarks\n * Used to identify URL-based source paths in stack traces or source maps.\n *\n * @since 1.0.0\n */\n\nconst FILE_PROTOCOL = /^file:\\/\\//;\n\n/**\n * Formats a single stack frame into a readable string.\n *\n * @param frame - The stack frame to format\n * @returns A string representing the formatted stack frame, including function name,\n * file path, and optional line/column information\n *\n * @remarks\n * - Shortens paths inside the framework root.\n * - Adds line and column information in gray if available.\n * - Applies coloring to the file path using {@link xterm.darkGray}.\n * - Normalizes multiple spaces in the output.\n *\n * @example\n * ```ts\n * const line = formatStackFrame.call(context, frame);\n * console.log(line); // at myFunction file.js [10:5]\n * ```\n *\n * @see xterm\n * @see MULTIPLE_SPACES\n *\n * @since 1.0.0\n */\n\nexport function formatStackFrame(this: StackContextInterface, frame: StackFrameInterface): string {\n if (frame.fileName?.includes(this.framework.rootPath)) {\n frame.fileName = relative(this.framework.rootPath, frame.fileName);\n }\n\n if (!frame.fileName) {\n return frame.source ?? '';\n }\n\n const position = (frame.line && frame.column)\n ? xterm.gray(`[${ frame.line }:${ frame.column }]`)\n : '';\n\n return `at ${ frame.functionName ?? '' } ${ xterm.darkGray(frame.fileName) } ${ position }`\n .replace(MULTIPLE_SPACES, ' ')\n .trim();\n}\n\n/**\n * Constructs a location string for a stack frame, suitable for links or display.\n *\n * @param frame - The stack frame being processed\n * @param position - The resolved source position with code\n * @returns A string representing the source location, including line number\n *\n * @remarks\n * - Handles HTTP/HTTPS URLs and file paths.\n * - Prepends the source root if available and normalizes path separators.\n * - Appends the line number using `#L` format.\n * - Falls back to the frame's fileName if no source is provided, stripping `file://` prefixes.\n *\n * @example\n * ```ts\n * const location = getSourceLocation.call(context, frame, position);\n * console.log(location); // src/utils/file.js#L12\n * ```\n *\n * @see URL_PATTERN\n * @see FILE_PROTOCOL\n *\n * @since 1.0.0\n */\n\nexport function getSourceLocation(this: StackContextInterface, frame: StackFrameInterface, position: Required<PositionWithCodeInterface>): string {\n const { source, sourceRoot, line } = position;\n\n if (source) {\n const lastIndex = source.lastIndexOf('http://');\n const lastHttpsIndex = source.lastIndexOf('https://');\n\n if (Math.max(lastIndex, lastHttpsIndex) !== -1)\n return `${ source.substring(Math.max(lastIndex, lastHttpsIndex)) }#L${ line }`;\n\n if (URL_PATTERN.test(source))\n return `${ source }#L${ line }`;\n\n if (sourceRoot) {\n const path = relative(\n dirname(this.framework.distPath),\n join(this.framework.distPath, source)\n ).replace(/\\\\/g, '/');\n\n return `${ sourceRoot }${ path }#L${ line }`;\n }\n\n return `${ source }#L${ line }`;\n }\n\n return frame.fileName ? frame.fileName.replace(FILE_PROTOCOL, '') : '';\n}\n\n/**\n * Highlights code at a specific position with syntax coloring.\n *\n * @param position - The position object containing the code to highlight\n * @returns The code string with applied syntax highlighting and formatting\n *\n * @remarks\n * - Uses {@link highlightCode} to apply syntax highlighting to the `position.code`.\n * - Wraps the highlighted code with {@link formatErrorCode} for additional formatting.\n * - Default highlight color is {@link xterm.brightPink}.\n *\n * @example\n * ```ts\n * const highlighted = highlightPositionCode({ code: 'const x = 1;', line: 1, column: 0 });\n * console.log(highlighted); // Outputs syntax-highlighted code string\n * ```\n *\n * @see highlightCode\n * @see formatErrorCode\n * @see xterm.brightPink\n *\n * @since 1.0.0\n */\n\nexport function highlightPositionCode(position: PositionWithCodeInterface): string {\n return formatErrorCode(\n { ...position, code: highlightCode(position.code) },\n { color: xterm.brightPink }\n );\n}\n\n/**\n * Formats a stack frame using position information and highlights the relevant code.\n *\n * @param frame - The stack frame to format\n * @param position - The resolved source position containing line, column, and code\n * @returns A formatted string representing the stack frame with function, file, and line information\n *\n * @remarks\n * - Caches the code and formatted code on the context for reuse.\n * - Uses {@link highlightPositionCode} to apply syntax highlighting.\n * - Builds the file location using {@link getSourceLocation}.\n * - Delegates final formatting to {@link formatStackFrame}.\n *\n * @example\n * ```ts\n * const formatted = formatFrameWithPosition.call(context, frame, position);\n * console.log(formatted); // at myFunction src/utils/file.js [10:5]\n * ```\n *\n * @see formatStackFrame\n * @see getSourceLocation\n * @see highlightPositionCode\n *\n * @since 1.0.0\n */\n\nexport function formatFrameWithPosition(this: StackContextInterface, frame: StackFrameInterface, position: Required<PositionWithCodeInterface>): string {\n if (!this.code) {\n this.code = position.code;\n this.source = position.source;\n this.formatCode = highlightPositionCode(position);\n }\n\n return formatStackFrame.call(this, {\n ...frame,\n line: position.line,\n column: position.column,\n functionName: position.name ?? frame.functionName,\n fileName: getSourceLocation.call(this, frame, position)\n });\n}\n\n/**\n * Processes a single stack frame and formats it for display, optionally including source map information.\n *\n * @param frame - The stack frame to process\n * @param options - Optional {@link SourceOptionsInterface} for retrieving source positions\n * @returns A formatted string representing the stack frame, or an empty string if filtered out\n *\n * @remarks\n * - Skips native frames if {@link StackContextInterface.withNativeFrames} is false.\n * - Skips framework files if {@link StackContextInterface.withFrameworkFrames} is false.\n * - Attempts to resolve source positions using {@link FrameworkService.getSourceMap} and\n * {@link getPositionWithCode}.\n * - Delegates formatting to {@link formatFrameWithPosition} or {@link formatStackFrame} depending on availability of position information.\n *\n * @example\n * ```ts\n * const formatted = stackEntry.call(context, frame, { includeCode: true });\n * console.log(formatted);\n * ```\n *\n * @see formatStackFrame\n * @see StackContextInterface\n * @see formatFrameWithPosition\n * @see FrameworkService.getSourceMap\n * @see SourceService.getPositionWithCode\n *\n * @since 1.0.0\n */\n\nexport function stackEntry(this: StackContextInterface, frame: StackFrameInterface, options?: SourceOptionsInterface): string {\n if (!this.withNativeFrames && frame.native) return '';\n if (!frame.line && !frame.column && !frame.fileName && !frame.functionName) return '';\n\n const source = this.framework.getSourceMap(frame.fileName ?? '');\n if (!source) {\n return formatStackFrame.call(this, frame);\n }\n\n const position = source.getPositionWithCode(\n frame.line ?? 0,\n frame.column ?? 0,\n Bias.LOWER_BOUND,\n options\n );\n\n if (position && (!this.withFrameworkFrames && this.framework.isFrameworkFile(position)))\n return '';\n\n if (position) {\n this.line = position.line;\n this.column = position.column;\n\n return formatFrameWithPosition.call(this, frame, position);\n }\n\n return formatStackFrame.call(this, frame);\n}\n\n/**\n * Parses an error stack trace into a structured and formatted representation.\n *\n * @param error - The {@link Error} object to parse\n * @param options - Optional {@link StackTraceInterface} configuration for controlling stack parsing\n * @returns A {@link StackInterface} object containing structured stack frames and formatted code\n *\n * @remarks\n * - Creates a {@link StackContextInterface} using the {@link FrameworkService} for resolving source maps.\n * - Uses {@link parseErrorStack} to convert the error into individual stack frames.\n * - Each frame is processed via {@link stackEntry}, applying filtering for native and framework files.\n * - Returns the fully formatted stack with code snippets and line/column metadata.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (error) {\n * const stackData = parseStackTrace(error);\n * console.log(stackData.stacks); // Array of formatted stack lines\n * console.log(stackData.formatCode); // Highlighted code snippet\n * }\n * ```\n *\n * @see stackEntry\n * @see StackInterface\n * @see parseErrorStack\n * @see StackTraceInterface\n * @see StackContextInterface\n *\n * @since 1.0.0\n */\n\nexport function parseStackTrace(error: Error, options: StackTraceInterface = {}): StackInterface {\n const context: StackContextInterface = {\n code: '',\n source: '',\n framework: inject(FrameworkService),\n formatCode: '',\n withNativeFrames: false,\n withFrameworkFrames: false,\n ...options,\n ...(globalThis.VERBOSE && {\n withNativeFrames: true,\n withFrameworkFrames: true\n })\n };\n\n const parsedStack = parseErrorStack(error);\n const stacks = parsedStack.stack\n .map(frame => stackEntry.call(context, frame, options))\n .filter(Boolean);\n\n return {\n stacks,\n code: context.code,\n line: context.line ?? 0,\n column: context.column ?? 0,\n source: context.source,\n formatCode: context.formatCode\n };\n}\n\n/**\n * Formats an error and its stack trace into a human-readable string with enhanced styling.\n *\n * @param error - The {@link Error} object to format\n * @param options - Optional {@link StackTraceInterface} configuration for stack parsing\n * @returns A string containing the formatted error message, highlighted code, and enhanced stack trace\n *\n * @remarks\n * - Parses the error stack using {@link parseStackTrace}.\n * - Applies syntax highlighting and formatting to the code snippet and stack frames.\n * - Prepends the error name and message, followed by highlighted code (if available) and formatted stack frames.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (error) {\n * console.log(formatStack(error));\n * }\n * ```\n *\n * @see xterm\n * @see parseStackTrace\n * @see StackTraceInterface\n *\n * @since 1.0.0\n */\n\nexport function formatStack(error: Error, options: StackTraceInterface = {}): string {\n const metadata = parseStackTrace(error, options);\n const parts = [ `\\n${ error.name }: ${ error.message }\\n\\n` ];\n if (metadata.formatCode) {\n parts.push(`${ metadata.formatCode }\\n\\n`);\n }\n\n if (metadata.stacks.length > 0) {\n parts.push(`Enhanced Stack Trace:\\n ${ metadata.stacks.join('\\n ') }\\n`);\n }\n\n return parts.join('');\n}\n\n/**\n * Extracts structured metadata from an error's stack trace.\n *\n * @param error - The {@link Error} object to process\n * @param options - Optional {@link StackTraceInterface} configuration for parsing the stack\n * @returns A {@link StackMetadataInterface} object containing code, line/column positions, formatted code, and stack frames\n *\n * @remarks\n * - Internally calls {@link parseStackTrace} to generate a structured representation of the stack trace.\n * - Prepends each stack frame with indentation for better readability.\n * - Useful for logging, debugging, or programmatic analysis of error stacks.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Unexpected error\");\n * } catch (error) {\n * const meta = stackMetadata(error);\n * console.log(meta.stacks); // Indented stack frames\n * console.log(meta.formatCode); // Highlighted code snippet\n * }\n * ```\n *\n * @see parseStackTrace\n * @see StackTraceInterface\n * @see StackMetadataInterface\n *\n * @since 1.0.0\n */\n\nexport function stackMetadata(error: Error, options: StackTraceInterface = {}): StackMetadataInterface {\n let metadata = parseStackTrace(error, options);\n if(metadata.stacks.length < 1) metadata = parseStackTrace(error, { withFrameworkFrames: true });\n\n return {\n code: metadata.code,\n line: metadata.line,\n column: metadata.column,\n source: metadata.source,\n stacks: ' ' + metadata.stacks.join('\\n '),\n formatCode: metadata.formatCode\n };\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ConstructorType } from '@remotex-labs/xjet-expect';\nimport type { InjectableOptionsInterface, TokenElementType } from '@symlinks/interfaces/symlinks.interface';\n\n/**\n * Stores singleton instances of injectable classes.\n *\n * @since 1.0.0\n */\n\nconst SINGLETONS = new Map<ConstructorType, unknown>();\n\n/**\n * Stores metadata for classes marked as injectable via `@Injectable`.\n *\n * @internal\n * @since 1.0.0\n */\n\nconst INJECTABLES = new Map<ConstructorType, InjectableOptionsInterface>();\n\n/**\n * Marks a class as injectable and stores its configuration metadata.\n *\n * @template T - The type of the class instance\n * @template Args - The types of arguments accepted by the constructor, defaults to `unknown[]`\n *\n * @param options - Optional configuration for the injectable, including scope and factory\n *\n * @example\n * ```ts\n * @Injectable({ scope: 'singleton' })\n * class MyService {}\n * ```\n *\n * @see InjectableOptionsInterface\n * @since 1.0.0\n */\n\nexport function Injectable<T = unknown, Args extends Array<unknown> = unknown[]>(options?: InjectableOptionsInterface) {\n return function (target: new (...args: Args) => T): void {\n INJECTABLES.set(target, options || {});\n };\n}\n\n/**\n * Resolves and returns an instance of the given injectable token.\n *\n * @template T - The type of the instance to return\n * @template Args - The types of arguments passed to the constructor or factory\n *\n * @param token - The injectable class or token to resolve\n * @param args - Arguments to pass to the constructor or factory\n *\n * @returns The resolved instance of type `T`\n *\n * @throws Error - If the token is not registered as injectable via `@Injectable`\n *\n * @remarks\n * If the injectable is marked with scope `'singleton'`, the same instance will be returned\n * on the following calls. Otherwise, a new instance is created for each call.\n *\n * @example\n * ```ts\n * const service = inject(MyService);\n * ```\n *\n * @see TokenElementType\n * @since 1.0.0\n */\n\nexport function inject<T, Args extends Array<unknown>>(token: TokenElementType<T, Args>, ...args: Args): T {\n if (SINGLETONS.has(token)) return <T>SINGLETONS.get(token);\n\n const metadata = INJECTABLES.get(token);\n if (!metadata) throw new Error(`Cannot inject ${ token.name } \u2013 not marked @Injectable`);\n\n const instance: T = metadata.factory\n ? <T>metadata.factory(...args)\n : new token(...args);\n\n if (metadata?.scope === 'singleton') {\n SINGLETONS.set(token, instance);\n }\n\n return instance;\n}\n", "/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { normalize } from 'path';\nimport { readFileSync } from 'fs';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { type PositionInterface, SourceService } from '@remotex-labs/xmap';\n\n/**\n * Provides access to the framework's file paths and associated source maps.\n *\n * @remarks\n * This service manages the framework's source map files, including the main framework\n * file and any additional source files. It caches initialized {@link SourceService}\n * instances for performance.\n *\n * @example\n * ```ts\n * const frameworkService = new FrameworkService();\n * console.log(frameworkService.rootPath);\n * const sourceMap = frameworkService.sourceMap(frameworkService.filePath);\n * ```\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FrameworkService {\n /**\n * Absolute path to the current file.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly filePath: string;\n\n /**\n * Absolute path to the distribution directory.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly distPath: string;\n\n /**\n * Absolute path to the project root directory.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly rootPath: string;\n\n /**\n * Source service for the main framework file.\n * @readonly\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n readonly frameworkSourceMap: SourceService;\n\n /**\n * Cached {@link SourceService} instances for additional source files.\n * @since 1.0.0\n */\n\n private readonly sourceMaps = new Map<string, SourceService>();\n\n /**\n * Initializes a new {@link FrameworkService} instance.\n *\n * @remarks\n * Sets up the main framework source map, as well as root and distribution paths.\n *\n * @since 1.0.0\n */\n\n constructor() {\n this.filePath = import.meta.filename ?? __filename;\n this.setSourceFile(this.filePath);\n this.frameworkSourceMap = this.getSourceMap(this.filePath)!;\n\n this.rootPath = this.getRootDir();\n this.distPath = this.getDistDir();\n }\n\n /**\n * Determines whether a given {@link PositionInterface} refers to a framework file.\n *\n * @param position - The position information to check\n * @returns `true` if the position is from the framework (contains \"xJet\"), otherwise `false`\n *\n * @see PositionInterface\n * @since 1.0.0\n */\n\n isFrameworkFile(position: PositionInterface): boolean {\n const { source, sourceRoot } = position;\n const lowerCaseSource = source?.toLowerCase();\n\n return Boolean(\n (source && lowerCaseSource.includes('xjet') && !lowerCaseSource.includes('xjet.config')) ||\n (sourceRoot && sourceRoot.includes('xJet'))\n );\n }\n\n /**\n * Retrieves a cached {@link SourceService} for a given file path.\n *\n * @param path - Absolute path to the file\n * @returns A {@link SourceService} instance if found, otherwise `undefined`\n *\n * @remarks\n * Paths are normalized before lookup. Only previously initialized source maps\n * (via {@link setSource} or {@link setSourceFile}) are available in the cache.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n getSourceMap(path: string): SourceService | undefined {\n path = normalize(path);\n if (this.sourceMaps.has(path))\n return this.sourceMaps.get(path)!;\n\n return undefined;\n }\n\n /**\n * Registers and initializes a new {@link SourceService} for a provided source map string.\n *\n * @param source - The raw source map content\n * @param path - Absolute file path associated with the source map\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if initialization fails\n *\n * @remarks\n * If a source map for the given path is already cached, the cached instance is returned.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n setSource(source: string, path: string): void {\n const key = normalize(path);\n\n try {\n return this.initializeSourceMap(source, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Loads and initializes a {@link SourceService} for a file and its `.map` companion.\n *\n * @param path - Absolute path to the file\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if the `.map` file cannot be read or parsed\n *\n * @remarks\n * This method attempts to read the `.map` file located next to the provided file.\n * If already cached, returns the existing {@link SourceService}.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n setSourceFile(path: string): void {\n const key = normalize(path);\n const map = `${ path }.map`;\n\n if (this.sourceMaps.has(key))\n return;\n\n try {\n const sourceMapData = readFileSync(map, 'utf-8');\n\n return this.initializeSourceMap(sourceMapData, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Retrieves the project root directory.\n * @returns Absolute path to the project root\n *\n * @since 1.0.0\n */\n\n private getRootDir(): string {\n return process.cwd();\n }\n\n /**\n * Retrieves the distribution directory.\n * @returns Absolute path to the distribution folder\n *\n * @since 1.0.0\n */\n\n private getDistDir(): string {\n return dirname(this.filePath);\n }\n\n /**\n * Creates and caches a new {@link SourceService} instance for a given source map.\n *\n * @param source - Raw source map content\n * @param key - Normalized file path used as the cache key\n * @returns The newly created {@link SourceService} instance\n *\n * @remarks\n * This method is only used internally by {@link setSource} and {@link setSourceFile}.\n * The instance is cached in {@link sourceMaps} for reuse.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n private initializeSourceMap(source: string, key: string): void {\n if(source?.includes('\"mappings\": \"\"'))\n return;\n\n const sourceMap = new SourceService(source, this.filePath);\n this.sourceMaps.set(key, sourceMap);\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { formatStack } from '@providers/stack.provider';\n\n/**\n * Base an abstract error class for all xJet-specific errors.\n *\n * Extends the native `Error` class with improved stack trace handling,\n * optional formatted stack traces, and serialization capabilities.\n *\n * @remarks\n * This class is the foundation for all custom xJet error types.\n * It ensures consistent behavior, proper prototype chain setup, and\n * provides methods for serializing the error and accessing a formatted stack trace.\n *\n * @example\n * ```ts\n * // Extending the base error class\n * export class ValidationError extends xJetBaseError {\n * constructor(message: string) {\n * super(message);\n * this.name = 'ValidationError';\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport abstract class xJetBaseError extends Error {\n /**\n * Stores a pre-formatted stack trace for the error.\n * @since 1.0.0\n */\n\n protected formattedStack: string | undefined;\n\n /**\n * Creates a new instance of the base error class.\n *\n * @param message - The error message describing the problem.\n * @param name - Optional error name; defaults to `'xJetError'`.\n *\n * @remarks\n * Properly sets up the prototype chain to ensure `instanceof` works for derived classes.\n * Captures the stack trace if supported by the runtime environment.\n *\n * @example\n * ```ts\n * class MyError extends xJetBaseError {}\n * throw new MyError('Something went wrong');\n * ```\n *\n * @since 1.0.0\n */\n\n protected constructor(message: string, name: string = 'xJetError') {\n super(message);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Gets the formatted stack trace, if available.\n *\n * @returns The formatted stack trace, or `undefined` if not set.\n *\n * @since 1.0.0\n */\n\n get formatStack(): string | undefined {\n return this.formattedStack;\n }\n\n /**\n * Serializes the error instance to a plain object for JSON conversion.\n *\n * @returns A plain object containing all enumerable properties of the error,\n * including `name`, `message`, and `stack`.\n *\n * @remarks\n * Useful for logging, error reporting, or transmitting error details across processes.\n *\n * @example\n * ```ts\n * const error = new xJetError('Validation failed');\n * const json = JSON.stringify(error.toJSON());\n * ```\n *\n * @since 1.0.0\n */\n\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {};\n\n // Copy all own (non-inherited) enumerable properties\n for (const key of Object.keys(this)) {\n const value = this[key as keyof this];\n if(value) json[key] = value;\n }\n\n // Ensure `name`, `message`, and `stack` are included\n json.name = this.name;\n json.stack = this.stack;\n json.message = this.message;\n\n return json;\n }\n\n /**\n * Custom inspect behavior for Node.js console output.\n *\n * @returns The formatted stack trace if available, otherwise the raw stack trace.\n *\n * @since 1.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n return this.formattedStack ?? this.stack;\n }\n\n /**\n * Generates a formatted stack trace using provided options and stores it in `formattedStack`.\n *\n * @param error - The error object to format.\n * @param options - Options controlling stack trace formatting.\n *\n * @remarks\n * This method is intended to be called by derived classes or internal code\n * to prepare a styled or enhanced stack trace for logging or display.\n *\n * @example\n * ```ts\n * class ValidationError extends xJetBaseError {\n * constructor(message: string) {\n * super(message);\n * this.reformatStack(this, { withFrameworkFrames: true });\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n protected reformatStack(error: Error, options?: StackTraceInterface): void {\n this.formattedStack = formatStack(error, options);\n }\n}\n", "/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\nimport { formatStack } from '@providers/stack.provider';\n\n/**\n * Formats and logs error output in a standardized way.\n *\n * @remarks\n * This utility is designed for use in global error handlers such as\n * `uncaughtException` and `unhandledRejection`.\n * - If the error is an {@link AggregateError}, all individual errors are iterated and logged.\n * - Errors extending {@link xJetBaseError} are logged directly without stack formatting.\n * - Standard {@link Error} instances are logged using {@link formatStack}, with both\n * framework and native frames included.\n * - Non-error values are logged as-is.\n *\n * @param reason - The error, aggregate error, or arbitrary value to log.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (err) {\n * formatErrors(err);\n * }\n * ```\n *\n * @see formatStack\n * @see xJetBaseError\n * @see AggregateError\n *\n * @since 1.0.0\n */\n\nexport function formatErrors(reason: unknown): void {\n if (reason instanceof AggregateError) {\n console.error('AggregateError:', reason.message);\n for (const err of reason.errors) {\n if (err instanceof Error && !(err instanceof xJetBaseError)) {\n console.error(formatStack(err, { withFrameworkFrames: true, withNativeFrames: true }));\n } else {\n console.error(err);\n }\n }\n\n return;\n }\n\n if (reason instanceof Error && !(reason instanceof xJetBaseError)) {\n console.error(formatStack(reason, { withFrameworkFrames: true, withNativeFrames: true }));\n } else {\n console.error(reason);\n }\n}\n\n/**\n * Global handler for uncaught exceptions in Node.js.\n *\n * @param reason - The value or error object representing the uncaught exception\n *\n * @throws This handler does not throw, but catches uncaught exceptions\n *\n * @remarks\n * When an uncaught exception occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`, signaling failure.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded,\n * throw new Error('This error will be logged and exit the process');\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#event-uncaughtexception | Node.js documentation on 'uncaughtException'}\n *\n * @since 1.0.0\n */\n\nprocess.on('uncaughtException', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n/**\n * Global handler for unhandled promise rejections in Node.js.\n *\n * @param reason - The value or error object representing the reason for the unhandled promise rejection\n *\n * @throws This handler does not throw, but catches unhandled promise rejections\n *\n * @remarks\n * When an unhandled promise rejection occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`. Using a distinct exit code allows differentiating between uncaught exceptions\n * and unhandled promise rejections.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded\n * Promise.reject(new Error('This rejection will be logged and exit the process'));\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#process_event_unhandledrejection | Node.js documentation on 'unhandledRejection'}\n *\n * @since 1.0.0\n */\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Argv, Options } from 'yargs';\nimport type { CliOptionsInterface } from '@providers/interfaces/cli-provider.interface';\n\n/**\n * Imports\n */\n\nimport yargs from 'yargs';\nimport { resolve } from 'path';\nimport { hideBin } from 'yargs/helpers';\nimport { bannerComponent } from '@components/banner.component';\nimport { configuration } from '@providers/configuration.provider';\n\n/**\n * Default path to the xJet configuration file.\n *\n * @remarks\n * - Used as the fallback configuration file if the user does not specify `--config`.\n * - Can be overridden by CLI argument `--config` or `-c`.\n *\n * @example\n * ```ts\n * import { DEFAULT_CONFIG_PATH } from '@cli/parse-arguments';\n * console.log(DEFAULT_CONFIG_PATH); // 'xJet/xjet.config.ts'\n * ```\n *\n * @since 1.0.0\n */\n\nconst DEFAULT_CONFIG_PATH = 'xJet/config.xjet.ts';\n\n/**\n * Default command-line options for the xJet test runner.\n *\n * @remarks\n * Provides the baseline configuration for parsing CLI arguments using `yargs`.\n * Each property maps to a CLI flag, with type, aliases, and description.\n *\n * @since 1.0.0\n */\n\nconst DEFAULT_CLI_OPTIONS = {\n files: {\n describe: 'Glob patterns or file paths used to discover test files',\n type: 'string',\n array: true\n },\n suites: {\n alias: 's',\n describe: 'Filter pattern for test suite files. Only matching files from `files` will run.',\n type: 'string',\n array: true\n },\n filter: {\n alias: 'f',\n describe: 'Run only tests or suites matching these names',\n type: 'string',\n array: true\n },\n config: {\n alias: 'c',\n describe: 'Path to xJet configuration file (.ts or .js)',\n type: 'string',\n default: DEFAULT_CONFIG_PATH,\n normalize: true,\n coerce: (value: string) => resolve(value)\n },\n reporter: {\n alias: 'r',\n describe: 'Reporter for test results. Built-in: \"spec\", \"json\", \"junit\". Can also be a custom module path.',\n type: 'string'\n },\n outputFile: {\n describe: 'Optional file path to write reporter output (e.g., \"reports/junit.xml\")',\n type: 'string'\n },\n verbose: {\n alias: 'v',\n describe: 'Include full stack traces, including internal frames',\n type: 'boolean'\n },\n logLevel: {\n alias: 'l',\n describe: 'Set the logging verbosity level (Silent, Error, Warn, Info, Debug)',\n type: 'string',\n choices: [ 'Silent', 'Error', 'Warn', 'Info', 'Debug' ]\n },\n timeout: {\n alias: 't',\n describe: 'Maximum time (ms) a single test can run before failing',\n type: 'number'\n },\n bail: {\n alias: 'b',\n describe: 'Stop running tests after the first failure',\n type: 'boolean'\n },\n watch: {\n alias: 'w',\n describe: 'Watch files for changes and re-run tests automatically',\n type: 'boolean'\n },\n randomize: {\n describe: 'Randomize the order of test execution',\n type: 'boolean'\n }\n} as const;\n\n/**\n * Predefined command usage examples for xJet CLI.\n *\n * @remarks\n * Each tuple contains:\n * - The CLI command string.\n * - A short description of what the command does.\n *\n * These examples are used to populate the help output (`--help`) of the CLI.\n *\n * @example\n * ```bash\n * xJet --config ./xjet.config.ts # Run tests with custom configuration\n * xJet --filter \"auth.*\" --verbose # Run auth-related tests with verbose logging\n * xJet --suites \"src/**\\/*.test.ts\" # Run specific test suites\n * xJet --files \"src/**\\/*.test.ts\" # Run a pattern to collect test files\n * xJet --watch --coverage # Run tests in watch mode with coverage\n * ```\n *\n * @since 1.0.0\n */\n\nconst USAGE_EXAMPLES = [\n [ 'xJet --config ./xjet.config.ts', 'Run tests with custom configuration' ],\n [ 'xJet --filter \"auth.*\" --verbose', 'Run auth-related tests with verbose logging' ],\n [ 'xJet --suites \"src/**/*.test.ts\"', 'Run specific test suites' ],\n [ 'xJet --files \"src/**/*.test.ts\"', 'Run pattern to collect test files' ],\n [ 'xJet --watch --coverage', 'Run tests in watch mode with coverage' ]\n] as const;\n\n/**\n * Reads user-defined CLI options from the xJet configuration file.\n *\n * @remarks\n * - Parses only the `--config` option to locate the user configuration file.\n * - Loads the configuration via {@link configuration} and extracts `userArgv`.\n * - Returns an empty object if no user CLI options are defined.\n *\n * @returns A promise resolving to a record of CLI options conforming to {@link Options}.\n *\n * @example\n * ```ts\n * const userOptions = await getUserArgv();\n * console.log(userOptions.files, userOptions.suites);\n * ```\n *\n * @since 1.0.0\n */\n\nexport async function getUserArgv(): Promise<Record<string, Options>> {\n const argv = yargs(process.argv).options({\n config: DEFAULT_CLI_OPTIONS.config\n }).parseSync();\n\n return (await configuration(argv.config, argv as CliOptionsInterface)).userArgv ?? {};\n}\n\n/**\n * Parses command-line arguments for the xJet test runner.\n *\n * @param argv - Array of command-line arguments (typically `process.argv`).\n * @returns A promise resolving to {@link CliOptionsInterface} with fully parsed CLI options.\n *\n * @remarks\n * - Combines default CLI options (`DEFAULT_CLI_OPTIONS`) with user-defined options from {@link getUserArgv}.\n * - Overrides `showHelp` to display the xJet banner via {@link bannerComponent}.\n * - Supports glob patterns for `files` and `suites`, test filtering via `filter`, and custom reporters (`reporter` and `outputFile`).\n * - Supports execution flags: `verbose`, `silent`, `timeout`, `bail`, `watch`, `randomize`.\n * - Evaluation order for test selection:\n * 1. `files` \u2192 collect all test files matching patterns.\n * 2. `suites` \u2192 filter files by suite patterns.\n * 3. `filter` \u2192 filter individual tests or describes by name.\n * - Automatically registers usage examples defined in {@link USAGE_EXAMPLES}.\n *\n * @example\n * ```ts\n * import { parseArguments } from '@cli/parse-arguments';\n * const options = await parseArguments(process.argv);\n * console.log(options.files, options.suites, options.filter);\n * ```\n *\n * @see {@link getUserArgv} for loading user-defined CLI options from the configuration file.\n * @see {@link CliOptionsInterface} for the shape of returned options.\n *\n * @since 1.0.0\n */\n\nexport async function parseArguments(argv: Array<string>): Promise<CliOptionsInterface> {\n const userOptions = await getUserArgv();\n\n const parser = yargs(hideBin(argv));\n const originalShowHelp = parser.showHelp;\n parser.showHelp = function (consoleFunction?: string | ((s: string) => void)): Argv<unknown> {\n console.log(bannerComponent());\n this.group(Object.keys(DEFAULT_CLI_OPTIONS), 'xJet Options:');\n this.group(Object.keys(userOptions), 'user Options:');\n\n return originalShowHelp.call(this, consoleFunction as (s: string) => void);\n };\n\n const cli = parser\n .usage('Usage: xJet [files..] [options]')\n .command('* [files..]', 'Specific test files to run (supports glob patterns)', (yargs) => {\n return yargs.positional('files', {\n describe: 'Specific test files to run (supports glob patterns)',\n type: 'string',\n array: true\n });\n })\n .options(userOptions)\n .options(DEFAULT_CLI_OPTIONS)\n .epilogue('For more information, check the documentation')\n .help()\n .alias('help', 'h')\n .strict()\n .version();\n\n USAGE_EXAMPLES.forEach(([ command, description ]) => {\n cli.example(command, description);\n });\n\n return cli.parseSync() as CliOptionsInterface;\n}\n\n", "/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * ASCII art logo for the framework.\n *\n * @remarks\n * This logo is styled using {@link xterm} color utilities when displayed\n * via the {@link bannerComponent}.\n *\n * @example\n * ```ts\n * console.log(asciiLogo);\n * ```\n *\n * @since 1.0.0\n */\n\nexport const asciiLogo = `\n ___ _\n |_ | | |\n__ __ | | ___| |_\n\\\\ \\\\/ / | |/ _ \\\\ __|\n > </\\\\__/ / __/ |_\n/_/\\\\_\\\\____/ \\\\___|\\\\__|\n`;\n\n/**\n * Creates a colored ASCII banner including the framework version.\n *\n * @remarks\n * Uses {@link xterm} to render the ASCII logo and\n * {@link xterm} to highlight the `__VERSION` string.\n *\n * @returns A formatted string suitable for console output\n *\n * @example\n * ```ts\n * console.log(bannerComponent());\n * ```\n *\n * @see asciiLogo\n * @since 1.0.0\n */\n\nexport function bannerComponent(): string {\n return `${ xterm.burntOrange(asciiLogo) }\\nVersion: ${ xterm.brightPink(__VERSION) }\\n`;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { CliOptionsInterface } from '@providers/interfaces/cli-provider.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { defaultConfiguration } from '@configuration/default.configuration';\nimport { parseConfigurationFile } from '@configuration/parse.configuration';\n\n/**\n * Loads and merges the xJet configuration.\n *\n * @param configFile - Optional path to a user configuration file (e.g., 'xjet.config.ts').\n * @param cli - Command-line options provided by the user.\n * @returns A promise that resolves to the final {@link ConfigurationInterface} object.\n *\n * @remarks\n * This function performs the following steps:\n * 1. Starts with the default configuration.\n * 2. If a configuration file is provided and exists, it is parsed using {@link parseConfigurationFile}.\n * 3. The user configuration is merged with the default configuration. The `exclude` arrays from both\n * configurations are concatenated to preserve all exclusions.\n * 4. Finally, command-line options override any existing configuration values.\n *\n * This ensures that defaults, user configuration, and CLI flags are combined consistently,\n * giving priority to CLI arguments.\n *\n * @example\n * ```ts\n * import { configuration } from '@services/configuration.service';\n *\n * const cliOptions = { watch: true, verbose: true };\n * const config = await configuration('xjet.config.ts', cliOptions);\n * console.log(config);\n * ```\n *\n * @see parseConfigurationFile\n * @see ConfigurationInterface\n *\n * @since 1.0.0\n */\n\nexport async function configuration(configFile: string = '', cli: CliOptionsInterface): Promise<ConfigurationInterface> {\n let config = { ...defaultConfiguration };\n if (configFile && existsSync(configFile)) {\n const userConfig = await parseConfigurationFile(configFile);\n if (userConfig) {\n config = {\n ...config,\n ...userConfig,\n exclude: [ ...(config.exclude ?? []), ...(userConfig.exclude ?? []) ]\n };\n }\n }\n\n return <ConfigurationInterface> { ...config, ...cli };\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { version } from 'process';\n\n/**\n * The default settings for configuring a testing execution environment.\n *\n * @remarks\n * This configuration includes parameters such as file patterns to include/exclude,\n * timeout settings, verbosity levels, and others necessary for test orchestration.\n * These values can typically be overridden by user-defined configurations.\n *\n * @example\n * ```ts\n * import { defaultConfiguration } from './config';\n *\n * // Using default configuration with overrides\n * const config = {\n * ...defaultConfiguration,\n * timeout: 10000,\n * verbose: true\n * };\n * ```\n *\n * @see ConfigurationInterface\n * @since 1.0.0\n */\n\nexport const defaultConfiguration: Partial<ConfigurationInterface> = {\n bail: false,\n files: [ '**/*.test.ts', '**/*.spec.ts' ],\n watch: false,\n suites: [],\n filter: [],\n verbose: false,\n timeout: 5000,\n parallel: 1,\n exclude: [ /node_modules/ ],\n reporter: 'default',\n randomize: false,\n build: {\n target: [ `node${ version.slice(1) }` ],\n packages: 'bundle',\n platform: 'browser',\n external: []\n }\n};\n", "/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions } from 'esbuild';\nimport type { ModuleInterface } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { createRequire } from 'module';\nimport { sandboxExecute } from '@services/vm.service';\nimport { VMRuntimeError } from '@errors/vm-runtime.error';\nimport { transpileFile } from '@services/transpiler.service';\n\n/**\n * Parses and executes a JavaScript configuration file in a secure sandbox.\n *\n * @param file - The path to the configuration file (e.g., 'xjet.config.js').\n * @returns A promise that resolves to the exported configuration object.\n *\n * @remarks\n * This function performs the following steps:\n * 1. Transpiles the provided configuration file using esbuild with Node.js\n * compatible settings and without minification.\n * 2. Executes the transpiled code in a sandboxed environment using `sandboxExecute`.\n * Only a controlled set of globals (Error, Buffer, RegExp, require, console,\n * setTimeout, setInterval, and a module object) are exposed.\n * 3. Captures any errors thrown during execution and wraps them in a {@link VMRuntimeError}.\n * 4. Returns the exported configuration object from the module. If no default export\n * is found, it returns an empty object.\n *\n * @throws VMRuntimeError - If an error occurs during sandbox execution.\n *\n * @example\n * ```ts\n * import { parseConfigurationFile } from '@services/configuration-parser';\n *\n * const config = await parseConfigurationFile('xjet.config.js');\n * console.log(config);\n * ```\n *\n * @see transpileFile\n * @see sandboxExecute\n * @see VMRuntimeError\n *\n * @since 1.0.0\n */\n\nexport async function parseConfigurationFile(file: string): Promise<ConfigurationInterface> {\n const transpileOptions: BuildOptions = {\n minify: false,\n format: 'cjs',\n outdir: dirname(file),\n platform: 'node',\n logLevel: 'silent',\n packages: 'external',\n minifySyntax: true,\n preserveSymlinks: true,\n minifyWhitespace: true,\n minifyIdentifiers: false\n };\n\n const module: ModuleInterface<ConfigurationInterface> = { exports: {} };\n const { code, path } = await transpileFile(file, transpileOptions);\n const require = createRequire(path);\n\n try {\n await sandboxExecute(code, {\n Error,\n module,\n Buffer,\n RegExp,\n require,\n console,\n setTimeout,\n setInterval\n }, { filename: path });\n } catch (error: unknown) {\n if(error instanceof Error)\n throw new VMRuntimeError(<Error> error);\n\n throw error;\n }\n\n return <ConfigurationInterface> (module.exports.default ?? {});\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Context, ScriptOptions } from 'vm';\n\n/**\n * Imports\n */\n\nimport { Script, createContext } from 'vm';\n\n/**\n * Executes arbitrary code inside a Node.js VM sandbox.\n *\n * @param code - The JavaScript source code to execute\n * @param sandbox - Optional {@link Context} object to inject into the VM environment\n * @param options - Optional {@link ScriptOptions} used when compiling the script\n *\n * @returns A promise resolving to the result of the executed code\n *\n * @throws Error - If the provided code fails to compile or runtime execution throws\n *\n * @remarks\n * This function uses Node.js's {@link Script} and {@link createContext} APIs to safely run code in\n * an isolated environment. Execution is configured with `breakOnSigint` enabled and `displayErrors` disabled.\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"2 + 2\");\n * console.log(result); // 4\n * ```\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"user.name\", { user: { name: \"Alice\" } });\n * console.log(result); // \"Alice\"\n * ```\n *\n * @see Context\n * @see ScriptOptions\n *\n * @since 1.0.0\n */\n\nexport async function sandboxExecute(code: string, sandbox: Context = {}, options: ScriptOptions = {}): Promise<unknown> {\n const script = new Script(code, options);\n const context = createContext(sandbox);\n\n return await script.runInContext(context, { breakOnSigint: true, displayErrors: false });\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\n\n/**\n * Represents an error that occurs during VM runtime execution.\n *\n * Extends {@link xJetBaseError} and adds support for wrapping native errors,\n * handling `AggregateError` instances, and preserving nested errors.\n *\n * @remarks\n * This class is designed to encapsulate runtime errors in a virtual machine context.\n * If the original error is already a `xJetBaseError`, it is returned as-is.\n * AggregateErrors are flattened into an array of `VMRuntimeError` instances.\n *\n * The formatted stack trace is automatically generated for both single and nested errors.\n *\n * @example\n * ```ts\n * try {\n * // Some VM execution code that throws\n * } catch (err) {\n * const vmError = new VMRuntimeError(err, { withFrameworkFrames: true });\n * console.error(vmError.formattedStack);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport class VMRuntimeError extends xJetBaseError {\n /**\n * If the original error is an AggregateError, contains nested VMRuntimeError instances.\n *\n * @since 1.0.0\n */\n\n errors?: Array<VMRuntimeError> = [];\n\n /**\n * Creates a new `VMRuntimeError` instance from a native or xJetBaseError.\n *\n * @param originalError - The original error object thrown during execution.\n * @param options - Optional stack trace formatting options.\n *\n * @remarks\n * - If `originalError` is already an instance of `xJetBaseError`, it is returned as-is.\n * - If `originalError` is an `AggregateError`, each nested error is converted into a `VMRuntimeError`.\n * - The message and stack of the original error are preserved.\n * - The formatted stack trace is generated via {@link xJetBaseError.reformatStack}.\n *\n * @since 1.0.0\n */\n\n constructor(private originalError: Error, options?: StackTraceInterface) {\n if (originalError instanceof xJetBaseError) {\n return <VMRuntimeError> originalError;\n }\n\n // Pass the message to the base class Error\n super(originalError.message, 'VMRuntimeError');\n\n // Handle AggregateError\n if (originalError instanceof AggregateError && Array.isArray(originalError.errors)) {\n // Process nested errors\n this.errors = originalError.errors.map(error =>\n new VMRuntimeError(error, options)\n );\n }\n\n this.stack = originalError.stack;\n this.message = originalError.message;\n this.reformatStack(originalError, options);\n }\n\n /**\n * Custom Node.js inspect method for displaying the error in the console.\n *\n * @returns A string representation of the formatted stack trace, or\n * a concatenated list of nested errors if present.\n *\n * @remarks\n * Overrides the Node.js default inspection behavior.\n * If this instance contains nested errors, they are listed with their formatted stacks.\n *\n * @since 1.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n if (this.errors && this.errors.length > 0) {\n const errorList = this.errors.map(\n (error) => `${ error.formattedStack ?? error.stack }`\n ).join('');\n\n return `VMRuntimeError Contains ${ this.errors.length } nested errors:\\n${ errorList }\\n`;\n }\n\n return this.formattedStack ?? this.stack;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions, BuildResult, Metafile } from 'esbuild';\nimport type { ESBuildErrorInterface } from '@errors/interfaces/esbuild-error.interface';\nimport type { TranspileFileInterface, TranspileFileType } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { build } from 'esbuild';\nimport { xJetError } from '@errors/xjet.error';\nimport { esBuildError } from '@errors/esbuild.error';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Default ESBuild options used when building or transpiling files.\n *\n * @remarks\n * These defaults bundle, minify, preserve symlinks, and generate external sourcemaps\n * targeting modern browser environments.\n *\n * see BuildOptions\n * @since 1.0.0\n */\n\nexport const defaultBuildOptions: BuildOptions = {\n write: false,\n bundle: true,\n minify: true,\n outdir: `${ cwd() }`,\n format: 'esm',\n target: 'esnext',\n platform: 'browser',\n sourcemap: 'external',\n mangleQuoted: true,\n sourcesContent: true,\n preserveSymlinks: true\n};\n\n/**\n * Builds multiple files using ESBuild with specified options.\n *\n * @param filePaths - Array of entry points to build\n * @param buildOptions - Optional override build options\n *\n * @returns A promise resolving to an ESBuild BuildResult including metafile information\n *\n * @throws esBuildError - Thrown if ESBuild encounters errors during build\n *\n * @remarks\n * This function merges user-provided options with default options and ensures\n * that a metafile is generated. If any errors occur during the build, they are\n * wrapped in a {@link esBuildError} for consistent error reporting.\n *\n * @example\n * ```ts\n * const result = await buildFiles(['src/index.ts'], { minify: false });\n * console.log(result.outputFiles);\n * ```\n *\n * @see esBuildError\n * @since 1.0.0\n */\n\nexport async function buildFiles(filePaths: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<BuildResult<BuildOptions & Metafile>> {\n try {\n return await build({\n absWorkingDir: cwd(),\n ...defaultBuildOptions,\n ...buildOptions,\n metafile: true,\n entryPoints: filePaths\n }) as BuildResult<BuildOptions & Metafile>;\n } catch (esbuildErrors) {\n throw new esBuildError(<ESBuildErrorInterface> esbuildErrors);\n }\n}\n\n/**\n * Transpiles multiple files and returns their output code and paths.\n *\n * @param filePaths - Array of files to transpile\n * @param buildOptions - Optional override ESBuild options\n *\n * @returns A promise resolving to an array of transpiled files with paths and code\n *\n * @remarks\n * Output files ending with `.js.map` are registered with the {@link FrameworkService}.\n * Only `.js` files are returned in the result array for further processing.\n *\n * @example\n * ```ts\n * const transpiled = await transpileFiles(['src/index.ts']);\n * console.log(transpiled[0].path, transpiled[0].code);\n * ```\n *\n * @see buildFiles\n * @see FrameworkService\n *\n * @since 1.0.0\n */\n\nexport async function transpileFiles(filePaths: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<TranspileFileType> {\n const result = await buildFiles(filePaths, buildOptions);\n\n const transpiled: TranspileFileType = [];\n const outputFiles = result.outputFiles ?? [];\n const framework = inject(FrameworkService);\n\n for (const file of outputFiles) {\n const basePath = file.path.replace(/\\.(map)$/, '');\n const isSourceMap = file.path.endsWith('.js.map');\n const isJsFile = file.path.endsWith('.js');\n\n if (isSourceMap) {\n framework.setSource(file.text, basePath);\n } else if (isJsFile) {\n transpiled.push({\n path: basePath,\n code: file.text + `//# sourceURL=${ basePath }`\n });\n }\n }\n\n return transpiled;\n}\n\n/**\n * Transpiles a single file and returns its output code and path.\n *\n * @param filePath - The path of the file to transpile\n * @param buildOptions - Optional override ESBuild options\n *\n * @returns A promise resolving to a single transpiled file object\n *\n * @throws xJetError - Thrown if no output is generated for the file\n *\n * @remarks\n * Internally calls {@link transpileFiles} with a single-element array and returns\n * the first result. Ensures consistent error reporting if the transpilation fails.\n *\n * @example\n * ```ts\n * const file = await transpileFile('src/index.ts');\n * console.log(file.path, file.code);\n * ```\n *\n * @see xJetError\n * @see transpileFiles\n *\n * @since 1.0.0\n */\n\nexport async function transpileFile(filePath: string, buildOptions: BuildOptions = {}): Promise<TranspileFileInterface> {\n const files = await transpileFiles([ filePath ], buildOptions);\n const result = files.shift();\n if (!result) {\n throw new xJetError('Failed to transpile file: No output generated');\n }\n\n return result;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\n\n/**\n * Represents a generic xJet framework error.\n *\n * Extends {@link xJetBaseError} and automatically formats the stack trace\n * according to the provided options.\n *\n * @remarks\n * This class is intended for general-purpose errors within the xJet framework.\n * The stack trace is formatted automatically during construction, with\n * framework-specific frames included by default.\n *\n * @example\n * ```ts\n * throw new xJetError('An unexpected error occurred');\n * ```\n *\n * @since 1.0.0\n */\n\nexport class xJetError extends xJetBaseError {\n\n /**\n * Creates a new instance of `xJetError`.\n *\n * @param message - The error message to display\n * @param options - Optional stack trace formatting options (default includes framework frames)\n *\n * @remarks\n * The constructor passes the message to the base `xJetBaseError` class,\n * then reformats the stack trace using {@link xJetBaseError.reformatStack}.\n *\n * @since 1.0.0\n */\n\n constructor(message: string, options: StackTraceInterface = { withFrameworkFrames: true }) {\n // Pass the message to the base class Error\n super(message);\n this.reformatStack(this, options);\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ESBuildErrorInterface, ESBuildAggregateErrorInterface } from '@errors/interfaces/esbuild-error.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { formatCode } from '@remotex-labs/xmap/formatter.component';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\n\n/**\n * Represents an error produced by ESBuild during the build process.\n *\n * Extends {@link xJetBaseError} and provides formatted output for\n * individual or aggregated ESBuild errors.\n *\n * @remarks\n * If the error contains aggregate errors (`aggregateErrors`), each error\n * is formatted with colorized output, code highlighting, and positional\n * information. Otherwise, a standard stack trace is generated.\n *\n * @example\n * ```ts\n * import { esBuildError } from '@errors/esbuild.error';\n *\n * try {\n * // some ESBuild operation\n * } catch (error) {\n * throw new esBuildError(error as ESBuildErrorInterface);\n * }\n * ```\n *\n * @see xJetBaseError\n * @see ESBuildErrorInterface\n * @see ESBuildAggregateErrorInterface\n *\n * @since 1.0.0\n */\n\nexport class esBuildError extends xJetBaseError {\n /**\n * Creates a new `esBuildError` instance.\n *\n * @param error - The ESBuild error object to wrap\n *\n * @remarks\n * The constructor checks if the error contains `aggregateErrors` and\n * formats each entry with syntax highlighting and positional information.\n * If not, the error is reformatted using the base error's stack formatting.\n *\n * @since 1.0.0\n */\n\n constructor(error: ESBuildErrorInterface) {\n super('esBuildError build failed', 'esBuildError');\n\n if (error.aggregateErrors) this.formatAggregateErrors(error.aggregateErrors);\n else this.reformatStack(error, { withFrameworkFrames: true });\n }\n\n /**\n * Formats a list of ESBuild aggregate errors into a single, colorized stack string.\n *\n * @param errors - Array of ESBuild aggregate errors\n *\n * @remarks\n * Each error is highlighted using {@link highlightCode} and {@link formatCode},\n * and includes file location, line, and column for easier debugging.\n *\n * @since 1.0.0\n */\n\n private formatAggregateErrors(errors: Array<ESBuildAggregateErrorInterface>): void {\n this.formattedStack = '';\n\n for (const error of errors) {\n this.formattedStack += `\\n${ this.name }: \\n${ xterm.lightCoral(`${ error.text }: ${ error.notes.pop()?.text }`) }\\n\\n`;\n this.formattedStack += formatCode(highlightCode(error.location.lineText.trim()), {\n startLine: error.location.line\n });\n\n this.formattedStack += '\\n\\n';\n this.formattedStack += `at ${ xterm.dim(error.location.file) } ${\n xterm.gray(`[${ error.location.line }:${ error.location.column }]`)\n }\\n\\n`;\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractTarget } from '@targets/abstract/target.abstract';\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { join } from 'path';\nimport { exit } from 'process';\nimport { WatchService } from '@services/watch.service';\nimport { getSpecFiles } from '@providers/specs.provider';\nimport { inject } from '@symlinks/services/inject.service';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { transpileFiles } from '@services/transpiler.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { getReporter } from '@messages/services/reports.service';\nimport { MessageService } from '@messages/services/message.service';\nimport { ExternalService, LocalService } from '@targets/target.module';\n\n/**\n * Code banner injected at the top of transpiled JavaScript files.\n *\n * @remarks\n * This is passed to the transpiler (esbuild) to ensure a clean newline\n * at the start of each bundled file. It can also be extended later to\n * include configuration headers, metadata, or runtime bootstrap code.\n *\n * @since 1.0.0\n */\n\nconst banner = {\n js: '\\n'\n};\n\n/**\n * Code footer injected at the bottom of transpiled JavaScript files.\n *\n * @remarks\n * Ensures that once the suite code is fully bundled and loaded,\n * the `state.run({})` function is invoked to start the test execution lifecycle.\n *\n * @since 1.0.0\n */\n\nconst footer = {\n js: 'state.run({})'\n};\n\n/**\n * Service responsible for executing, transpiling, and managing test suites.\n *\n * @remarks\n * The `SuitesService` class handles the lifecycle of test execution:\n * - Locating and transpiling spec files.\n * - Initializing the target environment (local or external).\n * - Managing reporters and error states.\n * - Optionally watching for changes and re-running tests.\n *\n * It uses injected services like {@link FrameworkService}, {@link MessageService},\n * and target services ({@link LocalService} / {@link ExternalService}) to orchestrate the process.\n *\n * @example\n * ```ts\n * const service = new SuitesService(config);\n * await service.executeSuites();\n * ```\n *\n * @since 1.0.0\n */\n\nexport class SuitesService {\n /**\n * Reference to the currently active test target.\n *\n * @remarks\n * This property is initialized once during construction\n * and cannot be reassigned afterward due to the `readonly` modifier.\n * It resolves to either a `LocalService` or `ExternalService`,\n * both of which extend the abstract target contract (`AbstractTarget`).\n *\n * @since 1.0.0\n */\n\n private readonly target: AbstractTarget;\n\n /**\n * Instance of the {@link FrameworkService} injected via the DI container.\n *\n * @remarks\n * This property is resolved once during class instantiation and cannot\n * be reassigned due to the `readonly` modifier. It provides access to\n * framework-level paths, configuration, and shared utilities.\n *\n * @since 1.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Creates an instance of {@link SuitesService}.\n *\n * @param config - The runtime configuration object that defines\n * suite files, build options, runners, and other\n * execution parameters.\n *\n * @remarks\n * The constructor initializes the {@link target} by invoking\n * {@link SuitesService.createTarget | createTarget}, ensuring the\n * appropriate execution environment (local or external) is selected\n * based on the provided configuration.\n *\n * @since 1.0.0\n */\n\n constructor(private config: ConfigurationInterface) {\n this.target = this.createTarget();\n }\n\n /**\n * Executes all discovered test suites based on the current configuration.\n *\n * @remarks\n * This method orchestrates the end-to-end lifecycle of test execution:\n *\n * - Discovers suite files using {@link getSpecFiles}.\n * - Validates that test files are available, throwing an error if none are found.\n * - Initializes the configured {@link AbstractTarget}, such as a local or external runner.\n * - Creates a {@link MessageService} with the selected reporter to handle\n * event reporting and error tracking.\n * - Transpiles and executes suites via {@link SuitesService.exec}.\n * - Optionally watches for file changes when `watch` mode is enabled.\n * - Frees target resources after execution completes.\n * - Terminates the process with exit codes depending on test outcomes:\n * - `0` if all suites passed.\n * - `1` if any test error occurred.\n * - `2` if any suite-level error occurred.\n *\n * @throws Error If no test files matching the configuration are found.\n *\n * @example\n * ```ts\n * const service = new SuitesService(config);\n * await service.executeSuites();\n * ```\n *\n * @since 1.0.0\n */\n\n async executeSuites(): Promise<void> {\n const specsFiles = getSpecFiles(this.framework.rootPath, this.config);\n if (Object.keys(specsFiles).length === 0) {\n if(this.config.suites.length > 0)\n throw xterm.redBright('No test files found for ') + xterm.greenBright(this.config.suites.join(', '));\n\n throw xterm.redBright('No test files found for ') + xterm.greenBright(this.config.files.join(', '));\n }\n\n await this.target.initTarget?.();\n const message = new MessageService(this.target, await getReporter(this.config));\n await this.exec(message, specsFiles);\n\n if (this.config.watch) {\n await this.watchForChanges(message, specsFiles);\n }\n\n await this.target.freeTarget?.();\n\n if (message.hasError) exit(1);\n if (message.hasSuiteError) exit(2);\n exit(0);\n }\n\n /**\n * Executes a single run of the provided test suites.\n *\n * @remarks\n * This method performs the following tasks in sequence:\n * - Initializes the reporter with discovered suite file paths and available runners.\n * - Transpiles the test suite files into executable format.\n * - Delegates execution to the configured {@link AbstractTarget}.\n * - Finalizes reporting by calling the reporter\u2019s `finish` method.\n *\n * @param message - The {@link MessageService} instance responsible for reporting\n * events and aggregating errors during execution.\n * @param specsFiles - A record mapping suite identifiers to their file system paths.\n *\n * @example\n * ```ts\n * const message = new MessageService(target, reporter);\n * await this.exec(message, { 'suite1': '/path/to/suite1.spec.ts' });\n * ```\n *\n * @since 1.0.0\n */\n\n private async exec(message: MessageService, specsFiles: Record<string, string>): Promise<void> {\n message.reporter.init?.(Object.values(specsFiles), message.target.getRunners());\n const transpiled = await this.transpileSuites(specsFiles);\n await this.target.executeSuites(transpiled, specsFiles);\n message.reporter.finish?.();\n }\n\n /**\n * Creates and returns the appropriate test execution target.\n *\n * @remarks\n * This method determines whether to use an {@link ExternalService}\n * or {@link LocalService} as the execution target based on the presence\n * of configured test runners in {@link ConfigurationInterface.testRunners}.\n *\n * - If one or more `testRunners` are specified, an {@link ExternalService} is injected.\n * - Otherwise, a {@link LocalService} is injected.\n *\n * @returns An {@link AbstractTarget} instance configured according to the current setup.\n *\n * @example\n * ```ts\n * const target = this.createTarget();\n * await target.initTarget?.();\n * ```\n *\n * @see AbstractTarget\n * @see ExternalService\n * @see LocalService\n *\n * @since 1.0.0\n */\n\n private createTarget(): AbstractTarget {\n return (this.config.testRunners && this.config.testRunners.length > 0)\n ? inject(ExternalService, this.config)\n : inject(LocalService, this.config);\n }\n\n /**\n * Initializes a watch mode to monitor test files for changes.\n *\n * @remarks\n * This method sets up a {@link WatchService} that observes the provided\n * test specification files (`specsFiles`).\n * When a change is detected, the suite execution is re-triggered\n * using the {@link SuitesService.exec | exec} method bound to the given {@link MessageService}.\n *\n * This enables continuous testing in development environments when\n * the `watch` option is enabled in {@link ConfigurationInterface}.\n *\n * @param message - The active {@link MessageService} used for reporting\n * and coordinating suite execution.\n * @param specsFiles - A record of spec file identifiers mapped to their file paths.\n *\n * @returns A `Promise` that resolves when the {@link WatchService} is fully initialized.\n *\n * @example\n * ```ts\n * if (this.config.watch) {\n * await this.watchForChanges(message, specsFiles);\n * }\n * ```\n *\n * @see WatchService\n * @see SuitesService.exec\n *\n * @since 1.0.0\n */\n\n private async watchForChanges(message: MessageService, specsFiles: Record<string, string>): Promise<void> {\n const watcher = new WatchService(this.config, specsFiles, this.exec.bind(this, message));\n await watcher.init();\n }\n\n /**\n * Transpiles the given test specification files according to the configured build options.\n *\n * @remarks\n * This method uses {@link transpileFiles} to process the test files, applying\n * the build configuration from {@link ConfigurationInterface.build}.\n * It automatically injects shared dependencies, applies a banner and footer, and\n * enforces the CommonJS module format (`cjs`).\n * Minification is disabled, but syntax and whitespace optimizations are applied.\n *\n * @param filePaths - A record mapping identifiers to the absolute paths of the test files\n * that need to be transpiled.\n *\n * @returns A `Promise` resolving to a {@link TranspileFileType} object containing\n * the transpiled outputs.\n *\n * @example\n * ```ts\n * const transpiled = await this.transpileSuites({\n * 'example.test.ts': '/path/to/example.test.ts'\n * });\n * ```\n *\n * @see transpileFiles\n * @see ConfigurationInterface.build\n *\n * @since 1.0.0\n */\n\n private async transpileSuites(filePaths: Record<string, string>): Promise<TranspileFileType> {\n return await transpileFiles(filePaths, {\n ...this.config.build,\n banner,\n footer,\n format: 'cjs',\n minify: false,\n inject: [ join(this.framework.distPath, 'shared.js') ],\n logLevel: 'silent',\n sourcemap: true,\n minifySyntax: true,\n preserveSymlinks: true,\n minifyWhitespace: true,\n minifyIdentifiers: false,\n define: {\n 'import.meta': 'import_meta'\n }\n });\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TestExecutionType } from '@services/interfaces/watch-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { accessSync } from 'fs';\nimport { readFile, watch } from 'fs/promises';\nimport { dirname, join, normalize } from 'path';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { compilePatterns, matchesAny } from '@components/glob.component';\nimport { resolveImport, updateAliases } from '@providers/import-resolver.provider';\n\n/**\n * Service for watching the project filesystem and re-running only the tests\n * affected by file changes.\n *\n * @remarks\n * The service maintains a dependency graph that maps source files to test files.\n * When a file changes:\n * - If it's a test file, that file is re-executed.\n * - If it's a dependency of one or more test files, all dependent test files are re-executed.\n * - Deleted files are removed from the graph automatically.\n *\n * The watcher uses a debounced handler (default 400 ms) to batch multiple\n * filesystem changes before re-running tests.\n *\n * @example\n * ```ts\n * const service = new WatchService(config, specFiles, async (suites) => {\n * console.log('Re-running tests:', suites);\n * });\n * await service.init();\n * ```\n *\n * @see compilePatterns\n * @see matchesAny\n * @since 1.0.0\n */\n\nexport class WatchService {\n /**\n * Regular expression for matching ESM-style import paths.\n *\n * @remarks\n * Captures module specifiers from statements such as\n * - `import x from 'module'`\n * - `import { y } from \"module\"`\n *\n * The named capture group `path` contains the module specifier string.\n *\n * @example\n * ```ts\n * const code = \"import { readFile } from 'fs';\";\n * const match = WatchService.IMPORT_REGEX.exec(code);\n * console.log(match?.groups?.path); // \"fs\"\n * ```\n *\n * @since 1.0.0\n */\n\n private static readonly IMPORT_REGEX = /(?:from|import)\\s+['\"](?<path>[^'\"]+)['\"]/g;\n\n /**\n * Regular expression for matching a file extension.\n *\n * @remarks\n * Matches the last dot (`.`) in a file name and all following characters,\n * excluding additional dots or path separators.\n * Effectively isolates the extension from a file path.\n *\n * @example\n * ```ts\n * const file = \"example.test.ts\";\n * const match = WatchService.FILE_EXTENSION_REGEX.exec(file);\n * console.log(match?.[0]); // \".ts\"\n * ```\n *\n * Useful for stripping extensions when normalizing or mapping test files.\n *\n * @since 1.0.0\n */\n\n private static readonly FILE_EXTENSION_REGEX = /\\.[^/.]+$/;\n\n /**\n * Reference to the core {@link FrameworkService}.\n *\n * @remarks\n * Injected via the {@link inject} helper, this service provides access to\n * framework-level configuration such as the project root path, runtime\n * environment, and shared utilities.\n * It is used here for resolving relative paths and coordinating with the\n * broader testing infrastructure.\n *\n * @see inject\n * @see FrameworkService\n *\n * @since 1.0.0\n */\n\n private readonly framework: FrameworkService = inject(FrameworkService);\n\n /**\n * Tracks the dependency relationships between source files and test files.\n *\n * @remarks\n * Each key is a file path (either a source or test file), and its value is a set of\n * test files that depend on it. This graph is used to determine which tests\n * need to be re-executed when a file changes.\n *\n * @example\n * ```ts\n * // If \"utils.ts\" changes, all dependent tests are retrieved:\n * const affectedTests = dependencyGraph.get('src/utils.ts');\n * ```\n *\n * @since 1.0.0\n */\n\n private readonly dependencyGraph: Map<string, Set<string>> = new Map();\n\n /**\n * Caches the list of direct dependencies for each file.\n *\n * @remarks\n * Each key is a file path, and the corresponding value is an array of file paths\n * that the key file directly imports. This cache avoids repeated parsing of\n * files when tracking changes in the dependency graph.\n *\n * @example\n * ```ts\n * const deps = dependenciesCache.get('src/test/example.spec.ts');\n * // deps might be ['src/utils.ts', 'src/helpers.ts']\n * ```\n *\n * @since 1.0.0\n */\n\n private readonly dependenciesCache: Map<string, Array<string>> = new Map();\n\n /**\n * Timer used for debouncing file change events.\n *\n * @remarks\n * When multiple file changes occur in quick succession, this timer ensures that\n * the `handleChangedFiles` method is called only once after a short delay,\n * preventing redundant executions and improving performance.\n *\n * @since 1.0.0\n */\n\n private debounceTimer: NodeJS.Timeout | null = null;\n\n /**\n * Compiled regular expressions for test file inclusion.\n *\n * @remarks\n * These patterns are derived from the user's configuration (`config.files`) and\n * are used to determine which files should be treated as test/spec files during\n * watch or execution.\n *\n * @since 1.0.0\n */\n\n private readonly patterns: Array<RegExp>;\n\n /**\n * Compiled regular expressions for file exclusion.\n *\n * @remarks\n * These patterns are derived from the user's configuration (`config.exclude`) and\n * are used to ignore files or directories when scanning for test files or\n * tracking dependencies.\n *\n * @since 1.0.0\n */\n\n private readonly excludes: Array<RegExp>;\n\n /**\n * Initializes the WatchService for monitoring test files and their dependencies.\n *\n * @param config - Configuration object containing `files` and `exclude` patterns.\n * @param testsFile - Map of test file relative paths to absolute paths.\n * @param exec - Callback invoked with the changed suites when a relevant file changes.\n *\n * @remarks\n * The constructor compiles the provided file inclusion and exclusion patterns\n * and prepares internal caches for dependency tracking. This sets up the service\n * for watching test files and their imported dependencies for changes.\n *\n * @since 1.0.0\n */\n\n constructor(config: ConfigurationInterface, private testsFile: Record<string, string>, private exec: TestExecutionType) {\n updateAliases();\n this.patterns = compilePatterns(config?.files ?? []);\n this.excludes = compilePatterns(config?.exclude ?? []);\n }\n\n /**\n * Initializes the file watcher and builds the initial dependency graph.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Updates the dependency graph for all known test files.\n * 2. Sets up a recursive file system watcher on the framework's root directory.\n * 3. On file changes, normalizes paths, filters excluded files, and schedules\n * handling of changed files with a debouncing to avoid excessive executions.\n *\n * @returns A promise that resolves when the watcher is ready.\n *\n * @since 1.0.0\n */\n\n async init(): Promise<void> {\n await Promise.all(Object.values(this.testsFile).map(\n (testFile) => this.updateGraph(testFile))\n );\n\n const changedFilesSet = new Set<string>();\n const watcher = watch(this.framework.rootPath, { recursive: true });\n for await (const { filename } of watcher) {\n if (!filename) continue;\n\n const fullPath = normalize(filename);\n if (matchesAny(fullPath, this.excludes)) continue;\n\n changedFilesSet.add(fullPath);\n this.debounce(() => this.handleChangedFiles([ ...changedFilesSet ], changedFilesSet));\n }\n }\n\n /**\n * Debounce the execution of a function to limit how frequently it runs.\n *\n * @param fn - The function to execute after the debounce delay.\n * @param delay - Optional debounce delay in milliseconds (default is 400 ms).\n *\n * @remarks\n * If multiple calls are made within the delay period, only the last one will execute.\n * This is used in the file watcher to prevent excessive calls to handle file changes\n * when multiple filesystem events occur in quick succession.\n *\n * @since 1.0.0\n */\n\n private debounce(fn: () => void, delay = 400): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(fn, delay);\n }\n\n /**\n * Checks whether a file exists on the filesystem.\n *\n * @param file - Absolute or relative path to the file.\n * @returns `true` if the file exists and is accessible, otherwise `false`.\n *\n * @remarks\n * This method uses synchronous filesystem access to determine the file's existence.\n * It is primarily used by the watcher to verify that a changed file still exists\n * before processing it.\n *\n * @since 1.0.0\n */\n\n private fileExists(file: string): boolean {\n try {\n accessSync(file);\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Removes a file and all its associations from the dependency graph.\n *\n * @param file - The absolute path of the file to remove.\n *\n * @remarks\n * This method removes the file from both the main `dependencyGraph` and the\n * `dependenciesCache`. It also ensures that any other files that depend on this\n * file no longer reference it as a dependency. This is useful when a file is\n * deleted or no longer relevant to the test execution.\n *\n * @since 1.0.0\n */\n\n private removeFileFromGraph(file: string): void {\n this.dependencyGraph.delete(file);\n this.dependenciesCache.delete(file);\n\n for (const dependents of this.dependencyGraph.values()) {\n dependents.delete(file);\n }\n }\n\n /**\n * Processes a batch of changed files, updates the dependency graph, and triggers test execution.\n *\n * @param changedFiles - Array of absolute paths for files that have changed.\n * @param changedFilesSet - Set used for debouncing and tracking currently changed files.\n *\n * @remarks\n * For each file in `changedFiles`:\n * 1. If the file no longer exists, it is removed from the dependency graph.\n * 2. If the file matches test patterns, the dependency graph is updated and the file is queued for execution.\n * 3. If the file is a dependency of any test files, those dependent test files are also updated and queued.\n *\n * Once all relevant test files are collected, the `exec` function is called with a map of suite IDs to their absolute file paths.\n *\n * @since 1.0.0\n */\n\n private async handleChangedFiles(changedFiles: string[], changedFilesSet: Set<string>): Promise<void> {\n changedFilesSet.clear();\n const suites: Record<string, string> = {};\n\n for (const file of changedFiles) {\n if (!this.fileExists(file)) {\n this.removeFileFromGraph(file);\n continue;\n }\n\n if (matchesAny(file, this.patterns)) {\n await this.updateGraph(file);\n const key = file.replace(WatchService.FILE_EXTENSION_REGEX, '');\n suites[key] = file;\n }\n\n if (this.dependencyGraph.has(file)) {\n await this.updateGraph(file);\n this.dependencyGraph.get(file)?.forEach(suite => {\n const key = suite.replace(WatchService.FILE_EXTENSION_REGEX, '');\n suites[key] = suite;\n });\n }\n }\n\n if (Object.keys(suites).length > 0) {\n await this.exec(suites);\n }\n }\n\n /**\n * Extracts and returns all TypeScript dependencies for a given test file.\n *\n * @param target - Absolute path of the file to analyze for imports.\n * @param force - If `true`, bypasses the cache and recomputes dependencies.\n * @returns An array of absolute paths representing the imported files.\n *\n * @remarks\n * This function reads the file content, matches all `import` or `from` statements\n * using the {@link WatchService.IMPORT_REGEX}, and resolves relative paths to absolute paths.\n * Results are cached in {@link dependenciesCache} for faster lookups.\n *\n * @example\n * ```ts\n * const deps = await getTestDependencies('/project/tests/unit/example.spec.ts');\n * console.log(deps); // ['/project/src/util.ts', '/project/src/helper.ts', ...]\n * ```\n *\n * @since 1.0.0\n */\n\n private async getTestDependencies(target: string, force: boolean = false): Promise<Array<string>> {\n if (!force && this.dependenciesCache.has(target)) {\n return this.dependenciesCache.get(target)!;\n }\n\n try {\n const content = await readFile(target, 'utf-8');\n const dependencies: string[] = [];\n\n for (const match of content.matchAll(WatchService.IMPORT_REGEX)) {\n const importPath = match.groups?.path;\n if (!importPath) continue;\n\n const path = resolveImport(importPath) ?? join(dirname(target), importPath);\n dependencies.push(path.endsWith('.ts') ? path : `${ path }.ts`);\n }\n\n this.dependenciesCache.set(target, dependencies);\n\n return dependencies;\n } catch {\n this.dependenciesCache.set(target, []);\n\n return [];\n }\n }\n\n /**\n * Recursively links a set of test files to their dependencies in the dependency graph.\n *\n * @param testFiles - Array of test file paths that depend on the given dependencies.\n * @param dependencies - Array of dependency file paths to link to the test files.\n *\n * @remarks\n * This function ensures that any changes in a dependency file can trigger re-execution\n * of all test files that depend on it. It also recursively processes nested dependencies\n * by calling {@link getTestDependencies} for each dependency.\n *\n * @example\n * ```ts\n * await linkDependency(['tests/unit/example.spec.ts'], ['src/util.ts']);\n * ```\n *\n * @since 1.0.0\n */\n\n private async linkDependency(testFiles: Array<string>, dependencies: Array<string>): Promise<void> {\n for (const dep of dependencies) {\n const depSet = this.dependencyGraph.get(dep) ?? new Set<string>();\n const originalSize = depSet.size;\n testFiles.forEach((test) => depSet.add(test));\n\n if (!this.dependencyGraph.has(dep)) {\n this.dependencyGraph.set(dep, depSet);\n }\n\n if (depSet.size > originalSize) {\n const nestedDeps = await this.getTestDependencies(dep);\n if (nestedDeps.length > 0) {\n await this.linkDependency(testFiles, nestedDeps);\n }\n }\n }\n }\n\n /**\n * Updates the dependency graph for a changed file.\n *\n * @param changedFile - The absolute path of the file that has changed.\n *\n * @remarks\n * This method ensures that the dependency graph remains up to date when a file changes:\n * - If the changed file is a test file (matches the configured patterns), its direct dependencies\n * are retrieved using {@link getTestDependencies} and linked via {@link linkDependency}.\n * - If the changed file is a dependency for other test files, all dependent test files are updated\n * recursively to include the changed file's dependencies.\n *\n * The dependency graph allows the watch service to re-run only affected test files when a source\n * or test file changes, improving efficiency during watch mode.\n *\n * @example\n * ```ts\n * await updateGraph('tests/unit/example.spec.ts');\n * ```\n *\n * @since 1.0.0\n */\n\n private async updateGraph(changedFile: string): Promise<void> {\n const isTestFile = matchesAny(changedFile, this.patterns);\n\n if (isTestFile) {\n const deps = await this.getTestDependencies(changedFile, true);\n await this.linkDependency([ changedFile ], deps);\n } else if (this.dependencyGraph.has(changedFile)) {\n const testFiles = [ ...this.dependencyGraph.get(changedFile)! ];\n const deps = await this.getTestDependencies(changedFile, true);\n await this.linkDependency(testFiles, deps);\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Dirent } from '@humanfs/node';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { join, relative } from 'path';\nimport { existsSync, readdirSync } from 'fs';\nimport { inject } from '@symlinks/symlinks.module';\nimport { FrameworkService } from '@services/framework.service';\nimport { compilePatterns, matchesAny } from '@components/glob.component';\n\n/**\n * Computes the relative path of a file from the project root.\n *\n * @param path - The full absolute path of the file.\n * @returns The file path relative to the root.\n *\n * @since 1.0.0\n */\n\nexport function getRelativePath(path: string): string {\n return relative(inject(FrameworkService).rootPath, path);\n}\n\n/**\n * Recursively collects test files from a directory matching include patterns and not matching exclude patterns.\n *\n * @param dir - Directory to scan.\n * @param patterns - Regex patterns for files to include.\n * @param excludes - Regex patterns for files to exclude.\n * @param suites - Regex patterns for test suites to include (temp suite filter).\n * @param specFiles - Optional accumulator for collected files.\n * @returns A map of relative file paths to absolute paths.\n *\n * @remarks\n * This function traverses the directory tree, skips excluded paths early, and collects files that\n * match both suite and file patterns. The `FrameworkService` is used to compute relative paths.\n *\n * @since 1.0.0\n */\n\nexport function collectFilesFromDir(\n dir: string, patterns: Array<RegExp>, excludes: Array<RegExp>, suites: Array<RegExp>, specFiles: Record<string, string> = {}\n): Record<string, string> {\n if (!existsSync(dir)) return {};\n const entries: Array<Dirent> = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = getRelativePath(fullPath);\n\n if (matchesAny(relativePath, excludes))\n continue;\n\n if (entry.isDirectory()) {\n collectFilesFromDir(fullPath, patterns, excludes, suites, specFiles);\n continue;\n }\n\n const allowSuite = suites.length === 0 || matchesAny(relativePath, suites);\n if (allowSuite && matchesAny(fullPath, patterns)) {\n const relativeFilePath = relativePath;\n const key = relativeFilePath.replace(/\\.[^/.]+$/, '');\n\n specFiles[key] = relativeFilePath;\n }\n }\n\n return specFiles;\n}\n\n/**\n * Retrieves all test files from a directory based on the provided configuration and suite filters.\n *\n * @param dir - Root directory to scan for test files.\n * @param config - Configuration object containing `files` and `exclude` patterns.\n * @returns A map of relative file paths to absolute paths.\n *\n * @remarks\n * This function compiles configuration patterns into regular expressions and delegates\n * a file collection to {@link collectFilesFromDir}.\n * It supports filtering by:\n * - **files** \u2192 which files to include\n * - **exclude** \u2192 which files or directories to skip\n * - **suites** \u2192 optional suite-specific filters;\n *\n * @example\n * ```ts\n * const specFiles = getSpecFiles('/project/tests', config, [/unit/]);\n * console.log(specFiles);\n * // { 'unit/test1.spec.ts': '/project/tests/unit/test1.spec.ts', ... }\n * ```\n *\n * @see collectFilesFromDir\n * @since 1.0.0\n */\n\nexport function getSpecFiles(dir: string, config: ConfigurationInterface): Record<string, string> {\n const suitesRegex = compilePatterns(config?.suites ?? []);\n const patternsRegex = compilePatterns(config?.files ?? []);\n const excludesRegex = compilePatterns(config?.exclude ?? []);\n\n return collectFilesFromDir(dir, patternsRegex, excludesRegex, suitesRegex);\n}\n", "/**\n * Constants\n */\n\nimport { getRelativePath } from '@providers/specs.provider';\n\n/**\n * Matches a single-character glob symbol (`?`).\n *\n * @remarks\n * In glob patterns, `?` matches exactly one character.\n *\n * @since 1.0.0\n */\n\nconst QUESTION_MARK = /\\?/g;\n\n/**\n * Matches brace expansion groups in glob patterns (e.g. `{a,b,c}`).\n *\n * @remarks\n * Brace groups expand into multiple alternatives separated by commas.\n *\n * @since 1.0.0\n */\n\nconst BRACE_PATTERN = /\\{([^}]+)\\}/g;\n\n/**\n * Matches double asterisks (`**`) used in glob patterns.\n *\n * @remarks\n * `**` typically represents recursive directory matching.\n *\n * @since 1.0.0\n */\n\nconst DOUBLE_ASTERISK = /(?:\\/|^)\\*{2}(?:\\/|$)/g;\n\n/**\n * Matches a single asterisk (`*`) in glob patterns.\n *\n * @remarks\n * `*` matches zero or more characters within a single directory segment.\n *\n * @since 1.0.0\n */\n\nconst SINGLE_ASTERISK = /(?<!\\.)\\*/g;\n\n/**\n * Matches escaped character classes in glob patterns (e.g. `[abc]`).\n *\n * @remarks\n * Used to translate character class expressions into regex equivalents.\n *\n * @since 1.0.0\n */\n\nconst CHARACTER_CLASS = /\\\\\\[([^\\]]+)\\\\\\]/g;\n\n/**\n * Matches special regex characters that need escaping.\n *\n * @remarks\n * Ensures that characters like `.`, `+`, `$`, `|`, `[]`, `\\`\n * are properly escaped when compiling glob patterns.\n *\n * @since 1.0.0\n */\n\nconst REGEX_SPECIAL_CHARS = /[.+$|[\\]\\\\]/g;\n\n/**\n * Compiles a glob pattern into a corresponding regular expression.\n *\n * @param globPattern - The glob pattern string to convert.\n * @returns A `RegExp` instance that matches the given glob pattern.\n *\n * @remarks\n * This function converts common glob syntax into equivalent\n * regular expression syntax. It supports:\n * - `*` to match zero or more characters (excluding `/`)\n * - `**` to match across directories\n * - `?` to match exactly one character\n * - Character classes like `[abc]`\n * - Brace expansions like `{a,b,c}`\n *\n * Escapes regex-special characters before applying glob conversions\n * to ensure the resulting expression is valid.\n *\n * @example\n * ```ts\n * const regex = compileGlobPattern(\"src/**\\/*.ts\");\n * console.log(regex.test(\"src/utils/helpers.ts\")); // true\n * console.log(regex.test(\"dist/index.js\")); // false\n * ```\n *\n * @since 1.0.0\n */\n\nexport function compileGlobPattern(globPattern: string): RegExp {\n const escapeRegexChars = (pattern: string): string =>\n pattern.replace(REGEX_SPECIAL_CHARS, '\\\\$&');\n\n const convertGlobToRegex = (pattern: string): string => {\n return pattern\n .replace(QUESTION_MARK, '.')\n .replace(DOUBLE_ASTERISK, '.*\\/?')\n .replace(SINGLE_ASTERISK, '[^/]+')\n .replace(CHARACTER_CLASS, (_, chars) => `[${ chars }]`)\n .replace(BRACE_PATTERN, (_, choices) =>\n `(${ choices.split(',').join('|') })`);\n };\n\n return new RegExp(`^${ convertGlobToRegex(escapeRegexChars(globPattern)) }$`);\n}\n\n/**\n * Determines whether a given string is a glob pattern.\n *\n * @param str - The string to test.\n * @returns `true` if the string contains glob-like syntax, otherwise `false`.\n *\n * @remarks\n * This function checks for the presence of common glob syntax\n * characters (`*`, `?`, `[]`, `{}`, `!`, `@`, `+`, `()`, `|`),\n * brace expressions (e.g. `{a,b}`), and extglob patterns\n * (e.g. `@(pattern)`).\n *\n * It is useful for distinguishing between literal file paths\n * and glob patterns when working with file matching or build\n * tools.\n *\n * @example\n * ```ts\n * isGlob(\"src/**\\/*.ts\"); // true\n * isGlob(\"file.txt\"); // false\n * isGlob(\"lib/@(a|b).js\"); // true\n * ```\n *\n * @since 1.0.0\n */\n\nexport function isGlob(str: string): boolean {\n // Checks for common glob patterns including:\n // * ? [ ] { } ! @ + ( ) |\n const globCharacters = /[*?[\\]{}!@+()|\\]]/.test(str);\n\n // Check for brace expressions like {a,b}\n const hasBraces = /{[^}]+}/.test(str);\n\n // Check for extglob patterns like @(pattern)\n const hasExtglob = /@\\([^)]+\\)/.test(str);\n\n return globCharacters || hasBraces || hasExtglob;\n}\n\n/**\n * Determines whether a given path matches any of the provided regular expression patterns.\n *\n * @param path - The string path to check against the patterns.\n * @param patterns - An array of RegExp objects to test the path against.\n * @returns A boolean indicating whether the path matches any of the patterns.\n *\n * @remarks This function is commonly used in file filtering operations like\n * in the `collectFilesFromDir` function to determine which files to include\n * or exclude based on pattern matching.\n *\n * @example\n * ```ts\n * const isMatch = matchesAny('src/file.ts', [/\\.ts$/, /\\.js$/]);\n * console.log(isMatch); // true\n * ```\n *\n * @since 1.6.0\n */\n\nexport function matchesAny(path: string, patterns: Array<RegExp>): boolean {\n return patterns.some(regex => regex.test(path));\n}\n\n/**\n * Compiles an array of string/glob/regex patterns into {@link RegExp} objects.\n *\n * @remarks\n * - If an entry is already a `RegExp`, it is returned as-is.\n * - If an entry is a glob pattern (e.g. `src/**\\/*.test.ts`), it is compiled into a regex\n * using {@link compileGlobPattern}.\n * - Otherwise, literal file paths are converted into an exact-match regex,\n * with regex metacharacters properly escaped.\n *\n * @param patterns - A list of strings (paths, globs) or regular expressions.\n * @returns An array of {@link RegExp} objects ready for matching.\n *\n * @example\n * ```ts\n * const regexes = compilePatterns([\n * /\\.test\\.ts$/, // already a regex\n * \"src/utils/helper.ts\", // literal file path\n * \"tests/**\\/*.spec.ts\" // glob pattern\n * ]);\n *\n * matchesAnyRegex(\"src/utils/helper.ts\", regexes); // true\n * ```\n *\n * @since 1.0.0\n */\n\nexport function compilePatterns(patterns: Array<string | RegExp>): Array<RegExp> {\n return patterns.map(pattern => {\n if (pattern instanceof RegExp) {\n return pattern;\n }\n\n if (isGlob(pattern)) {\n return compileGlobPattern(pattern);\n }\n\n const escapedPattern = getRelativePath(pattern).replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n return new RegExp(`^${ escapedPattern }$`);\n });\n}\n", "/**\n * Imports\n */\n\nimport { relative } from 'path';\nimport { readFileSync } from 'fs';\nimport { pathToFileURL } from 'url';\nimport { createRequire } from 'module';\nimport { inject } from '@symlinks/symlinks.module';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * A map storing TypeScript path aliases.\n *\n * @remarks\n * The keys are the alias patterns (with '*' removed), and the values are\n * the corresponding target paths (also with '*' removed).\n *\n * @example\n * ```ts\n * typescriptAlias.set('@app/', 'src/app/');\n * ```\n */\n\nexport const typescriptAlias = new Map<string, string>();\n\n/**\n * Updates the `typescriptAlias` map based on a `tsconfig.json` file.\n *\n * @param tsconfigPath - The path to the TypeScript configuration file.\n * Defaults to `'tsconfig.json'`.\n *\n * @remarks\n * Reads the `compilerOptions.paths` section and populates the alias map.\n * Only the first path in each entry is used, and any trailing '*' are removed.\n *\n * @example\n * ```ts\n * updateAliases(); // Uses default 'tsconfig.json'\n * updateAliases('configs/tsconfig.app.json'); // Custom path\n * ```\n */\n\nexport function updateAliases(tsconfigPath: string = 'tsconfig.json'): void {\n const raw = readFileSync(tsconfigPath, 'utf8');\n const json = JSON.parse(raw);\n const paths = json.compilerOptions?.paths;\n\n if (!paths) return;\n\n for (const [ key, value ] of Object.entries(paths)) {\n if (Array.isArray(value) && value.length > 0) {\n typescriptAlias.set(key.replace('*', ''), value[0].replace('*', ''));\n }\n }\n}\n\n/**\n * Resolves an import path to its relative path from the framework root.\n *\n * @param importPath - The import path to resolve.\n *\n * @returns The resolved relative path if found, otherwise `undefined`.\n *\n * @remarks\n * This function first checks the `typescriptAlias` map for a matching pattern.\n * If none is found, it attempts to resolve the module using Node's `require.resolve`.\n * The returned path is always relative to the framework's root path.\n *\n * @example\n * ```ts\n * const resolved = resolveImport('@app/utils');\n * // might return 'src/app/utils.ts' relative to framework root\n * ```\n */\n\nexport function resolveImport(importPath: string): string | undefined {\n const framework = inject(FrameworkService);\n for (const [ pattern, target ] of typescriptAlias.entries()) {\n if (importPath.includes(pattern)) {\n const resolved = importPath.replace(pattern, target);\n\n return relative(framework.rootPath, resolved);\n }\n }\n\n try {\n const require = createRequire(pathToFileURL(framework.rootPath + '/__placeholder__.js').href);\n const path = require.resolve(importPath);\n if(path) return relative(framework.rootPath, path);\n } catch {\n return;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractReporter } from '@messages/abstract/report.abstract';\nimport type { ReporterConstructorType } from '@messages/interfaces/abstract.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\nimport type { TranspileFileInterface } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { createRequire } from 'module';\nimport { xJetError } from '@errors/xjet.error';\nimport { sandboxExecute } from '@services/vm.service';\nimport { VMRuntimeError } from '@errors/vm-runtime.error';\nimport { transpileFile } from '@services/transpiler.service';\nimport { LogLevel } from '@messages/constants/report.constant';\nimport { JsonReporter } from '@messages/reports/json.reporter';\nimport { JunitReporter } from '@messages/reports/junit.reporter';\nimport { ConsoleReporter } from '@messages/reports/console.report';\n\n/**\n * Transpiles a reporter file into a CommonJS module.\n *\n * @param reporterPath - Path to the reporter file to transpile\n * @returns A promise that resolves to a {@link TranspileFileInterface} containing the transpiled file\n *\n * @remarks\n * Uses the `transpileFile` utility with predefined options:\n * - `minify: false`\n * - `format: 'cjs'`\n * - `platform: 'node'`\n * - `logLevel: 'silent'`\n * - `packages: 'external'`\n *\n * @see TranspileFileInterface\n * @since 1.0.0\n */\n\nexport async function transpile(reporterPath: string): Promise<TranspileFileInterface> {\n return transpileFile(reporterPath, {\n minify: false,\n format: 'cjs',\n platform: 'node',\n logLevel: 'silent',\n packages: 'external'\n });\n}\n\n/**\n * Loads and parses an external reporter file.\n *\n * @param reporterPath - Path to the external reporter file\n * @returns A promise that resolves to the reporter constructor ({@link ReporterConstructorType}) if successful, otherwise `undefined`\n *\n * @throws VMRuntimeError - If an error occurs during sandboxed execution\n *\n * @remarks\n * This function first transpiles the reporter using {@link transpile} and then executes it\n * in a sandboxed environment. The module's default export is expected to be a subclass of {@link AbstractReporter}.\n * Throws a {@link VMRuntimeError} if execution fails.\n *\n * @see transpile\n * @see ReporterConstructorType\n *\n * @since 1.0.0\n */\n\nexport async function parseExternalReporter(reporterPath: string): Promise<ReporterConstructorType | undefined> {\n const { code, path } = await transpile(reporterPath);\n\n try {\n const module = { exports: { default: undefined } };\n const require = createRequire(path);\n const context = { Error, Buffer, RegExp, module, process, console, require, setTimeout, setInterval };\n\n await sandboxExecute(code, context, { filename: path });\n\n return module.exports.default;\n } catch (error) {\n throw new VMRuntimeError(error as Error);\n }\n}\n\n/**\n * Retrieves a reporter instance based on the provided configuration.\n *\n * @param config - Configuration object containing reporter settings\n * @returns A promise that resolves to an {@link AbstractReporter} instance\n *\n * @throws xJetError - If the reporter path does not export a valid reporter class\n * @throws VMRuntimeError - If instantiation of a custom reporter fails\n *\n * @remarks\n * This function supports both built-in and custom external reporters:\n * - Built-in reporters: `json`, `junit`, `default` (console).\n * - Custom reporters: dynamically loaded via {@link parseExternalReporter}.\n * The reporter is instantiated with `LogLevel.Debug` and an optional output file path.\n *\n * @see LogLevel\n * @see AbstractReporter\n * @see parseExternalReporter\n *\n * @since 1.0.0\n */\n\nexport async function getReporter(config: ConfigurationInterface): Promise<AbstractReporter> {\n const { reporter, outputFile } = config;\n\n // Built-in reporters\n const builtInReporters: Record<string, new (level: LogLevel, path?: string) => AbstractReporter> = {\n json: JsonReporter,\n junit: JunitReporter,\n default: ConsoleReporter\n };\n\n if (builtInReporters[reporter] || !existsSync(reporter)) {\n const Reporter = builtInReporters[reporter] || ConsoleReporter;\n\n return new Reporter(LogLevel[config.logLevel] ?? 0, outputFile);\n }\n\n const CustomReporter = await parseExternalReporter(reporter);\n if (!CustomReporter) {\n throw new xJetError(`Reporter at \"${ reporter }\" does not have a valid default export`);\n }\n\n if (typeof CustomReporter !== 'function') {\n throw new xJetError(`Reporter at \"${ reporter }\" is not a valid constructor`);\n }\n\n try {\n return new CustomReporter(LogLevel.Debug, outputFile);\n } catch (error) {\n throw new VMRuntimeError(error as Error);\n }\n}\n", "/**\n * Defines the log verbosity levels for reporters and test execution.\n *\n * @remarks\n * Each level represents the minimum severity of messages that should be\n * captured or displayed. Higher levels include all messages from lower levels.\n *\n * @example\n * ```ts\n * if (log.level >= LogLevel.Warn) {\n * console.warn(log.message);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport enum LogLevel {\n Silent = 0,\n Error = 1,\n Warn = 2,\n Info = 3,\n Debug = 4\n}\n\n/**\n * Defines the types of messages emitted during test execution.\n *\n * @remarks\n * These message types are used internally by reporters, runners,\n * and event emitters to categorize test events. Each type corresponds\n * to a specific stage or element of the test lifecycle.\n *\n * @example\n * ```ts\n * if (message.type === MessageType.Test) {\n * console.log('Test event received');\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport const enum MessageType {\n Test = 1,\n Describe = 2,\n EndSuite = 3,\n StartSuite = 4\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { EndMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { JsonTestInterface } from '@messages/reports/interfaces/json-reporter.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { JsonDescribeInterface, JsonSuiteInterface } from '@messages/reports/interfaces/json-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { AbstractReporter } from '@messages/abstract/report.abstract';\n\n/**\n * Reporter implementation that generates a JSON representation of test execution results.\n *\n * @remarks\n * The {@link JsonReporter} class extends {@link AbstractReporter} and is responsible for\n * capturing suite, describe, and test events during execution.\n * Results are aggregated in memory as a nested object structure and written to disk\n * (and `stdout`) when {@link finish} is called.\n * This allows external tools to consume structured test output for analysis, dashboards,\n * or CI integrations.\n *\n * @example\n * ```ts\n * const reporter = new JsonReporter();\n * reporter.init(['math.spec.ts'], [runner]);\n * // events will populate `reporter.testResults`\n * reporter.finish(); // writes JSON file if `outFilePath` is set\n * ```\n *\n * @see AbstractReporter\n * @see JsonTestInterface\n * @see JsonSuiteInterface\n * @see JsonDescribeInterface\n *\n * @since 1.0.0\n */\n\nexport class JsonReporter extends AbstractReporter {\n /**\n * Holds aggregated results, keyed by runner and suite name.\n *\n * @remarks\n * Structure:\n * ```ts\n * {\n * runnerName: {\n * suiteName: JsonSuiteInterface\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n protected testResults: Record<string, Record<string, JsonSuiteInterface>> = {};\n\n /**\n * Initializes result containers for all suites and runners prior to execution.\n *\n * @param suites - An array of suite names (usually file paths or identifiers)\n * that will be executed.\n * @param runners - An array of runner instances, each implementing {@link RunnerInterface},\n * representing the environments in which the suites will run.\n *\n * @remarks\n * This method pre-populates the {@link JsonReporter.testResults | `testResults`} map\n * with an entry for every suite\u2013runner combination.\n * Each entry is initialized with an empty {@link JsonSuiteInterface} structure,\n * including a root {@link JsonDescribeInterface}, so that subsequent events\n * (such as tests and describes) can be safely appended without requiring null checks.\n *\n * @example\n * ```ts\n * reporter.init(['math.spec.ts'], [ { name: 'node' } ]);\n * console.log(reporter.testResults.node['math.spec.ts']);\n * // {\n * // runner: 'node',\n * // suiteName: 'math.spec.ts',\n * // timestamp: Date,\n * // rootDescribe: { tests: [], describes: [], ... }\n * // }\n * ```\n *\n * @since 1.0.0\n */\n\n init(suites: Array<string>, runners: Array<RunnerInterface>): void {\n for (const suiteName of suites) {\n for (const runner of runners) {\n this.testResults[runner.name] = this.testResults[runner.name] ?? {};\n this.testResults[runner.name][suiteName] = {\n runner: runner.name,\n suiteName: suiteName,\n timestamp: new Date(),\n rootDescribe: {\n tests: [],\n ancestry: [],\n describes: [],\n description: '',\n timestamp: new Date()\n }\n };\n }\n }\n }\n\n /**\n * Marks the start of a test suite execution and initializes its result container.\n *\n * @remarks\n * This method creates a fresh {@link JsonSuiteInterface} entry in\n * {@link JsonReporter.testResults | `testResults`} for the specified runner\u2013suite pair.\n * It ensures that any prior results are replaced with a clean structure,\n * containing a root {@link JsonDescribeInterface} to collect nested describes and tests.\n *\n * Typically called when the reporter receives a {@link StartMessageInterface} event\n * signaling the beginning of a suite.\n *\n * @param event - The suite start event, containing the suite name,\n * runner identifier, and timestamp of the start.\n *\n * @example\n * ```ts\n * reporter.suiteStart({\n * runner: 'node',\n * suite: 'math.spec.ts',\n * timestamp: new Date()\n * });\n *\n * console.log(reporter.testResults.node['math.spec.ts']);\n * // {\n * // runner: 'node',\n * // suiteName: 'math.spec.ts',\n * // timestamp: Date,\n * // rootDescribe: { tests: [], describes: [], ... }\n * // }\n * ```\n *\n * @see JsonSuiteInterface\n * @see JsonDescribeInterface\n *\n * @since 1.0.0\n */\n\n suiteStart(event: StartMessageInterface): void {\n const key = event.suite;\n const name = event.runner;\n\n this.testResults[name][key] = {\n runner: event.runner,\n suiteName: key,\n timestamp: event.timestamp,\n rootDescribe: {\n tests: [],\n ancestry: [],\n describes: [],\n description: '',\n timestamp: event.timestamp\n }\n };\n }\n\n /**\n * Handles the completion of a test suite and updates its metadata.\n *\n * @param event - The event object containing details about the completed suite.\n *\n * @remarks\n * This method is invoked when a test suite finishes execution. It updates the suite's\n * duration, the root describe block's duration, and records any errors that occurred\n * during the suite's execution. If the suite already has errors, the new error is\n * appended to the existing list; otherwise, a new errors array is created.\n *\n * @example\n * ```ts\n * suiteEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * duration: 1250,\n * error: new Error('Test failed')\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n suiteEnd(event: EndMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n\n suite.duration = event.duration;\n suite.rootDescribe.duration = event.duration;\n\n if (event.error) {\n suite.errors = suite.errors ?? [];\n suite.errors.push(event.error);\n }\n }\n\n /**\n * Handles the start of a `describe` block in a test suite and registers it in the suite hierarchy.\n *\n * @param event - The event object containing information about the `describe` block.\n *\n * @remarks\n * This method is called when a `describe` block begins execution. It constructs a JSON\n * representation of the `describe` block, including its ancestry, description, timestamp,\n * and skipped status. The block is then inserted into the appropriate parent within the\n * suite's structure. If no parent exists, it is added to the suite's `rootDescribe`.\n *\n * @example\n * ```ts\n * describeStart({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login functionality',\n * timestamp: Date.now(),\n * skipped: false\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n describeStart(event: StartAssertionMessageInterface): void {\n if(event.description === '') return;\n const describeJson: JsonDescribeInterface = {\n tests: [],\n describes: [],\n skipped: event.skipped ?? false,\n ancestry: event.ancestry,\n timestamp: event.timestamp,\n description: event.description\n };\n\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (parent) parent.describes.push(describeJson);\n else suite.rootDescribe.describes.push(describeJson);\n }\n\n /**\n * Handles the completion of a `describe` block and updates its metadata.\n *\n * @param event - The event object containing details about the completed `describe` block.\n *\n * @remarks\n * This method is invoked when a `describe` block finishes execution. It updates the block's\n * duration and records any errors that occurred during its execution. If the block already\n * has errors, new errors are appended to the existing list; otherwise, a new errors array\n * is created. If the specified `describe` block cannot be found in the suite, the method\n * exits silently.\n *\n * @example\n * ```ts\n * describeEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * duration: 320,\n * errors: [new Error('Login failed')]\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n describeEnd(event: EndAssertionMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n const describe = this.findParentDescribe(suite, event.ancestry);\n if (!describe) return;\n\n if (event.errors && event.errors.length > 0) {\n describe.errors = describe.errors ?? [];\n describe.errors.push(...event.errors);\n }\n\n describe.duration = event.duration;\n }\n\n /**\n * Handles the start of a test that is either skipped or marked as `todo` and registers it under its parent `describe`.\n *\n * @param event - The event object containing details about the test.\n *\n * @remarks\n * This method is invoked when a test begins execution but is either skipped or flagged as `todo`.\n * It constructs a JSON representation of the test, including its ancestry, description, timestamp,\n * skipped status, and todo status, and then inserts it into the appropriate parent `describe` block\n * within the suite. If the parent cannot be found, the method exits silently.\n *\n * @example\n * ```ts\n * testStart({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login with invalid credentials',\n * timestamp: Date.now(),\n * skipped: true,\n * todo: false\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n testStart(event: StartAssertionMessageInterface): void {\n if(!event.skipped && !event.todo) return;\n\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (!parent) return;\n\n const testJson: JsonTestInterface = {\n todo: event.todo,\n skipped: event.skipped,\n ancestry: event.ancestry,\n timestamp: event.timestamp,\n description: event.description\n };\n\n parent.tests.push(testJson);\n }\n\n /**\n * Handles the completion of a test and registers its results under the appropriate parent `describe`.\n *\n * @param event - The event object containing details about the completed test.\n *\n * @remarks\n * This method is called when a test finishes execution. It constructs a JSON representation\n * of the test, including its pass/fail status, errors, ancestry, duration, timestamp, and description.\n * The test result is then added to the parent `describe` block within the suite. If the parent\n * cannot be found, the method exits silently.\n *\n * @example\n * ```ts\n * testEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login with invalid credentials',\n * timestamp: Date.now(),\n * duration: 120,\n * passed: false,\n * errors: [new Error('Invalid credentials')]\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n testEnd(event: EndAssertionMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (!parent) return;\n\n const testJson: JsonTestInterface = {\n passed: event.passed,\n errors: event.errors ?? [],\n ancestry: event.ancestry,\n duration: event.duration,\n timestamp: event.timestamp,\n description: event.description\n };\n\n parent.tests.push(testJson);\n }\n\n /**\n * Finalizes the test run, outputs the results, and optionally writes them to a file.\n *\n * @remarks\n * This method serializes all collected test results into a JSON string with indentation\n * for readability. If an output file path (`outFilePath`) is specified, it writes the JSON\n * results to that file. Regardless of file output, the results are also logged to the console.\n *\n * @example\n * ```ts\n * // Finish a test run and write results to a file\n * testTracker.outFilePath = './results.json';\n * testTracker.finish();\n * ```\n *\n * @since 1.0.0\n */\n\n finish(): void {\n const result = JSON.stringify(this.testResults, null, 4);\n if(this.outFilePath) {\n const folderPath = dirname(this.outFilePath);\n mkdirSync(folderPath, { recursive: true });\n writeFileSync(this.outFilePath, result);\n }\n\n console.log(result);\n }\n\n /**\n * Retrieves a test suite by its runner and suite name from the collected test results.\n *\n * @param runner - The name or identifier of the test runner.\n * @param suiteName - The name or identifier of the suite to retrieve.\n * @returns The `JsonSuiteInterface` object representing the requested suite.\n *\n * @throws Will throw an error if the specified suite does not exist for the given runner.\n *\n * @remarks\n * This method looks up a suite within `testResults` using the provided runner and suite name.\n * If the suite does not exist, it throws an error. This ensures that any operations on suites\n * are performed on valid, existing data.\n *\n * @example\n * ```ts\n * const suite = this.getSuite('jest', 'UserService tests');\n * console.log(suite.rootDescribe.tests);\n * ```\n *\n * @since 1.0.0\n */\n\n private getSuite(runner: string, suiteName: string): JsonSuiteInterface {\n if(!this.testResults[runner] || !this.testResults[runner][suiteName])\n throw new Error(`Suite not found: ${ runner } -> ${ suiteName }`);\n\n return this.testResults[runner][suiteName];\n }\n\n /**\n * Finds the parent `describe` block within a suite based on the provided ancestry.\n *\n * @param suite - The suite in which to search for the parent `describe`.\n * @param ancestry - An array of strings representing the hierarchy of parent `describe` names.\n * @returns The `JsonDescribeInterface` representing the found parent `describe` block.\n * If no matching parent is found, returns the suite's `rootDescribe`.\n *\n * @remarks\n * This method traverses the hierarchy of `describe` blocks in a suite using the\n * `ancestry` array, which contains the sequence of parent descriptions leading\n * to the target block. If the ancestry is empty, the suite's `rootDescribe` is returned.\n * If any ancestor in the path is not found, the method returns the `rootDescribe`\n * as a fallback. This ensures tests and nested `describe` blocks are always attached\n * to a valid parent.\n *\n * @example\n * ```ts\n * const parentDescribe = this.findParentDescribe(suite, ['Authentication tests', 'Login tests']);\n * parentDescribe.tests.push(newTestJson);\n * ```\n *\n * @since 1.0.0\n */\n\n private findParentDescribe(suite: JsonSuiteInterface, ancestry: Array<string>): JsonDescribeInterface & JsonTestInterface {\n if (ancestry.length === 0) return suite.rootDescribe;\n let currentDescribes = suite.rootDescribe.describes ?? [];\n let parent: JsonDescribeInterface | undefined;\n\n for (const name of ancestry) {\n parent = currentDescribes.find(d => d.description === name);\n if (!parent) return suite.rootDescribe;\n currentDescribes = parent.describes;\n }\n\n return <JsonDescribeInterface> parent;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { LogLevel } from '@messages/constants/report.constant';\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { StartAssertionMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { StartMessageInterface, LogMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, EndMessageInterface } from '@messages/interfaces/messages.interface';\n\n/**\n * Base class for implementing custom reporters.\n *\n * @remarks\n * The `AbstractReporter` defines lifecycle hooks that can be implemented\n * by concrete reporter classes to customize how test results are reported.\n *\n * Reporters receive structured event messages during test execution,\n * including suite start/end, describe/test assertions, logs, and finalization.\n *\n * Each method is optional (`?`) and may be implemented depending on\n * the reporter\u2019s needs (e.g., console logging, file output, JSON reporting).\n *\n * @example\n * ```ts\n * class ConsoleReporter extends AbstractReporter {\n * log(log: LogMessageInterface): void {\n * console.log(`[LOG] ${log.message}`);\n * }\n *\n * suiteStart(event: StartMessageInterface): void {\n * console.log(`Suite started: ${event.suiteName}`);\n * }\n * }\n * ```\n *\n * @see RunnerInterface\n * @see LogMessageInterface\n * @see StartMessageInterface\n * @see EndMessageInterface\n *\n * @since 1.0.0\n */\n\nexport abstract class AbstractReporter {\n /**\n * Creates a new reporter.\n *\n * @param logLevel - The minimum log level this reporter should handle.\n * @param outFilePath - Optional file path where logs or reports should be written.\n */\n\n constructor(\n protected readonly logLevel: LogLevel,\n protected readonly outFilePath?: string\n ) {}\n\n /**\n * Initializes the reporter before test execution starts.\n *\n * @remarks\n * This method is called at the beginning of each test session.\n * In **watch mode**, it will be invoked for every new session restart.\n * Reporters can use this hook to reset the internal state, prepare output files,\n * or print session headers.\n *\n * @param suites - A list of suite names to be executed in this session.\n * @param runners - A list of configured runners available in this session.\n *\n * @since 1.0.0\n */\n\n init?(suites: Array<string>, runners: Array<RunnerInterface>): void;\n\n /**\n * Handles log messages emitted during test execution.\n *\n * @param log - The structured log message including level, text,\n * and optional metadata.\n *\n * @remarks\n * This method is triggered whenever the test code calls\n * `xJet.log()`, `xJet.error()`, or similar logging helpers.\n * Reporters can use this hook to capture, format, and\n * output logs to the console, files, or custom UIs.\n *\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n log?(log: LogMessageInterface): void;\n\n /**\n * Signals the start of a test suite execution.\n *\n * @param event - The structured event containing suite metadata\n * such as its ID, name, and runner.\n *\n * @remarks\n * Called when a suite begins running. Reporters can use this\n * hook to display suite headers, initialize timers, or log\n * contextual information about the suite.\n *\n * @see StartMessageInterface\n * @since 1.0.0\n */\n\n suiteStart?(event: StartMessageInterface): void;\n\n /**\n * Signals the completion of a test suite execution.\n *\n * @param event - The structured event containing final suite\n * metadata such as its ID, name, duration, and\n * aggregated results.\n *\n * @remarks\n * Called after a suite has finished running. Reporters can use\n * this hook to display summary information, update progress,\n * or finalize suite-level reporting.\n *\n * @see EndMessageInterface\n * @since 1.0.0\n */\n\n suiteEnd?(event: EndMessageInterface): void;\n\n /**\n * Signals the start of a `describe` block execution.\n *\n * @param event - The structured event containing metadata\n * about the `describe` block, including its\n * ID, name, and parent context.\n *\n * @remarks\n * Called when a `describe` block begins running. Reporters\n * can use this hook to display section headers, indent logs,\n * or prepare contextual grouping in the output.\n *\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n describeStart?(event: StartAssertionMessageInterface): void;\n\n /**\n * Signals the completion of a `describe` block execution.\n *\n * @param event - The structured event containing metadata\n * about the `describe` block, including its\n * ID, name, duration, and results.\n *\n * @remarks\n * Called after a `describe` block has finished running.\n * Reporters can use this hook to close sections, summarize\n * grouped tests, or adjust indentation and formatting.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n describeEnd?(event: EndAssertionMessageInterface): void;\n\n /**\n * Signals the start of an individual test execution.\n *\n * @param event - The structured event containing metadata\n * about the test, including its ID, name,\n * and parent suite or `describe` block.\n *\n * @remarks\n * Called when a test begins running. Reporters can use this\n * hook to display test-level headers, start timers, or\n * track progress.\n *\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n testStart?(event: StartAssertionMessageInterface): void;\n\n /**\n * Signals the completion of an individual test execution.\n *\n * @param event - The structured event containing metadata\n * about the test, including its ID, name,\n * duration, and result status.\n *\n * @remarks\n * Called after a test has finished running. Reporters can use\n * this hook to display test results, update progress bars,\n * or log assertion summaries.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n testEnd?(event: EndAssertionMessageInterface): void;\n\n /**\n * Called when all suites have finished executing.\n *\n * @remarks\n * This method is invoked at the **end of each test session**.\n * In watch mode, it will be called after every session completes,\n * allowing reporters to finalize logs, write summary files, or\n * perform cleanup for that session.\n *\n * @since 1.0.0\n */\n\n finish?(): void;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { JsonDescribeInterface } from '@messages/reports/interfaces/json-reporter.interface';\nimport type { JsonSuiteInterface, JsonTestInterface } from '@messages/reports/interfaces/json-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { JsonReporter } from '@messages/reports/json.reporter';\n\n/**\n * JunitReporter converts test results into JUnit-compatible XML format.\n *\n * @remarks\n * Extends the `JsonReporter` to output test results as XML. This reporter\n * traverses the suites, describes, and tests collected during the run,\n * producing a hierarchical XML representation suitable for CI tools.\n *\n * @example\n * ```ts\n * const reporter = new JunitReporter();\n * reporter.testStart({ ... });\n * reporter.testEnd({ ... });\n * reporter.finish(); // Outputs JUnit XML to console or file\n * ```\n *\n * @since 1.0.0\n */\n\nexport class JunitReporter extends JsonReporter {\n /**\n * Parts of the XML document being built during test result conversion.\n *\n * @remarks\n * This array stores fragments of the JUnit XML output as strings. The final XML\n * is constructed by joining these parts together in `finish()`. It is initialized\n * with the XML declaration and grows as suites, describes, and tests are converted\n * to XML.\n *\n * @example\n * ```ts\n * this.xmlParts.push('<testsuite name=\"ExampleSuite\">');\n * this.xmlParts.push('</testsuite>');\n * const xmlContent = this.xmlParts.join('\\n');\n * ```\n *\n * @since 1.0.0\n */\n\n protected xmlParts: Array<string> = [ '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' ];\n\n /**\n * Finalizes the JUnit XML report and outputs it.\n *\n * @remarks\n * This method constructs the complete JUnit XML document from the collected test results.\n * It iterates over all test runners and their suites, converts them into XML format,\n * and appends them to the internal `xmlParts` array. After building the full XML:\n * - If `outFilePath` is defined, the XML is written to the specified file.\n * - The XML is also logged to the console.\n *\n * @example\n * ```ts\n * reporter.finish(); // Generates and outputs the complete JUnit XML\n * ```\n *\n * @since 1.0.0\n */\n\n finish(): void {\n this.xmlParts.push('<testsuites>');\n Object.entries(this.testResults).forEach(([ runnerName, suitesByName ]) => {\n this.xmlParts.push(`<testsuites name=\"${ runnerName }\">`);\n\n Object.values(suitesByName).forEach(suite => {\n this.convertSuiteToXml(suite);\n });\n\n this.xmlParts.push('</testsuites>');\n });\n\n this.xmlParts.push('</testsuites>');\n const xmlContent = this.xmlParts.join('\\n');\n if(this.outFilePath) {\n const folderPath = dirname(this.outFilePath);\n mkdirSync(folderPath, { recursive: true });\n writeFileSync(this.outFilePath, xmlContent);\n }\n\n console.log(xmlContent);\n }\n\n /**\n * Converts a test suite into a JUnit `<testsuite>` XML element and appends it to `xmlParts`.\n *\n * @param suite - The test suite to convert to XML.\n *\n * @remarks\n * This method calculates the total number of tests, failures, skipped tests, and the suite duration.\n * It constructs the `<testsuite>` element with these attributes and recursively converts\n * the root describe block and all nested describes/tests into XML. The resulting XML\n * fragments are appended to the `xmlParts` array.\n *\n * @example\n * ```ts\n * this.convertSuiteToXml(suite);\n * // xmlParts will now include <testsuite> with all tests nested inside\n * ```\n *\n * @since 1.0.0\n */\n\n private convertSuiteToXml(suite: JsonSuiteInterface): void {\n const rootDescribe = suite.rootDescribe;\n const tests = this.countTests(rootDescribe);\n const failures = this.countFailures(rootDescribe);\n const skipped = this.countSkipped(rootDescribe);\n const duration = this.formatDuration(suite.duration);\n\n const suiteAttrs = [\n `name=\"${ suite.suiteName }\"`,\n `tests=\"${ tests }\"`,\n `failures=\"${ failures }\"`,\n `skipped=\"${ skipped }\"`,\n `time=\"${ duration }\"`\n ].join(' ');\n\n this.xmlParts.push(`<testsuite ${ suiteAttrs }>`);\n this.convertDescribeToXml(rootDescribe);\n this.xmlParts.push('</testsuite>');\n }\n\n /**\n * Recursively converts a `describe` block and its nested describes/tests into XML.\n *\n * @param describe - The `describe` block to convert.\n *\n * @remarks\n * This method traverses the hierarchy of a `describe` block:\n * - Converts all tests in the current describe using `convertTestToXml`.\n * - Recursively processes all nested describes.\n *\n * The resulting XML fragments are appended to the `xmlParts` array.\n *\n * @example\n * ```ts\n * this.convertDescribeToXml(rootDescribe);\n * // All tests and nested describes are appended to xmlParts\n * ```\n *\n * @since 1.0.0\n */\n\n private convertDescribeToXml(describe: JsonDescribeInterface): void {\n describe.tests.forEach(test => this.convertTestToXml(test));\n describe.describes.forEach(nested => this.convertDescribeToXml(nested));\n }\n\n /**\n * Converts a single test into a JUnit `<testcase>` XML element and appends it to `xmlParts`.\n *\n * @param test - The test to convert.\n *\n * @remarks\n * This method constructs the XML representation of a test including:\n * - `classname` based on its ancestry\n * - `name` from the test description\n * - `time` from the test duration in seconds\n *\n * It handles different test statuses:\n * - Skipped or TODO tests generate a `<skipped>` child element.\n * - Passed tests generate a self-closing `<testcase>` element.\n * - Failed tests include one or more `<failure>` elements created by `formatErrors`.\n *\n * @example\n * ```ts\n * this.convertTestToXml(test);\n * // xmlParts will include a <testcase> element representing this test\n * ```\n *\n * @since 1.0.0\n */\n\n private convertTestToXml(test: JsonTestInterface): void {\n const duration = this.formatDuration(test.duration);\n const name = test.description;\n const classname = test.ancestry.join('.') || 'root';\n const baseAttributes = `classname=\"${ classname }\" name=\"${ name }\" time=\"${ duration }\"`;\n\n if (test.skipped || test.todo) {\n const reason = test.todo ? 'TODO' : 'Skipped';\n this.xmlParts.push(`<testcase ${ baseAttributes }><skipped message=\"${ reason }\" /></testcase>`);\n\n return;\n }\n\n if (test.passed) {\n this.xmlParts.push(`<testcase ${ baseAttributes } />`);\n\n return;\n }\n\n const errors = this.formatErrors(test.errors);\n this.xmlParts.push(`<testcase ${ baseAttributes }>${ errors }</testcase>`);\n }\n\n /**\n * Formats an array of test errors into JUnit `<failure>` XML elements.\n *\n *\n * @param errors - Array of errors from a test.\n * @returns A string containing one or more `<failure>` XML elements concatenated.\n *\n * @remarks\n * Each error is converted into a `<failure>` element with:\n * - `message` attribute from the error name\n * - Escaped error message and stack trace inside the element\n * - Optional `formatCode` content if provided\n *\n * If the errors array is empty or undefined, an empty string is returned.\n *\n * @example\n * ```ts\n * const xmlErrors = this.formatErrors(test.errors);\n * // xmlErrors contains <failure> elements for each test error\n * ```\n *\n * @since 1.0.0\n */\n\n private formatErrors(errors: JsonTestInterface['errors']): string {\n if (!errors?.length) return '';\n\n return errors.map(e =>\n `<failure message=\"${ e.name }\">${ this.escapeXml(e.message) }\\n${ e.formatCode }\\n\\n${ this.escapeXml(e.stack) }</failure>`\n ).join('');\n }\n\n /**\n * Converts a duration from milliseconds to seconds as a string with three decimal places.\n *\n * @param duration - The duration in milliseconds.\n * @returns The duration in seconds as a string with three decimal places.\n *\n * @remarks\n * If the input duration is `undefined`, it defaults to `0`. The output is formatted\n * as a string suitable for inclusion in JUnit XML `time` attributes.\n *\n * @example\n * ```ts\n * const seconds = this.formatDuration(1234); // \"1.234\"\n * const zero = this.formatDuration(); // \"0.000\"\n * ```\n *\n * @since 1.0.0\n */\n\n private formatDuration(duration?: number): string {\n return ((duration ?? 0) / 1000).toFixed(3);\n }\n\n /**\n * Counts the total number of tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count tests in.\n * @returns The total number of tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks to calculate\n * the total number of tests. Only actual test entries in the `tests` array are counted;\n * skipped or todo tests are included in this count.\n *\n * @example\n * ```ts\n * const totalTests = this.countTests(rootDescribe);\n * console.log(totalTests); // e.g., 15\n * ```\n *\n * @since 1.0.0\n */\n\n private countTests(describe: JsonDescribeInterface): number {\n return describe.tests.length + describe.describes.reduce((sum, nested) => sum + this.countTests(nested), 0);\n }\n\n /**\n * Counts the total number of skipped or TODO tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count skipped or TODO tests in.\n * @returns The total number of skipped or TODO tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks. A test is counted as skipped\n * if its `skipped` or `todo` property is `true`.\n *\n * @example\n * ```ts\n * const skippedTests = this.countSkipped(rootDescribe);\n * console.log(skippedTests); // e.g., 3\n * ```\n *\n * @since 1.0.0\n */\n\n private countSkipped(describe: JsonDescribeInterface): number {\n const skippedInCurrent = describe.tests.filter(t => t.skipped || t.todo).length;\n\n return skippedInCurrent + describe.describes.reduce((sum, nested) => sum + this.countSkipped(nested), 0);\n }\n\n /**\n * Counts the total number of failed tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count failed tests in.\n * @returns The total number of failed tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks. A test is counted as a failure\n * if it is not passed, not skipped, and not marked as TODO.\n *\n * @example\n * ```ts\n * const failedTests = this.countFailures(rootDescribe);\n * console.log(failedTests); // e.g., 2\n * ```\n *\n * @since 1.0.0\n */\n\n private countFailures(describe: JsonDescribeInterface): number {\n const failuresInCurrent = describe.tests.filter(t => !t.passed && !t.skipped && !t.todo).length;\n\n return failuresInCurrent + describe.describes.reduce((sum, nested) => sum + this.countFailures(nested), 0);\n }\n\n /**\n * Escapes special XML characters in a string to ensure valid XML output.\n *\n * @param str - The string to escape.\n * @returns The escaped string safe for XML content.\n *\n * @remarks\n * This method replaces the following characters with their corresponding XML entities:\n * - `&` \u2192 `&amp;`\n * - `\"` \u2192 `&quot;`\n * - `'` \u2192 `&apos;`\n * - `<` \u2192 `&lt;`\n * - `>` \u2192 `&gt;`\n *\n * @example\n * ```ts\n * const safeXml = this.escapeXml('<div class=\"example\">Hello & Welcome</div>');\n * console.log(safeXml);\n * // &lt;div class=&quot;example&quot;&gt;Hello &amp; Welcome&lt;/div&gt;\n * ```\n *\n * @since 1.0.0\n */\n\n private escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { SuiteMapInterface } from '@messages/reports/interfaces/console-reporter.interface';\nimport type { EndMessageInterface, LogMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, SuiteErrorInterface } from '@messages/interfaces/messages.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { SuiteStatsInterface, TestStatsInterface } from '@messages/reports/interfaces/console-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { ANSI, writeRaw } from '@remotex-labs/xansi';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { LogLevel } from '@messages/constants/report.constant';\nimport { ShadowRenderer } from '@remotex-labs/xansi/shadow.service';\nimport { AbstractReporter } from '@messages/abstract/report.abstract';\nimport { ConsoleState, formatStatus, statePrefix, STATIC_HEIGHT } from '@messages/reports/constants/console.constant';\n\n/**\n * Reporter that renders test suite and test results in the console.\n *\n * @remarks\n * The `ConsoleReporter` extends {@link AbstractReporter} and is responsible for:\n * - Rendering suite and test results in real-time using ANSI colors and cursor control.\n * - Tracking per-suite and per-test statistics via {@link SuiteStatsInterface} and {@link TestStatsInterface}.\n * - Maintaining per-suite content for rendering with {@link ShadowRenderer}.\n * - Showing summary of suites and tests, including totals, passed, failed, skipped, and TODO counts.\n *\n * It uses:\n * - `ShadowRenderer` for managing console regions (info and status blocks).\n * - `formatStatus` and `statePrefix` for ANSI-colored output.\n * - `STATIC_HEIGHT` to reserve space for status display at the bottom.\n *\n * @example\n * ```ts\n * const reporter = new ConsoleReporter(LogLevel.Info);\n * reporter.init(['MySuite'], runners);\n * reporter.testStart(testEvent);\n * reporter.testEnd(testEndEvent);\n * reporter.suiteEnd(suiteEndEvent);\n * reporter.finish();\n * ```\n *\n * @since 1.0.0\n */\n\nexport class ConsoleReporter extends AbstractReporter {\n /**\n * Timestamp when the reporter started.\n * @since 1.0.0\n */\n\n private startTime: number = Date.now();\n\n /**\n * Whether there is only a single runner executing tests.\n * @since 1.0.0\n */\n\n private isSingleRunner = false;\n\n /**\n * Interval ID for periodic state updates.\n * @since 1.0.0\n */\n\n private updateInterval: NodeJS.Timeout | undefined;\n\n /**\n * Maximum length of runner names, used for padding in the console display.\n * @since 1.0.0\n */\n\n private maxRunnerNameLength = 0;\n\n /**\n * ShadowRenderer for displaying per-suite detailed output.\n * @since 1.0.0\n */\n\n private readonly info: ShadowRenderer;\n\n /**\n * ShadowRenderer for displaying a summary of all suites and tests.\n * @since 1.0.0\n */\n\n private readonly status: ShadowRenderer;\n\n /**\n * Aggregated test counters across all suites.\n * @since 1.0.0\n */\n\n private tests: Required<TestStatsInterface> = this.createTests();\n\n /**\n * Aggregated suite counters across all suites.\n * @since 1.0.0\n */\n\n private suites: Required<SuiteStatsInterface> = this.createSuites();\n\n /**\n * Map of suite name + runner to per-suite rendering content and stats.\n * @since 1.0.0\n */\n\n private readonly suiteMap: Map<string, Required<SuiteMapInterface>> = new Map();\n\n /**\n * Initializes the console reporter.\n *\n * @param logLevel - The log level threshold for output.\n * @param outFilePath - Optional path for writing logs to a file.\n *\n * @remarks\n * Creates `ShadowRenderer` instances for info and status blocks based on terminal size.\n *\n * @since 1.0.0\n */\n\n constructor(logLevel: LogLevel, outFilePath?: string) {\n super(logLevel, outFilePath);\n\n const height = process.stdout.rows ?? 24;\n const width = process.stdout.columns ?? 80;\n\n this.info = new ShadowRenderer(height - STATIC_HEIGHT - 1, width, 1, 0);\n this.status = new ShadowRenderer(STATIC_HEIGHT, width, height - STATIC_HEIGHT, 0);\n }\n\n /**\n * Initializes the console reporter with suites and runners.\n *\n * @param suites - Array of suite names to track and render.\n * @param runners - Array of runner objects executing the tests.\n *\n * @remarks\n * This method performs the following actions:\n * - Clears the console and hides the cursor using ANSI sequences.\n * - Resets internal start time, test and suite counters.\n * - Determines if only a single runner is executing to adjust formatting.\n * - Starts a periodic interval to update the summary status at the bottom.\n * - Initializes `suiteMap` with per-suite content and counters for each runner.\n * - Prepares each suite title with a pending status using {@link getPrefix}.\n * - Renders all suites immediately using {@link renderSuites}.\n *\n * Each suite in `suiteMap` includes:\n * - `todo`, `total`, `passed`, `failed`, `skipped` counters initialized to `0`.\n * - `title` with `[ Pending ]` status prefix.\n * - Empty `details` array for storing log lines and error messages.\n *\n * @example\n * ```ts\n * reporter.init(['Suite1', 'Suite2'], runners);\n * ```\n *\n * @since 1.0.0\n */\n\n init(suites: Array<string>, runners: Array<RunnerInterface>): void {\n writeRaw(ANSI.HIDE_CURSOR);\n writeRaw(ANSI.CLEAR_SCREEN);\n\n this.suiteMap.clear();\n this.startTime = Date.now();\n this.tests = this.createTests();\n this.suites = this.createSuites();\n this.isSingleRunner = runners.length < 2;\n this.updateInterval = setInterval(this.updateState.bind(this), 230);\n this.maxRunnerNameLength = Math.max(...runners.map(r => r.name.length));\n\n for (const suiteName of suites) {\n for (const runner of runners) {\n const key = this.getSuiteKey(runner.name, suiteName);\n const title = this.getPrefix(ConsoleState.Pending, runner.name, suiteName);\n this.suiteMap.set(key, {\n todo: 0,\n total: 0,\n passed: 0,\n failed: 0,\n skipped: 0,\n title: title,\n details: []\n });\n }\n }\n\n this.renderSuites();\n }\n\n /**\n * Handles a log message emitted by a test or suite and appends it to the corresponding suite details.\n *\n * @param log - The structured log message containing the message, level, ancestry, and optional invocation.\n *\n * @remarks\n * This method performs the following actions:\n * - Ignores the message if its level is below the reporter's `logLevel` or if `LogLevel.Silent` is set.\n * - Ensures the suite exists in `suiteMap` using {@link ensureSuite}.\n * - Formats the log message with:\n * - Level prefix using {@link getLogPrefix}.\n * - Ancestry path of the test/describe block.\n * - Indented multi-line message.\n * - Optional source code location if `log.invocation` is provided.\n * - Appends each formatted line to the suite's `details` array.\n * - Adds an empty line after each log for separation.\n * - Renders all suites immediately using {@link renderSuites}.\n *\n * @example\n * ```ts\n * reporter.log({\n * level: 'info',\n * levelId: LogLevel.Info,\n * message: 'This is a log message',\n * runner: 'runner1',\n * suite: 'MySuite',\n * ancestry: ['describe1', 'test1'],\n * timestamp: new Date()\n * });\n * ```\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n log(log: LogMessageInterface): void {\n if (log.levelId > this.logLevel || this.logLevel === LogLevel.Silent) return;\n const suite = this.ensureSuite(log.runner, log.suite);\n\n const lines: Array<string> = [ '' ];\n lines.push(this.getLogPrefix(log) + xterm.gray(` [${ log.ancestry.join(' > ') }]`));\n lines.push(...log.message.split('\\n').map(line => ' '.repeat(2) + line));\n\n if (log.invocation) {\n lines.push(\n xterm.gray(`at (${ log.invocation.source }:${ log.invocation.line }:${ log.invocation.column })`)\n );\n }\n\n for (const line of lines) {\n suite.details.push(line);\n }\n\n suite.details.push('');\n this.renderSuites();\n }\n\n /**\n * Handles the start of a test suite and updates the console display accordingly.\n *\n * @param event - Structured event data containing the runner and suite information.\n *\n * @remarks\n * This method performs the following actions:\n * - Ensures the suite exists in `suiteMap` using {@link ensureSuite}.\n * - Updates the suite title with a running status prefix using {@link getPrefix}.\n * - Renders the updated suites to the console using {@link renderSuites}.\n *\n * This is typically called when the reporter receives a {@link StartMessageInterface} from a test runner.\n *\n * @see StartMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#getPrefix - Generates the status-prefixed suite title.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see ConsoleReporter#renderSuites - Renders the suite map to the terminal.\n *\n * @since 1.0.0\n */\n\n suiteStart(event: StartMessageInterface): void {\n const suite = this.ensureSuite(event.runner, event.suite);\n suite.title = this.getPrefix(ConsoleState.Run, event.runner, event.suite);\n this.renderSuites();\n }\n\n /**\n * Handles the completion of a test suite and updates the console display accordingly.\n *\n * @param event - Structured event data containing suite results, runner information, duration, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Increments the global suite counter.\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - Determines the suite's final status based on errors, skipped/todo tests, or failed tests.\n * - Updates the suite title with a status prefix and duration using {@link getPrefix}.\n * - Adds formatted error details to the suite if present using {@link parseError}.\n * - Renders the updated suites to the console using {@link renderSuites}.\n *\n * This is typically called when the reporter receives an {@link EndMessageInterface} from a test runner.\n *\n * @see EndMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#getPrefix - Generates the status-prefixed suite title.\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see ConsoleReporter#renderSuites - Renders the suite map to the terminal.\n *\n * @since 1.0.0\n */\n\n suiteEnd(event: EndMessageInterface): void {\n this.suites.total += 1;\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n let prefix = ConsoleState.Passed;\n if (event.error) {\n this.suites.failed += 1;\n prefix = ConsoleState.Failed;\n } else if (suiteStats.total === suiteStats.skipped + suiteStats.todo) {\n this.suites.skipped += 1;\n prefix = ConsoleState.Skipped;\n } else if (suiteStats.failed > 0) {\n this.suites.failed += 1;\n prefix = ConsoleState.Failed;\n } else {\n this.suites.passed += 1;\n }\n\n let title = this.getPrefix(prefix, event.runner, event.suite);\n title += ` ${ (event.duration / 1000).toFixed(3) } s`;\n suiteStats.title = title;\n\n if (event.error) {\n suiteStats.details.push(...this.parseError(event.error));\n }\n\n this.renderSuites();\n }\n\n /**\n * Handles the completion of a `describe` block within a suite and updates its status.\n *\n * @param event - Structured event data containing `describe` block results, runner, suite, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - If errors are present, increments the `failed` counter for the suite.\n * - Appends formatted error details to the suite using {@link parseError}.\n *\n * This is typically called when the reporter receives an {@link EndAssertionMessageInterface}\n * event for a `describe` block.\n *\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see EndAssertionMessageInterface - Structure of the event data passed to this method.\n *\n * @since 1.0.0\n */\n\n describeEnd(event: EndAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.errors?.length) {\n suiteStats['failed'] += 1;\n for (const err of event.errors) {\n suiteStats.details.push(...this.parseError(err));\n }\n }\n }\n\n /**\n * Handles the start of a test case and updates the suite counters for `todo` or skipped tests.\n *\n * @param event - Structured event data containing test start information, runner, suite, and optional `todo`/`skipped` flags.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - If the test is marked `todo` or `skipped`, increments the corresponding counters in both\n * the suite and overall test statistics using {@link incrementTestCounters}.\n *\n * This is typically called when the reporter receives a {@link StartAssertionMessageInterface}\n * event for a test case.\n *\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see StartAssertionMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#incrementTestCounters - Updates the test counters for the suite and global stats.\n *\n * @since 1.0.0\n */\n\n testStart(event: StartAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.todo || event.skipped) {\n this.incrementTestCounters(event.todo ? 'todo' : 'skipped', suiteStats);\n }\n }\n\n /**\n * Handles the completion of a test case, updates counters, and appends formatted output for the suite.\n *\n * @param event - Structured event data containing test results, runner, suite, duration, ancestry, description, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - Increments the total test counters for the suite and global stats.\n * - If the test has errors:\n * - Marks the test as `failed` via {@link incrementTestCounters}.\n * - Appends a formatted test line with the ancestry path, description, and duration.\n * - Adds parsed error details using {@link parseError}.\n * - If no errors are present, marks the test as `passed` via {@link incrementTestCounters}.\n *\n * This is typically called when the reporter receives an {@link EndAssertionMessageInterface}\n * event for a test case.\n *\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see EndAssertionMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#incrementTestCounters - Updates the test counters for the suite and global stats.\n *\n * @since 1.0.0\n */\n\n testEnd(event: EndAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.errors && event.errors.length > 0) {\n this.incrementTestCounters('failed', suiteStats);\n\n let testLine = formatStatus.failed(`\u25CF ${ event.ancestry.join(' > ') } > ${ event.description }`);\n testLine += xterm.gray(` (${ (event.duration / 1000).toFixed(3) } s)`);\n suiteStats.details.push(testLine);\n\n for (const err of event.errors) {\n suiteStats.details.push(...this.parseError(err));\n }\n } else {\n this.incrementTestCounters('passed', suiteStats);\n }\n }\n\n /**\n * Finalizes the console reporter, clears the display, and flushes all pending output.\n *\n * @remarks\n * This method performs the following actions:\n * - Stops the periodic state update interval if it is running.\n * - Updates the console state one last time using {@link updateState}.\n * - Clears both the `info` and `status` {@link ShadowRenderer} buffers.\n * - Flushes all content from the `info` and `status` renderers to the terminal.\n *\n * Typically called after all suites and tests have completed to ensure\n * the console displays the final test results cleanly.\n *\n * @see ConsoleReporter#updateState - Updates the rendered state for suites and tests.\n * @see ShadowRenderer#clearScreen - Clears the renderer buffer.\n * @see ShadowRenderer#flushToTerminal - Outputs the buffered content to the terminal.\n *\n * @since 1.0.0\n */\n\n finish(): void {\n this.updateInterval?.close();\n this.updateState();\n\n this.info.clearScreen();\n this.status.clearScreen();\n this.info.flushToTerminal();\n this.status.flushToTerminal();\n }\n\n /**\n * Generates a unique key for a suite based on the runner name and suite name.\n *\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the test suite.\n * @returns A string key in the format `{runner}::{suiteName}` used to store and retrieve suite data.\n *\n * @remarks\n * This key is used internally to map each suite per runner in {@link suiteMap}.\n *\n * @see ConsoleReporter#suiteMap - Internal map storing per-suite information.\n *\n * @since 1.0.0\n */\n\n private getSuiteKey(runner: string, suiteName: string): string {\n return `${ runner }::${ suiteName }`;\n }\n\n /**\n * Retrieves the suite stats object for a given runner and suite name.\n *\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the test suite.\n * @returns The corresponding {@link SuiteMapInterface} containing counters, title, and details.\n *\n * @remarks\n * This method uses {@link getSuiteKey} to construct the key for the internal\n * {@link suiteMap} and retrieves the suite information.\n *\n * The returned object is guaranteed to exist if the suite was initialized via {@link init}.\n *\n * @see ConsoleReporter#getSuiteKey - Generates the key used to index the suite map.\n * @see ConsoleReporter#suiteMap - Internal storage of suite stats and details.\n *\n * @since 1.0.0\n */\n\n private ensureSuite(runner: string, suiteName: string): SuiteMapInterface {\n return this.suiteMap.get(this.getSuiteKey(runner, suiteName))!;\n }\n\n /**\n * Initializes and returns a fresh test statistics object.\n *\n * @returns A {@link TestStatsInterface} object with all counters set to `0`.\n *\n * @remarks\n * This method is used to reset or initialize the global test counters before\n * execution begins, ensuring all test counts start from zero.\n *\n * @see TestStatsInterface - Defines the counters for tests across all suites.\n *\n * @since 1.0.0\n */\n\n private createTests(): TestStatsInterface {\n return { total: 0, passed: 0, failed: 0, skipped: 0, todo: 0 };\n }\n\n /**\n * Creates a new suite statistics object with all counters initialized to zero.\n *\n * @returns A {@link SuiteStatsInterface} object representing the initial state of suite counters.\n *\n * @remarks\n * This method is used to reset or initialize the global suite counters before\n * execution begins. All counters (`total`, `passed`, `failed`, `skipped`) start from `0`.\n *\n * @see SuiteStatsInterface - Interface defining counters for suite execution.\n *\n * @since 1.0.0\n */\n\n private createSuites(): SuiteStatsInterface {\n return { total: 0, passed: 0, failed: 0, skipped: 0 };\n }\n\n /**\n * Converts a {@link SuiteErrorInterface} into an array of formatted strings for console output.\n *\n * @param error - The error object containing message, formatted code, and stack trace.\n * @returns An array of strings representing the error, formatted for display in the console.\n *\n * @remarks\n * The returned array contains:\n * - An empty line at the start\n * - The error message split by line\n * - The formatted code lines dimmed using {@link xterm.dim}\n * - The stack trace lines\n * - An empty line at the end\n *\n * This is used internally by the {@link ConsoleReporter} to render detailed error information\n * for failed tests or suites in the shadowed console output.\n *\n * @see SuiteErrorInterface - Structure of the error object.\n * @see xterm.dim - Utility to dim text in console output.\n *\n * @since 1.0.0\n */\n\n private parseError(error: SuiteErrorInterface): Array<string> {\n const lines = [ '', ...error.message.split('\\n'), '' ];\n lines.push(...error.formatCode.split('\\n').map(data => xterm.dim(data)), '');\n lines.push(...error.stack.split('\\n'), '');\n\n return lines;\n }\n\n /**\n * Increments the specified test counter for both the global test stats and the given suite stats.\n *\n * @param counter - The specific counter to increment (`total`, `passed`, `failed`, `skipped`, or `todo`).\n * @param suiteStats - The {@link TestStatsInterface} object representing the suite's current test statistics.\n *\n * @remarks\n * This method updates both the per-suite counters and the overall counters maintained\n * by the {@link ConsoleReporter}. The `total` counter is always incremented alongside\n * the specified counter.\n *\n * @see TestStatsInterface - Interface defining the available test counters.\n *\n * @since 1.0.0\n */\n\n private incrementTestCounters(counter: keyof TestStatsInterface, suiteStats: TestStatsInterface): void {\n suiteStats.total += 1;\n this.tests.total += 1;\n suiteStats[counter] += 1;\n this.tests[counter] += 1;\n }\n\n private updateState(): void {\n const suitesParts: Array<string> = [];\n const testsParts: Array<string> = [];\n\n if (this.suites.failed > 0) suitesParts.push(formatStatus.failed(`${ this.suites.failed } failed`));\n if (this.suites.passed > 0) suitesParts.push(formatStatus.passed(`${ this.suites.passed } passed`));\n if (this.suites.skipped > 0) suitesParts.push(formatStatus.skipped(`${ this.suites.skipped } skipped`));\n if (this.suites.total > 0) suitesParts.push(`${ this.suites.total } total`);\n\n if (this.tests.failed > 0) testsParts.push(formatStatus.failed(`${ this.tests.failed } failed`));\n if (this.tests.passed > 0) testsParts.push(formatStatus.passed(`${ this.tests.passed } passed`));\n if (this.tests.skipped > 0) testsParts.push(formatStatus.skipped(`${ this.tests.skipped } skipped`));\n if (this.tests.todo > 0) testsParts.push(formatStatus.todo(`${ this.tests.todo } todo`));\n if (this.tests.total > 0) testsParts.push(`${ this.tests.total } total`); // total at the end\n\n const elapsedSeconds = ((Date.now() - this.startTime) / 1000).toFixed(3);\n this.status.writeBlock(\n 0,\n 0,\n `Suites: ${ suitesParts.length ? suitesParts.join(', ') : 'No suites yet' }\\n` +\n `Tests: ${ testsParts.length ? testsParts.join(', ') : 'No tests yet' }\\n` +\n `Time: ${ xterm.lightOrange(`${ elapsedSeconds } s`) }`,\n true\n );\n this.status.render();\n }\n\n /**\n * Renders the current state of all suites and their test details to the console.\n *\n * @remarks\n * This method iterates over all suites in {@link suiteMap} and writes:\n * - The suite title at the current row\n * - Each suite detail (e.g., test logs, errors) indented by 2 spaces\n *\n * It uses the {@link ShadowRenderer} instances (`info`) to render the content\n * and handles scrolling if the number of rows exceeds the renderer's height.\n * After rendering suites, it calls {@link updateState} to refresh the summary of global counters.\n *\n * @see suiteMap - Map containing per-suite statistics and details.\n * @see ShadowRenderer - Handles writing text to a shadow buffer and flushing to the terminal.\n * @see updateState - Updates the global summary of test and suite counters.\n *\n * @since 1.0.0\n */\n\n private renderSuites(): void {\n let row = 0;\n for (const [ , suite ] of this.suiteMap) {\n this.info.writeText(row++, 0, suite.title, true);\n\n for (const detail of suite.details) {\n this.info.writeText(row++, 2, ANSI.CLEAR_LINE + detail, true);\n }\n }\n\n if (row > this.info.height) {\n this.info.scroll = row - this.info.height;\n } else {\n this.info.render();\n }\n\n this.updateState();\n }\n\n /**\n * Generates a formatted prefix for a suite, including its status and runner name.\n *\n * @param status - The current {@link ConsoleState} of the suite (e.g., Run, Passed, Failed).\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the suite.\n * @returns A formatted string with the suite status, optional runner name, and dimmed suite name.\n *\n * @remarks\n * - If `isSingleRunner` is true, the runner name is omitted.\n * - Uses {@link statePrefix} to map {@link ConsoleState} to a colored label.\n * - Suite name is dimmed for readability using {@link xterm.dim}.\n * - Runner name is colored with `xterm.burntOrange` when multiple runners are present.\n *\n * @see statePrefix\n * @see ConsoleState\n *\n * @since 1.0.0\n */\n\n private getPrefix(status: ConsoleState, runner: string, suiteName: string): string {\n const runnerPrefix = this.isSingleRunner ? '' :\n xterm.burntOrange(` [ ${ runner.padEnd(this.maxRunnerNameLength) } ]`);\n\n return `${ statePrefix[status] }${ runnerPrefix } ${ xterm.dim(suiteName) }`;\n }\n\n /**\n * Generates a formatted ANSI-colored prefix for a log message based on its level.\n *\n * @param log - The {@link LogMessageInterface} containing log level and details.\n * @returns A string representing the log level wrapped with the appropriate ANSI color codes.\n *\n * @remarks\n * - Maps {@link LogLevel} values to {@link formatStatus} or {@link xterm} colors:\n * - `Error` \u2192 `formatStatus.failed`\n * - `Warn` \u2192 `formatStatus.skipped`\n * - `Info` \u2192 `xterm.cyanBright`\n * - `Debug` \u2192 `formatStatus.running`\n * - Any other or default \u2192 `formatStatus.pending`\n * - The returned string is formatted as `[level]` in lowercase, colored according to its severity.\n *\n * @see LogMessageInterface\n * @see LogLevel\n * @see formatStatus\n * @see xterm\n *\n * @since 1.0.0\n */\n\n private getLogPrefix(log: LogMessageInterface): string {\n let statusPrefix = formatStatus.pending;\n\n switch (log.levelId) {\n case LogLevel.Error:\n statusPrefix = formatStatus.failed;\n break;\n case LogLevel.Warn:\n statusPrefix = formatStatus.skipped;\n break;\n case LogLevel.Info:\n statusPrefix = xterm.cyanBright;\n break;\n case LogLevel.Debug:\n statusPrefix = formatStatus.running;\n break;\n }\n\n return statusPrefix(`[ ${ log.level.toLowerCase() } ]`);\n }\n}\n", "/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * The fixed height in rows reserved for the console status display.\n *\n * @remarks\n * Used by {@link ConsoleReporter} and {@link ShadowRenderer} to reserve\n * space for the summary of suites and tests at the bottom of the terminal.\n *\n * @since 1.0.0\n */\n\nexport const STATIC_HEIGHT = 4;\n\n/**\n * ANSI color functions for rendering different statuses in the console.\n *\n * @remarks\n * Each property is a function that wraps a string in the corresponding color using `xterm.hex`.\n *\n * @example\n * ```ts\n * console.log(formatStatus.passed('Test Passed'));\n * ```\n *\n * @since 1.0.0\n */\n\nexport const formatStatus = {\n todo: xterm.hex('#da5aec'),\n failed: xterm.hex('#F08080'),\n passed: xterm.hex('#90EE90'),\n skipped: xterm.hex('#fcaa63'),\n running: xterm.hex('#FFD966'),\n pending: xterm.hex('#808080')\n} as const;\n\n/**\n * Mapping of {@link ConsoleState} to their corresponding display string with ANSI styling.\n *\n * @remarks\n * Used for rendering the status prefix of each suite in the console output.\n *\n * @example\n * ```ts\n * console.log(statePrefix[ConsoleState.Failed]); // Outputs a red \"[ FAILED ]\"\n * ```\n *\n * @since 1.0.0\n */\n\nexport const statePrefix: Record<ConsoleState, string> = {\n [ConsoleState.Pending]: formatStatus.pending('[ Pending ]'),\n [ConsoleState.Run]: formatStatus.running('[ RUNNING ]'),\n [ConsoleState.Skipped]: formatStatus.skipped('[ SKIPPED ]'),\n [ConsoleState.Passed]: formatStatus.passed('[ PASSED ]'),\n [ConsoleState.Failed]: formatStatus.failed('[ FAILED ]')\n};\n\n/**\n * Represents the possible states of a suite or test in the console reporter.\n *\n * @remarks\n * Used to determine which ANSI color and prefix to display for each suite or test.\n *\n * @example\n * ```ts\n * if (state === ConsoleState.Failed) {\n * console.log('This suite failed!');\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport const enum ConsoleState {\n Run = 0,\n Failed = 2,\n Passed = 3,\n Skipped = 4,\n Pending = 5\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractTarget } from '@targets/abstract/target.abstract';\nimport type { ErrorType } from '@messages/interfaces/abstract.interface';\nimport type { AbstractReporter } from '@messages/abstract/report.abstract';\nimport type { PacketKind } from '@packets/constants/packet-schema.constants';\nimport type { DecodedPacketType } from '@packets/interfaces/packets.interface';\nimport type { LogMessageInterface, SuiteErrorInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, EndMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { StackMetadataInterface, StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\n\n/**\n * Imports\n */\n\nimport { stackMetadata } from '@providers/stack.provider';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { LogLevel, MessageType } from '@messages/constants/report.constant';\n\n/**\n * Service for translating low-level {@link AbstractTarget} events into structured reporter messages.\n *\n * @remarks\n * The `MessageService` subscribes to a given execution target and transforms its raw\n * events (logs, errors, suite lifecycle, test events) into structured messages.\n * These messages are forwarded to an {@link AbstractReporter} implementation.\n *\n * Responsibilities:\n * - Logging events (`log`) \u2192 {@link handleLog}\n * - Suite errors (`error`) \u2192 {@link handleSuiteError}\n * - Suite lifecycle (`status`) \u2192 {@link handleSuiteStatus}\n * - Assertions & describes (`events`) \u2192 {@link handleSuiteEvent}\n *\n * @example\n * ```ts\n * const service = new MessageService(target);\n * await service.init(['suite.spec.ts'], config);\n * ```\n *\n * @see AbstractTarget\n * @see AbstractReporter\n * @since 1.0.0\n */\n\nexport class MessageService {\n /**\n * Framework service reference for resolving source maps and code metadata.\n *\n * @remarks\n * Injected via the DI system. Used mainly to map logs and errors to their\n * original code positions for more precise reporting.\n *\n * @since 1.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Indicates whether any test-level error has occurred.\n * @private\n */\n\n private error = false;\n\n /**\n * Indicates whether any suite-level error has occurred.\n * @private\n */\n\n private suiteError = false;\n\n /**\n * Creates a new `MessageService` and subscribes to target events.\n *\n * @param target - The execution target emitting logs, errors, and lifecycle events.\n * @param reporter - The active reporter receiving structured messages.\n *\n * @remarks\n * Binds the following listeners:\n * - `'log'` \u2192 {@link handleLog}\n * - `'error'` \u2192 {@link handleSuiteError}\n * - `'status'` \u2192 {@link handleSuiteStatus}\n * - `'events'` \u2192 {@link handleSuiteEvent}\n *\n * @since 1.0.0\n */\n\n constructor(readonly target: AbstractTarget, readonly reporter: AbstractReporter) {\n this.target.on('log', this.handleLog.bind(this));\n this.target.on('error', this.handleSuiteError.bind(this));\n this.target.on('status', this.handleSuiteStatus.bind(this));\n this.target.on('events', this.handleSuiteEvent.bind(this));\n }\n\n /**\n * Returns `true` if **any suite-level error** has been detected.\n * @returns `true` if a suite error occurred, otherwise `false`.\n *\n * @since 1.0.0\n */\n\n get hasSuiteError(): boolean {\n return this.suiteError;\n }\n\n /**\n * Returns `true` if **any test** has been detected.\n * @returns `true` if there is any error, otherwise `false`.\n *\n * @since 1.0.0\n */\n\n get hasError(): boolean {\n return this.error;\n }\n\n /**\n * Transforms a log packet into a {@link LogMessageInterface} and sends it to the reporter.\n *\n * @param log - The decoded log packet.\n * @param suitePath - Path of the suite that generated the log.\n *\n * @remarks\n * Resolves source position using source maps, attaches invocation context,\n * and passes the structured message to `reporter.log`.\n *\n * @example\n * ```ts\n * target.emit('log', logPacket, '/suite/path');\n * ```\n *\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n handleLog(log: DecodedPacketType<PacketKind.Log>, suitePath: string): void {\n const sourcemap = this.framework.getSourceMap(log.invocation.source);\n const source = sourcemap?.getPositionWithCode(log.invocation.line, log.invocation.column);\n\n const message: LogMessageInterface = {\n level: LogLevel[log.level] ?? 'UNKNOWN',\n suite: suitePath,\n runner: this.target.getRunnerName(log.runnerId),\n levelId: log.level,\n message: log.message,\n ancestry: log.ancestry.split(','),\n timestamp: new Date(log.timestamp)\n };\n\n if (source) {\n message.invocation = {\n code: source.code,\n line: source.line,\n column: source.column,\n source: source.source\n };\n }\n\n this.reporter.log?.(message);\n }\n\n /**\n * Transforms a suite error into an {@link EndMessageInterface} and sends it to the reporter.\n *\n * @param suiteError - The decoded error packet.\n * @param suitePath - Path of the suite where the error occurred.\n *\n * @remarks\n * Marks the suite as complete, decodes the error via {@link decodeError},\n * and forwards the message to `reporter.suiteEnd`.\n *\n * @see EndMessageInterface\n * @see SuiteErrorInterface\n * @since 1.0.0\n */\n\n handleSuiteError(suiteError: DecodedPacketType<PacketKind.Error>, suitePath: string): void {\n this.target.completeSuite(suiteError.runnerId + suiteError.suiteId, true);\n const message: EndMessageInterface = {\n suite: suitePath,\n error: <SuiteErrorInterface>this.decodeError(suiteError.error, { linesBefore: 2, linesAfter: 3 }),\n runner: this.target.getRunnerName(suiteError.runnerId),\n duration: 0,\n timestamp: new Date(suiteError.timestamp)\n };\n\n this.suiteError = true;\n this.reporter.suiteEnd?.(message);\n }\n\n /**\n * Handles suite lifecycle status updates.\n *\n * @param status - The decoded status packet.\n * @param suitePath - Path of the suite associated with the status.\n *\n * @remarks\n * Supported types:\n * - `StartSuite` \u2192 calls `reporter.suiteStart`\n * - `EndSuite` \u2192 marks suite complete and calls `reporter.suiteEnd`\n * - `Test` / `Describe` \u2192 builds a {@link StartAssertionMessageInterface} and calls `reporter.testStart` / `reporter.describeStart`\n *\n * @see MessageType\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n handleSuiteStatus(status: DecodedPacketType<PacketKind.Status>, suitePath: string): void {\n const baseMessage: StartMessageInterface = {\n suite: suitePath,\n runner: this.target.getRunnerName(status.runnerId),\n timestamp: new Date(status.timestamp)\n };\n\n switch (status.type) {\n case MessageType.StartSuite:\n this.reporter.suiteStart?.(baseMessage);\n break;\n case MessageType.EndSuite:\n this.target.completeSuite(status.runnerId + status.suiteId, false);\n (<EndMessageInterface> baseMessage).duration = status.duration;\n this.reporter.suiteEnd?.(<EndMessageInterface> baseMessage);\n break;\n case MessageType.Test:\n case MessageType.Describe: {\n const assertionMessage: StartAssertionMessageInterface = <StartAssertionMessageInterface> baseMessage;\n assertionMessage.ancestry = status.ancestry.split(',');\n assertionMessage.description = status.description;\n\n if (status.todo) assertionMessage.todo = true;\n if (status.skipped) assertionMessage.skipped = true;\n\n if (status.type === MessageType.Test) {\n this.reporter.testStart?.(assertionMessage);\n } else {\n this.reporter.describeStart?.(assertionMessage);\n }\n break;\n }\n }\n }\n\n /**\n * Handles completion of tests or describes.\n *\n * @param events - The decoded event's packet.\n * @param suitePath - Path of the suite associated with this event.\n *\n * @remarks\n * Builds an {@link EndAssertionMessageInterface}, attaches errors if present,\n * and forwards it to `reporter.testEnd` or `reporter.describeEnd`.\n *\n * Sets `hasError = true` if errors are present.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n handleSuiteEvent(events: DecodedPacketType<PacketKind.Events>, suitePath: string): void {\n const message: EndAssertionMessageInterface = {\n suite: suitePath,\n passed: true,\n runner: this.target.getRunnerName(events.runnerId),\n duration: events.duration,\n ancestry: events.ancestry.split(','),\n timestamp: new Date(events.timestamp),\n description: events.description\n };\n\n if (events.errors) {\n message.errors = <Array<SuiteErrorInterface>>this.decodeError(events.errors, { linesBefore: 2, linesAfter: 3 });\n message.passed = false;\n this.error = true;\n }\n\n if(events.type === MessageType.Test) {\n this.reporter.testEnd?.(message);\n } else {\n this.reporter.describeEnd?.(message);\n }\n }\n\n /**\n * Parses and structures an error or error array.\n *\n * @param error - JSON stringified error(s).\n * @param options - Optional stack trace metadata.\n * @returns Structured error(s).\n *\n * @remarks\n * - Parses into {@link ErrorType}.\n * - Enhances with {@link stackMetadata}.\n * - Falls back to caught error if parsing fails.\n *\n * @see SuiteErrorInterface\n * @since 1.0.0\n */\n\n private decodeError(error: string, options: StackTraceInterface = {}): SuiteErrorInterface | Array<SuiteErrorInterface> {\n try {\n const errorObject: ErrorType = JSON.parse(error);\n if (Array.isArray(errorObject)) {\n return errorObject.map(err => {\n return this.structuredError(\n err,\n stackMetadata(err, options)\n );\n });\n }\n\n return this.structuredError(\n errorObject,\n stackMetadata(errorObject, options)\n );\n } catch (e) {\n return this.structuredError(\n <ErrorType>e, stackMetadata(<ErrorType>e, options)\n );\n }\n }\n\n /**\n * Converts an {@link ErrorType} into a {@link SuiteErrorInterface}.\n *\n * @param error - Original error object.\n * @param metadata - Stack metadata for enriching error details.\n * @returns A structured error object.\n *\n * @remarks\n * Builds a standardized shape with name, message, matcher result,\n * and enriched stack/position info.\n *\n * @see ErrorType\n * @see StackMetadataInterface\n * @since 1.0.0\n */\n\n private structuredError(error: ErrorType, metadata: StackMetadataInterface): SuiteErrorInterface {\n return {\n name: error.name,\n line: metadata.line,\n code: metadata.code,\n formatCode: metadata.formatCode,\n stack: metadata.stacks,\n column: metadata.column,\n message: error.message,\n matcherResult: error.matcherResult\n };\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { ModuleInterface, TranspileFileType } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport * as process from 'process';\nimport { pathToFileURL } from 'url';\nimport { createRequire } from 'module';\nimport { dirname, relative, resolve } from 'path';\nimport { sandboxExecute } from '@services/vm.service';\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { AbstractTarget } from '@targets/abstract/target.abstract';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Local execution target for running tests within the local JavaScript environment.\n *\n * @remarks\n * The `LocalService` executes tests directly in a sandboxed environment\n * rather than using external runners. It handles:\n * - Test execution\n * - Error handling\n * - Source mapping and runtime context injection for accurate reporting\n *\n * @example\n * ```ts\n * const localService = new LocalService(config, frameworkService);\n * await localService.initTarget();\n * await localService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see PacketKind\n * @see AbstractTarget\n * @see TranspileFileType\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class LocalService extends AbstractTarget {\n /**\n * Unique identifier for the local runner instance.\n *\n * @remarks\n * This ID is generated when the `LocalService` instance is created and is used\n * to track test suites executed in the local environment. It ensures that each\n * suite execution can be associated with a specific runner for reporting and\n * error handling purposes.\n *\n * @since 1.0.0\n */\n\n private runnerId: string = this.generateId();\n\n /**\n * Returns the name of the local runner.\n *\n * @remarks\n * Since `LocalService` only has a single runner, this method always returns\n * the string `'local'`. It is used to identify the runner in reports,\n * events, and suite execution tracking.\n *\n * @returns The string `'local'`.\n *\n * @since 1.0.0\n */\n\n getRunnerName(): string {\n return 'local';\n }\n\n /**\n * Returns an array containing the local runner.\n *\n * @returns An array with a single object:\n * - `id`: The unique runner ID (`runnerId`).\n * - `name`: The runner name, always `'local'`.\n *\n * @remarks\n * `LocalService` only manages a single local runner. This method provides\n * a consistent interface with other targets by returning an array of\n * `RunnerInterface` objects, each with an `id` and `name`.\n *\n * @example\n * ```ts\n * const runners = localService.getRunners();\n * console.log(runners[0].id); // e.g., 'local-123'\n * console.log(runners[0].name); // 'local'\n * ```\n *\n * @since 1.0.0\n */\n\n getRunners(): Array<RunnerInterface> {\n return [\n {\n id: this.runnerId,\n name: this.getRunnerName()\n }\n ];\n }\n\n /**\n * Executes the provided transpiled test suites in a sandboxed local environment.\n *\n * @param transpileSuites - An array of transpiled test files to execute.\n * @param suites - A record mapping original suite names to their file paths.\n *\n * @remarks\n * This method registers the provided suites using `setSuites` and queues each\n * transpiled test file for execution using the internal queue. Each suite is\n * executed in the local sandbox via `executeTestWithErrorHandling`.\n *\n * Errors during execution are captured and emitted via the `eventEmitter`, but\n * do not halt the execution of other suites. The queue ensures controlled,\n * asynchronous execution of all tasks.\n *\n * @example\n * ```ts\n * await localService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see {@link setSuites} to register suites internally.\n * @see {@link executeTestWithErrorHandling} for individual suite execution logic.\n *\n * @since 1.0.0\n */\n\n async executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void> {\n this.setSuites(suites);\n const testExecutionTasks: Array<Promise<void>> = [];\n\n for (const transpile of transpileSuites) {\n const relativePath = relative(this.framework.rootPath, transpile.path)\n .replace(/\\.[^/.]+$/, '');\n\n testExecutionTasks.push(this.queue.enqueue(async () => {\n return this.executeTestWithErrorHandling(transpile.code, transpile.path, relativePath);\n }));\n }\n\n this.queue.start();\n await Promise.allSettled(testExecutionTasks);\n }\n\n /**\n * Executes test code in a local sandboxed environment.\n *\n * @param testCode - The transpiled test code to execute.\n * @param transpileFilePath - The original file path of the test file.\n * @param suiteId - The unique ID of the suite being executed.\n *\n * @remarks\n * This method creates a sandboxed execution context including\n * - Node.js globals (`Buffer`, `console`, timers)\n * - A `module` object for CommonJS exports\n * - A `require` function scoped to the test file\n * - A `__XJET` runtime context containing configuration and suite metadata\n * - A `dispatch` function for emitting test events\n *\n * The `sandboxExecute` function runs the test code within this isolated context.\n *\n * @example\n * ```ts\n * await localService.executeInSandbox(testCode, '/path/to/test.spec.ts', suiteId);\n * ```\n *\n * @since 1.0.0\n */\n\n private async executeInSandbox(testCode: string, transpileFilePath: string, suiteId: string): Promise<void> {\n const path = this.suites.get(suiteId)!;\n const module: ModuleInterface = { exports: {} };\n const require = createRequire(transpileFilePath);\n\n const safeProcess = Object.freeze({\n ...process,\n stdout: { write: (): void => {} },\n stderr: { write: (): void => {} }\n });\n\n const sandboxContext = {\n ...globalThis,\n Buffer,\n module,\n require,\n setTimeout,\n setInterval,\n clearTimeout,\n clearInterval,\n process: safeProcess,\n dispatch: this.dispatch.bind(this),\n __dirname: dirname(path),\n __filename: path,\n import_meta: {\n url: pathToFileURL(path),\n dirname: dirname(resolve(path)),\n filename: path\n },\n __XJET: {\n runtime: {\n bail: this.config.bail,\n path: path,\n filter: this.config.filter,\n timeout: this.config.timeout,\n suiteId: suiteId,\n runnerId: this.runnerId,\n randomize: this.config.randomize\n }\n }\n };\n\n await sandboxExecute(testCode, sandboxContext);\n }\n\n /**\n * Executes a single test suite in the local sandbox with error handling.\n *\n * @param testCode - The transpiled test code to execute.\n * @param filePath - The original file path of the test file.\n * @param relativePath - The relative path used to retrieve the suite ID.\n *\n * @returns A `Promise` that resolves when the suite has been executed or fails gracefully.\n *\n * @remarks\n * This method wraps the execution of a test suite in a `Promise` and tracks\n * it in the `runningSuites` map using the suite ID. If `executeInSandbox`\n * throws an error, the suite is marked as complete with failure, and an\n * 'error' event is emitted via the `eventEmitter`.\n *\n * The emitted error includes:\n * - `kind`: The packet type (`PacketKind.Error`)\n * - `error`: The serialized error object\n * - `suiteId`: The unique ID of the suite\n * - `runnerId`: The ID of the local runner\n *\n *\n * @example\n * ```ts\n * await localService.executeTestWithErrorHandling(testCode, '/path/to/test.spec.ts', 'tests/test.spec');\n * ```\n *\n * @since 1.0.0\n */\n\n private executeTestWithErrorHandling(testCode: string, filePath: string, relativePath: string): Promise<void> {\n const suiteId = this.suites.get(relativePath)!;\n\n return new Promise(async (resolve, reject) => {\n try {\n this.runningSuites.set(this.runnerId + suiteId, { resolve, reject });\n await this.executeInSandbox(testCode, filePath, suiteId);\n } catch (error) {\n this.completeSuite(this.runnerId + suiteId, true);\n this.eventEmitter.emit('error', {\n kind: PacketKind.Error,\n error: JSON.stringify(serializeError(error)),\n suiteId: suiteId,\n runnerId: this.runnerId,\n timestamp: new Date()\n }, this.suites.get(suiteId)!);\n }\n });\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { DecodedPacketType } from '@packets/packets.module';\nimport type { FunctionLikeType, FunctionType } from '@remotex-labs/xjet-expect';\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\nimport type { RunnerInterface, RunningSuitesInterface } from '@targets/interfaces/traget.interface';\n\n/**\n * Imports\n */\n\nimport EventEmitter from 'events';\nimport { xJetError } from '@errors/xjet.error';\nimport { decodePacket } from '@packets/packets.module';\nimport { QueueService } from '@services/queue.service';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Abstract Target class for all xJet execution targets.\n *\n * @remarks\n * A `AbstractTarget` defines the core lifecycle and event-handling logic\n * used by concrete target implementations (e.g., local, remote, or distributed).\n * It manages suites, event dispatching, and lifecycle completion.\n *\n * @since 1.0.0\n */\n\nexport abstract class AbstractTarget {\n /**\n * Queue service responsible for scheduling and executing tasks.\n * @since 1.0.0\n */\n\n protected readonly queue: QueueService;\n\n /**\n * Tracks the currently running test suites and their associated promises.\n * @since 1.0.0\n */\n\n protected readonly runningSuites: Map<string, RunningSuitesInterface> = new Map();\n\n /**\n * Registry of loaded test suites keyed by suite identifier.\n * @since 1.0.0\n */\n\n protected readonly suites: Map<string, string> = new Map();\n\n /**\n * Event emitter used for handling log, error, status, and event packets.\n * @since 1.0.0\n */\n\n protected readonly eventEmitter = new EventEmitter();\n\n /**\n * Creates a new runner service instance.\n *\n * @param config - The runtime configuration for the runner.\n *\n * @remarks\n * The {@link FrameworkService} is injected automatically and does not need\n * to be passed manually. The constructor initializes the {@link QueueService}\n * with the parallelism level defined in the configuration.\n *\n * @since 1.0.0\n */\n\n protected readonly framework: FrameworkService = inject(FrameworkService);\n\n /**\n * Initializes a new {@link AbstractTarget} instance.\n *\n * @param config - The runtime configuration that controls execution behavior,\n * such as parallelism and bail mode.\n *\n * @remarks\n * The constructor sets up the internal {@link QueueService} based on the\n * configured parallelism level. Other dependencies (e.g., {@link FrameworkService})\n * are injected automatically and not passed here.\n *\n * @since 1.0.0\n */\n\n constructor(protected config: ConfigurationInterface) {\n this.queue = new QueueService(this.config.parallel);\n }\n\n /**\n * Returns the number of currently active tasks in the queue.\n * @since 1.0.0\n */\n\n get numberActiveTask(): number {\n return this.queue.size;\n }\n\n /**\n * Initializes the target environment with the given specification files.\n * @returns A `Promise` that resolves when the initialization is complete.\n *\n * @remarks\n * Implementations should ensure that the target is fully ready for later\n * operations after this method completes.\n *\n * @see {@link disconnect} for cleaning up the target environment.\n * @since 1.0.0\n */\n\n initTarget?(): Promise<void>;\n\n /**\n * Frees resources and cleans up the target.\n *\n * @returns A `Promise` that resolves when all resources have been freed.\n *\n * @remarks\n * This abstract method must be implemented by subclasses of `AbstractTarget`.\n * It should handle all necessary teardown and resource releases associated with the target,\n * ensuring a clean shutdown and preventing resource leaks.\n *\n * @see {@link disconnect} for terminating the target's active connections.\n * @since 1.0.0\n */\n\n freeTarget?(): Promise<void>;\n\n /**\n * Resolves a human-readable runner name for a given runner identifier.\n *\n * @param runnerId - Identifier of the runner\n *\n * @since 1.0.0\n */\n\n abstract getRunnerName(runnerId: string): string;\n\n /**\n * Retrieves all registered runners for the target.\n *\n * @returns An array of {@link RunnerInterface} instances representing all active runners.\n *\n * @remarks\n * Each runner represents a test execution context. Implementations of this method should\n * return all currently available runners, whether they are local or external.\n *\n * @see RunnerInterface\n * @since 1.0.0\n */\n\n abstract getRunners(): Array<RunnerInterface>;\n\n /**\n * Executes the provided test or transpiled suites on this target.\n *\n * @param transpileSuites - The transpiled suite files to execute.\n * @param suites - A record mapping original file names to their content.\n *\n * @returns A `Promise` that resolves once all suites have been executed.\n *\n * @remarks\n * This abstract method must be implemented by subclasses of `AbstractTarget`.\n * It should handle the execution of all provided suites, applying them to the\n * target environment and using the corresponding original files as needed.\n *\n * Implementations may include:\n * - Transpiling or preparing files for execution\n * - Running tests or suites in the target environment\n * - Collecting and reporting results or errors\n *\n * @see {@link initTarget}, {@link disconnect}, {@link freeTarget} for target lifecycle methods.\n *\n * @since 1.0.0\n */\n\n abstract executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void>;\n\n /**\n * Subscribe to log events emitted during test execution.\n *\n * @remarks\n * These logs correspond to runtime messages (`console.log`, `console.info`,\n * `console.warn`, `console.error`, etc.) generated inside tests, describe\n * blocks, or hooks. The listener receives the decoded log packet\n * ({@link DecodedPacketType} with {@link PacketKind.Log})\n * along with the test file path.\n *\n * @param key - Must be `'log'`.\n * @param listener - A handler invoked with the decoded log packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketLogInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'log', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Log>, string ]>): this;\n\n /**\n * Subscribe to fatal suite error events.\n *\n * @remarks\n * These errors occur at the suite level and are **not** tied to individual\n * tests, describe blocks, or hooks. The listener receives the decoded error\n * packet ({@link DecodedPacketType} with {@link PacketKind.Error})\n * along with the test file path.\n *\n * @param key - Must be `'error'`.\n * @param listener - A handler invoked with the decoded error packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketErrorInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'error', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Error>, string ]>): this;\n\n /**\n * Subscribe to test or describe completion events.\n *\n * @remarks\n * These events are emitted when a test or describe block **finishes execution**.\n * Skipped and TODO tests are excluded. The listener receives the decoded events\n * packet ({@link DecodedPacketType} with {@link PacketKind.Events})\n * along with the test file path.\n *\n * @param key - Must be `'events'`.\n * @param listener - A handler invoked with the decoded events packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketEventsInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'events', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Events>, string ]>): this;\n\n /**\n * Subscribe to test or describe status updates.\n *\n * @remarks\n * These events are emitted when a test or describe block **starts**, is\n * **skipped**, or marked as **TODO**. The listener receives the decoded\n * status packet ({@link DecodedPacketType} with {@link PacketKind.Status})\n * along with the originating test file path.\n *\n * @param key - Must be `'status'`.\n * @param listener - A handler invoked with the decoded status packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketStatusInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'status', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Status>, string ]>): this;\n\n /**\n * Generic listener registration.\n *\n * @param key - Event name\n * @param listener - The listener function\n *\n * @since 1.0.0\n */\n\n on(key: string | symbol, listener: FunctionType): this {\n this.eventEmitter.on(key, listener);\n\n return this;\n }\n\n /**\n * Marks a test suite as complete and resolves or rejects its associated promise.\n *\n * @remarks\n * This method is called when a suite finishes execution or encounters a fatal error.\n * - If `hasError` is `true` and the configuration has `bail` enabled, all remaining tasks in the queue are stopped\n * and the suite's promise is rejected.\n * - Otherwise, the suite's promise is resolved normally.\n *\n * After completion, the suite is removed from the `runningSuites` map.\n *\n * @param suiteId - The unique identifier of the test suite.\n * @param hasError - Whether the suite encountered a fatal error. Defaults to `false`.\n *\n * @since 1.0.0\n */\n\n completeSuite(suiteId: string, hasError = false): void {\n const suiteContext = this.runningSuites.get(suiteId);\n if (!suiteContext) {\n return;\n }\n\n this.runningSuites.delete(suiteId);\n if (hasError && this.config.bail) {\n this.queue.stop();\n this.queue.clear();\n suiteContext.reject();\n } else {\n suiteContext.resolve();\n }\n }\n\n /**\n * Processes a raw packet buffer received from a runner and emits the corresponding event.\n *\n * @param buffer - The raw buffer containing the encoded packet.\n *\n * @throws xJetError - If the packet belongs to an unregistered suite or has an invalid kind.\n *\n * @remarks\n * The method decodes the packet using the schema defined in {@link PacketSchemas} and routes it\n * to the appropriate event based on its kind:\n * - `PacketKind.Log` \u2192 emits a `'log'` event\n * - `PacketKind.Error` \u2192 marks the suite as complete with an error and emits an `'error'` event\n * - `PacketKind.Status` \u2192 emits a `'status'` event (for start, skip, or TODO)\n * - `PacketKind.Events` \u2192 emits an `'events'` event (for test/describe end that is not skipped or TODO)\n *\n * If the packet's `suiteId` is not registered in the `suites` map, an {@link xJetError} is thrown.\n * Any unknown `kind` also results in an {@link xJetError}.\n *\n * @since 1.0.0\n */\n\n protected dispatch(buffer: Buffer): void {\n const data = decodePacket(buffer);\n const suitePath = this.suites.get(data.suiteId);\n if (!suitePath) throw new xJetError(\n `Runner '${ data.runnerId }' in test suite '${ data.suiteId }' is not registered`\n );\n\n switch (data.kind) {\n case PacketKind.Log:\n this.eventEmitter.emit('log', data, suitePath);\n break;\n\n case PacketKind.Error:\n this.completeSuite(data.runnerId + data.suiteId, true);\n this.eventEmitter.emit('error', data, suitePath);\n break;\n\n case PacketKind.Status:\n this.eventEmitter.emit('status', data, suitePath);\n break;\n\n case PacketKind.Events:\n this.eventEmitter.emit('events', data, suitePath);\n break;\n\n default:\n const errorMessage = `Invalid schema type '${ data.kind }' detected for runner '${ data.runnerId }' in test suite '${ data.suiteId }'`;\n throw new xJetError(errorMessage);\n }\n }\n\n /**\n * Generates a pseudo-random alphanumeric identifier.\n *\n * @returns A pseudo-random alphanumeric string.\n *\n * @remarks\n * The ID is composed of two concatenated random strings, each derived from\n * `Math.random()` and converted to base-36, then truncated to 7 characters.\n * This method is typically used to create unique identifiers for suites,\n * runners, or tasks at runtime. Note that the IDs are not cryptographically secure.\n *\n * @since 1.0.0\n */\n\n protected generateId(): string {\n return Math.random().toString(36).substring(2, 9) + Math.random().toString(36).substring(2, 9);\n }\n\n /**\n * Registers multiple suites in the target's internal map.\n *\n * @param suites - A record mapping suite name to their file paths.\n *\n * @remarks\n * This method clears any previously registered suites and adds the provided ones.\n * Each suite is stored in the internal `suites` map in two ways:\n * 1. They generated unique ID maps to the suite's file path.\n * 2. The original suite name maps to the generated ID.\n *\n * This allows suites to be accessed either by their unique ID or by their original name.\n * The suite content itself is not duplicated in memory; only references and IDs are stored.\n *\n * @example\n * ```ts\n * this.setSuites({\n * \"loginTests\": \"/path/to/login.spec.ts\",\n * \"signupTests\": \"/path/to/signup.spec.ts\"\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n protected setSuites(suites: Record<string, string>): void {\n this.suites.clear();\n if(!suites) throw new xJetError(\n 'Suites must be provided to register them in the target'\n );\n\n for (const [ suiteName, path ] of Object.entries(suites)) {\n const id = this.generateId();\n this.suites.set(id, path);\n this.suites.set(suiteName, id);\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { PacketHeaderInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { DecodedPacketType, PacketPayloadMapType } from '@packets/interfaces/packets.interface';\n\n/**\n * Imports\n */\n\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\nimport { errorSchema, headerSchema } from '@packets/schema/packet.schema';\nimport { PacketSchemas } from '@packets/constants/packet-schema.constants';\n\n/**\n * Exports constants\n */\n\nexport * from '@packets/constants/packet-schema.constants';\n\n/**\n * Exports interfaces\n */\n\nexport * from '@packets/interfaces/packets.interface';\nexport * from '@packets/interfaces/packet-schema.interface';\n\n/**\n * Encodes a packet of a given kind into a `Buffer`.\n *\n * @template T - The packet kind (`PacketKind.Log`, `PacketKind.Error`, `PacketKind.Status`, or `PacketKind.Events`)\n *\n * @param kind - The type of packet to encode\n * @param data - Partial data matching the packet type; will be combined with header information\n *\n * @returns A `Buffer` containing the serialized packet\n *\n * @throws Error if the provided `kind` does not correspond to a known packet schema\n *\n * @remarks\n * This function combines a header and the payload according to the packet kind.\n * The header includes the suite ID, runner ID, and a timestamp.\n *\n * @since 1.0.0\n */\n\nexport function encodePacket<T extends PacketKind>(kind: T, data: Partial<PacketPayloadMapType[T]>): Buffer {\n const schema = PacketSchemas[kind];\n if (!schema) throw new Error(`Invalid schema kind: ${ kind }`);\n\n const header: PacketHeaderInterface = {\n kind: kind,\n suiteId: globalThis?.__XJET?.runtime?.suiteId ?? '',\n runnerId: globalThis?.__XJET?.runtime.runnerId ?? '',\n timestamp: (new Date()).toISOString()\n };\n\n return Buffer.concat([\n headerSchema.toBuffer(header),\n schema.toBuffer(data)\n ]);\n}\n\n/**\n * Decodes a packet from a `Buffer` into its corresponding object representation.\n *\n * @template T - The expected packet kind (`PacketKind.Log`, `PacketKind.Error`, `PacketKind.Status`, or `PacketKind.Events`)\n *\n * @param buffer - The buffer containing the encoded packet\n * @returns The decoded packet object, combining the header and payload fields\n *\n * @throws Error if the packet kind is unknown or invalid\n *\n * @remarks\n * Decodes both the header and payload based on the packet kind.\n *\n * @since 1.0.0\n */\n\nexport function decodePacket<T extends PacketKind>(buffer: Buffer): DecodedPacketType<T> {\n let offset = headerSchema.size;\n const header = headerSchema.toObject(buffer, (dynamicOffset: number): void => {\n offset += dynamicOffset;\n });\n\n const type = header.kind as PacketKind;\n const schema = PacketSchemas[type];\n if (!schema) {\n throw new Error(`Unknown packet kind: ${ type }`);\n }\n\n const dataBuffer = buffer.subarray(offset);\n const data = schema.toObject(dataBuffer) as PacketPayloadMapType[T];\n\n return { ...header, ...data };\n}\n\n/**\n * Encodes an {@link Error} instance into a binary buffer following the packet schema.\n *\n * @param error - The error object to be serialized and encoded.\n * @param suiteId - Identifier of the suite where the error occurred.\n * @param runnerId - Identifier of the runner reporting the error.\n *\n * @returns A {@link Buffer} containing the encoded error packet, ready for transmission.\n *\n * @remarks\n * The function creates two binary sections:\n * - A **header**, describing the packet kind (`Error`), suite ID, runner ID, and timestamp.\n * - A **data buffer**, holding the serialized error details in JSON format.\n *\n * These two sections are concatenated into a single buffer.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Test failed\");\n * } catch (err) {\n * const buffer = encodeErrorSchema(err, \"suite-123\", \"runner-456\");\n * socket.send(buffer); // transmit over a transport channel\n * }\n * ```\n *\n * @see serializeError\n * @see PacketKind.Error\n *\n * @since 1.0.0\n */\n\nexport function encodeErrorSchema(error: Error, suiteId: string, runnerId: string): Buffer {\n const header = headerSchema.toBuffer({\n kind: PacketKind.Error,\n suiteId: suiteId ?? '',\n runnerId: runnerId ?? '',\n timestamp: (new Date()).toISOString()\n });\n\n const dataBuffer = errorSchema.toBuffer({\n error: JSON.stringify(serializeError(error))\n });\n\n return Buffer.concat([ header, dataBuffer ]);\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { PacketLogInterface, PacketStatusInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { PacketErrorInterface, PacketEventsInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { PacketHeaderInterface, PacketInvocationInterface } from '@packets/interfaces/packet-schema.interface';\n\n/**\n * Imports\n */\n\nimport { Struct } from '@remotex-labs/xstruct';\n\n/**\n * Schema for serializing and deserializing {@link PacketInvocationInterface} data.\n *\n * @remarks\n * Represents the location in source code where a test, describe, or log originates.\n *\n * @since 1.0.0\n */\n\nexport const invocationSchema = new Struct<PacketInvocationInterface>({\n line: 'UInt32LE',\n column: 'UInt32LE',\n source: 'string'\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketHeaderInterface} data.\n *\n * @remarks\n * Contains metadata for each packet, including kind, suite and runner identifiers, and timestamp.\n *\n * @since 1.0.0\n */\n\nexport const headerSchema = new Struct<PacketHeaderInterface>({\n kind: 'UInt8:4',\n suiteId: { type: 'string', size: 14 },\n runnerId: { type: 'string', size: 14 },\n timestamp: 'string'\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketLogInterface} data.\n *\n * @remarks\n * Used for console-like logs emitted by tests or describes, including message, level, ancestry, and invocation.\n *\n * @since 1.0.0\n */\n\nexport const logSchema = new Struct<PacketLogInterface>({\n level: 'UInt8',\n message: { type: 'string', lengthType: 'UInt32LE' },\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n invocation: invocationSchema\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketErrorInterface} data.\n *\n * @remarks\n * Represents suite-level fatal errors that are not tied to specific tests or describes.\n *\n * @since 1.0.0\n */\n\nexport const errorSchema = new Struct<PacketErrorInterface>({\n error: { type: 'string', lengthType: 'UInt32LE' }\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketStatusInterface} data.\n *\n * @remarks\n * Represents status updates for individual tests or describe blocks,\n * including whether it is TODO, skipped, and its ancestry and description.\n *\n * @since 1.0.0\n */\n\nexport const statusSchema = new Struct<PacketStatusInterface>({\n type: 'UInt8:5',\n todo: 'UInt8:1',\n skipped: 'UInt8:1',\n duration: 'UInt32LE',\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n description: { type: 'string', lengthType: 'UInt32LE' }\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketEventsInterface} data.\n *\n * @remarks\n * Represents events emitted during the test or describe execution,\n * including pass/fail status, duration, error messages, ancestry, and invocation.\n *\n * @since 1.0.0\n */\n\nexport const eventsSchema = new Struct<PacketEventsInterface>({\n type: 'UInt8:5',\n passed: 'UInt8:1',\n duration: 'UInt32LE',\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n description: { type: 'string', lengthType: 'UInt32LE' },\n errors: { type: 'string', lengthType: 'UInt32LE' }\n});\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Struct } from '@remotex-labs/xstruct';\n\n/**\n * Imports\n */\n\nimport { errorSchema, eventsSchema, logSchema, statusSchema } from '@packets/schema/packet.schema';\n\n/**\n * Defines the different kinds of packets that can be transmitted or received.\n *\n * @remarks\n * Each packet kind corresponds to a specific type of event or message in the test framework:\n * - `Log`: Console or logging messages\n * - `Error`: Suite-level fatal errors\n * - `Status`: Test or describe start events, including `skipped` and `todo` flags\n * - `Events`: Test or describe end events, only for completed tests/describes (no skipped or TODO)\n *\n * @since 1.0.0\n */\n\nexport const enum PacketKind {\n /**\n * Represents a log message packet, e.g., `console.log`, `console.error`.\n * @since 1.0.0\n */\n\n Log = 1,\n\n /**\n * Represents a fatal suite-level error.\n * Not associated with any test, describe, or hook.\n * @since 1.0.0\n */\n\n Error = 2,\n\n /**\n * Represents a status packet for test or describe start events.\n *\n * @remarks\n * Includes flags for:\n * - `skipped`: Whether the test or describe was skipped\n * - `todo`: Whether the test is marked as TODO\n *\n * @since 1.0.0\n */\n\n Status = 3,\n\n /**\n * Represents an event packet for test or describe end events.\n *\n * @remarks\n * Only includes completed tests/describes; skipped or TODO tests are not included.\n * Contains information such as `passed` and `duration`.\n *\n * @since 1.0.0\n */\n\n Events = 4\n}\n\n/**\n * Maps each {@link PacketKind} to its corresponding {@link Struct} schema for serialization/deserialization.\n *\n * @remarks\n * This object allows encoding and decoding packets of different kinds using\n * their respective `xStruct` schemas. Use `PacketSchemas[PacketKind.Log]` to\n * get the schema for log packets, etc.\n *\n * @see PacketKind\n * @see Struct\n *\n * @since 1.0.0\n */\n\nexport const PacketSchemas: Record<PacketKind, Struct> = {\n [PacketKind.Log]: logSchema,\n [PacketKind.Error]: errorSchema,\n [PacketKind.Status]: statusSchema,\n [PacketKind.Events]: eventsSchema\n} as const;\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TaskInterface } from '@services/interfaces/queue-service.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable } from '@symlinks/services/inject.service';\n\n/**\n * A service that manages asynchronous tasks with configurable concurrency.\n *\n * @remarks\n * This queue allows tasks to be enqueued and executed with a limit on the number of\n * concurrently running tasks. Tasks can be paused, resumed, cleared, or removed by runner ID.\n *\n * @example\n * ```ts\n * const queue = new QueueService(2);\n * queue.start();\n * queue.enqueue(async () => {\n * console.log(\"Task executed\");\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class QueueService {\n /**\n * Controls whether the queue processing is active or paused\n * @since 1.0.0\n */\n\n private paused = true;\n\n /**\n * Tracks the number of tasks currently being executed\n * @since 1.0.0\n */\n\n private activeCount = 0;\n\n /**\n * Maximum number of tasks that can execute concurrently\n * @since 1.0.0\n */\n\n private readonly concurrencyLimit: number;\n\n /**\n * Contains the pending tasks waiting to be processed\n * @since 1.0.0\n */\n\n private queue: Array<TaskInterface> = [];\n\n /**\n * Creates a new QueueService instance.\n *\n * @param concurrencyLimit - Maximum number of concurrent tasks (defaults to 1 if non-positive)\n * @default concurrencyLimit - 1\n *\n * @since 1.0.0\n */\n\n constructor(concurrencyLimit?: number) {\n this.concurrencyLimit = concurrencyLimit && concurrencyLimit > 0 ? concurrencyLimit : 1;\n }\n\n /**\n * Returns the number of tasks currently in the queue.\n *\n * @returns The number of pending tasks\n * @since 1.0.0\n */\n\n get size(): number {\n return this.queue.length;\n }\n\n /**\n * Returns the number of tasks currently running.\n *\n * @returns The number of active tasks\n * @since 1.0.0\n */\n\n get running(): number {\n return this.activeCount;\n }\n\n /**\n * Returns whether the queue is currently paused.\n *\n * @returns `true` if the queue is paused, otherwise `false`\n * @since 1.0.0\n */\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n /**\n * Pauses the processing of the queue.\n *\n * @since 1.0.0\n */\n\n stop(): void {\n this.paused = true;\n }\n\n /**\n * Resumes processing of the queue if it was paused.\n *\n * @since 1.0.0\n */\n\n start(): void {\n if (this.paused) {\n this.paused = false;\n // Start processing queue tasks again\n this.processQueue();\n }\n }\n\n /**\n * Clears all pending tasks from the queue and rejects their promises.\n *\n * @returns The number of tasks that were removed\n * @since 1.0.0\n */\n\n clear(): number {\n const count = this.queue.length;\n\n this.queue.forEach(taskItem => {\n if ('reject' in taskItem) {\n taskItem.reject();\n }\n });\n\n this.queue = [];\n\n return count;\n }\n\n /**\n * Adds a task to the queue and returns a promise for its result.\n *\n * @template T - The type of value that the task resolves to\n * @param task - A function returning a promise representing the asynchronous task\n * @param runnerId - Optional identifier for the runner executing this task\n *\n * @returns A promise that resolves or rejects with the task's result\n *\n * @see {@link TaskInterface}\n * @since 1.0.0\n */\n\n enqueue<T>(task: () => Promise<T>, runnerId?: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n // Wrap the task to handle its completion\n const wrappedTask = async (): Promise<void> => {\n try {\n const result = await task();\n resolve(result);\n } catch (error) {\n reject(error);\n } finally {\n this.activeCount--;\n this.processQueue();\n }\n };\n\n this.queue.push({ task: wrappedTask, runnerId, reject, resolve });\n if (!this.paused) {\n this.processQueue();\n }\n });\n }\n\n /**\n * Removes all tasks associated with a specific runner ID.\n *\n * @param runnerId - The ID of the runner whose tasks should be removed\n *\n * @returns The number of tasks removed\n * @since 1.0.0\n */\n\n removeTasksByRunner(runnerId: string): number {\n const initialCount = this.queue.length;\n this.queue = this.queue.filter(item => item.runnerId !== runnerId);\n\n return initialCount - this.queue.length;\n }\n\n /**\n * Processes tasks in the queue according to the concurrency limit.\n *\n * @since 1.0.0\n */\n\n private processQueue(): void {\n if (this.paused) {\n return;\n }\n\n while (this.activeCount < this.concurrencyLimit && this.queue.length > 0) {\n const item = this.queue.shift();\n if (item) {\n this.activeCount++;\n item.task();\n }\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { TestRunnerInterface } from '@configuration/interfaces/configuration.interface';\nimport type { RunnerInterface, RuntimeConfigInterface } from '@targets/interfaces/traget.interface';\n\n/**\n * Imports\n */\nimport yargs from 'yargs';\nimport { pathToFileURL } from 'url';\nimport { dirname, relative } from 'path';\nimport { xJetError } from '@errors/xjet.error';\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { withTimeout } from '@components/timeout.component';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { AbstractTarget } from '@targets/abstract/target.abstract';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Implementation of a test execution target that runs tests in external runners.\n *\n * @remarks\n * The `ExternalService` coordinates test execution across external processes or environments.\n * It connects to configured test runners, dispatches test code, and manages their lifecycle:\n * initialization (`initTarget`), execution (`executeSuites`), and cleanup (`freeTarget`).\n *\n * Unlike {@link LocalService}, which runs tests in a local sandbox, this class offloads execution\n * to one or more external runners (e.g., browser, VM, or remote environment).\n *\n * @example\n * ```ts\n * const config = {\n * testRunners: [\n * { name: 'chrome', connection: connectChromeRunner, connectionTimeout: 5000 }\n * ]\n * };\n *\n * const externalTarget = new ExternalService(config);\n * await externalTarget.initTarget();\n * await externalTarget.executeSuites(transpileFiles, originalFiles);\n * await externalTarget.freeTarget();\n * ```\n *\n * @see LocalService\n * @see AbstractTarget\n * @see TestRunnerInterface\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ExternalService extends AbstractTarget {\n /**\n * A map of all registered test runners.\n *\n * @remarks\n * The key is the unique runner ID (generated internally), and the value is\n * the corresponding `TestRunnerInterface` instance. This map tracks all\n * runners connected to this target and is used to dispatch test suites\n * during execution.\n *\n * @example\n * ```ts\n * for (const [id, runner] of externalService.runners) {\n * console.log(`Runner ${runner.name} has ID: ${id}`);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n readonly runners: Map<string, TestRunnerInterface> = new Map();\n\n /**\n * Initializes all configured external test runners.\n *\n * @throws xJetError - If no test runners are configured.\n *\n * @remarks\n * This method sets up the target environment by connecting to each test runner\n * defined in the configuration (`this.config.testRunners`). It also parses\n * optional CLI arguments provided via `this.config.userArgv` using `yargs`.\n *\n * All runner connections are initiated concurrently using `Promise.allSettled`\n * to ensure the target attempts to connect to every runner, even if some fail.\n *\n * @example\n * ```ts\n * await externalService.initTarget();\n * // All configured runners are now connected and ready to execute suites\n * ```\n *\n * @since 1.0.0\n */\n\n async initTarget(): Promise<void> {\n if (!this.config.testRunners || this.config.testRunners.length === 0)\n throw new xJetError('No test runners configured');\n\n let argv: Record<string, unknown> = {};\n if (this.config.userArgv) {\n argv = yargs(process.argv.slice(2))\n .options(this.config.userArgv)\n .parseSync();\n }\n\n await Promise.all(\n this.config.testRunners.map(runner => this.connectRunner(runner, argv))\n );\n }\n\n /**\n * Frees all resources associated with the target.\n *\n * @remarks\n * This method disconnects all registered test runners by calling their\n * `disconnect` method (if available). It is intended to be called when the\n * target is no longer needed, ensuring a clean shutdown and preventing\n * resource leaks.\n *\n * Disconnections are performed concurrently using `Promise.allSettled` so\n * that all runners are attempted even if some fail to disconnect.\n *\n * @example\n * ```ts\n * await externalService.freeTarget();\n * // All connected runners are now disconnected\n * ```\n *\n * @see {@link initTarget} to initialize runners before execution.\n * @see {@link executeSuites} for running suites on the connected runners.\n *\n * @since 1.0.0\n */\n\n async freeTarget(): Promise<void> {\n const disconnectionPromises = [];\n const runners = Array.from(this.runners.values());\n\n for (let i = 0; i < runners.length; i++) {\n const runner = runners[i];\n if (runner?.disconnect) {\n disconnectionPromises.push(runner?.disconnect?.());\n }\n }\n\n await Promise.allSettled(disconnectionPromises);\n }\n\n /**\n * Returns the name of a registered runner given its ID.\n *\n * @param runnerId - The unique ID of the runner.\n * @returns The name of the runner associated with the given ID.\n *\n * @throws xJetError - If no runner with the specified ID exists.\n *\n * @remarks\n * The `runnerId` corresponds to the internally generated ID assigned\n * to each runner when it was connected via `initTarget`.\n *\n * @example\n * ```ts\n * const runnerName = externalService.getRunnerName('runner-123');\n * console.log(runnerName); // e.g., \"chrome\"\n * ```\n *\n * @since 1.0.0\n */\n\n getRunnerName(runnerId: string): string {\n const name = this.runners.get(runnerId)?.name;\n if (!name) {\n throw new xJetError(`Runner with ID \"${ runnerId }\" not found`);\n }\n\n return name;\n }\n\n /**\n * Returns a list of all registered runners with their IDs and names.\n *\n * @returns An array of objects each containing:\n * - `id`: The unique runner ID.\n * - `name`: The runner's name.\n *\n * @remarks\n * This method provides a simplified view of all connected runners without exposing\n * the full `TestRunnerInterface` details. It is useful for reporting or UI purposes.\n *\n * @example\n * ```ts\n * const runners = externalService.getRunners();\n * runners.forEach(runner => {\n * console.log(`Runner ID: ${runner.id}, Name: ${runner.name}`);\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n getRunners(): Array<RunnerInterface> {\n return Array.from(this.runners.values()).map(runner => ({\n id: runner.id!,\n name: runner.name\n }));\n }\n\n /**\n * Executes the provided transpiled test suites on all registered runners.\n *\n * @param transpileSuites - An array of transpiled test files to execute.\n * @param suites - A record mapping original suite names to their file paths.\n *\n * @remarks\n * This method registers the provided suites internally via `setSuites` and\n * queues each transpiled suite for execution on every connected runner.\n *\n * Each suite is executed asynchronously, and errors are handled internally\n * without halting the execution of other suites.\n *\n * The `queue` ensures that execution tasks are managed per runner, preventing\n * race conditions and allowing controlled concurrency.\n *\n * After all tasks are queued, the queue is started and the method waits\n * for all execution tasks to settle using `Promise.allSettled`.\n *\n * @example\n * ```ts\n * await externalService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see {@link setSuites} to register suites for execution.\n * @see {@link executeTestWithErrorHandling} for individual test execution logic.\n *\n * @since 1.0.0\n */\n\n async executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void> {\n this.setSuites(suites);\n const testExecutionTasks: Array<Promise<void>> = [];\n\n for (const transpile of transpileSuites) {\n const relativePath = relative(this.framework.rootPath, transpile.path)\n .replace(/\\.[^/.]+$/, '');\n\n this.runners.forEach((runner: TestRunnerInterface, id: string) => {\n testExecutionTasks.push(this.queue.enqueue(async () => {\n return this.executeTestWithErrorHandling(transpile.code, relativePath, runner);\n }, id));\n });\n }\n\n this.queue.start();\n await Promise.allSettled(testExecutionTasks);\n }\n\n /**\n * Connects a single test runner and registers it in the internal map.\n *\n * @param runner - The test runner configuration to connect.\n * @param argv - Optional CLI arguments to pass to the runner during connection.\n *\n * @remarks\n * A unique ID is generated for the runner and assigned to `runner.id`.\n * The runner's `connection` method is called with a dispatch function, its ID,\n * and any provided arguments. The connection attempt is wrapped in a timeout\n * using `withTimeout` (defaulting to 5000 ms if `runner.connectionTimeout` is not set).\n *\n * If the connection succeeds, the runner is added to the `runners` map. If it fails,\n * the error is caught and logged as a `VMRuntimeError` without throwing,\n * allowing other runners to continue connecting.\n *\n * @example\n * ```ts\n * await this.connectRunner(runnerConfig, { verbose: true });\n * ```\n *\n * @since 1.0.0\n */\n\n private async connectRunner(runner: TestRunnerInterface, argv: Record<string, unknown>): Promise<void> {\n runner.id = this.generateId();\n await withTimeout(\n runner.connect(this.dispatch.bind(this), runner.id!, argv),\n runner?.connectionTimeout ?? 5000,\n `connection of runner \"${ runner.name }\"`\n );\n\n this.runners.set(runner.id, runner);\n }\n\n /**\n * Executes a single test suite on a runner with error handling.\n *\n * @param testCode - The transpiled test code to execute.\n * @param relativePath - The relative path of the test file, used to look up the suite ID.\n * @param runner - The test runner instance that will execute the suite.\n *\n * @returns A `Promise` that resolves when the suite has been executed or fails gracefully.\n *\n * @remarks\n * This method wraps the execution of a test suite in a `Promise` and tracks\n * it in the `runningSuites` map using the suite ID. If `executeInRunner`\n * throws an error, the suite is marked as complete with failure, and an\n * 'error' event is emitted via the `eventEmitter`.\n *\n * The emitted error includes:\n * - `kind`: The packet type (`PacketKind.Error`)\n * - `error`: The serialized error object\n * - `suiteId`: The unique ID of the suite\n * - `runnerId`: The ID of the runner that executed the suite\n *\n * @example\n * ```ts\n * await this.executeTestWithErrorHandling(testCode, \"tests/login.spec.ts\", runner);\n * ```\n *\n * @since 1.0.0\n */\n\n private executeTestWithErrorHandling(testCode: string, relativePath: string, runner: TestRunnerInterface): Promise<void> {\n const suiteId = this.suites.get(relativePath)!;\n\n return new Promise<void>(async (resolve, reject) => {\n try {\n this.runningSuites.set(runner.id + suiteId, { resolve, reject });\n await this.executeInRunner(testCode, suiteId, runner);\n } catch (error) {\n this.completeSuite(runner.id + suiteId, true);\n this.eventEmitter.emit('error', {\n kind: PacketKind.Error,\n error: JSON.stringify(serializeError(error)),\n suiteId: suiteId,\n runnerId: runner.id,\n timestamp: new Date()\n }, this.suites.get(suiteId)!);\n }\n });\n }\n\n /**\n * Dispatches a test suite to a runner with an injected runtime context.\n *\n * @param testCode - The transpiled test code to execute.\n * @param suiteId - The unique ID of the suite.\n * @param runner - The test runner instance that will execute the suite.\n *\n * @throws Throws a timeout error if the runner's dispatch does not complete in time.\n *\n * @remarks\n * This method prepares the test code by injecting runtime context (bail, path, filter,\n * timeout, suiteId, runnerId, randomization) using `prepareTestCodeWithContext`.\n * The prepared code is then dispatched to the runner via its `dispatch` method,\n * wrapped in a timeout using `withTimeout` (defaulting to 5000 ms if `runner.dispatchTimeout` is not set).\n *\n * The `suiteId` is used both for looking up the original file path in `suites` and for\n * identifying the suite during dispatch.\n *\n * @example\n * ```ts\n * await this.executeInRunner(testCode, suiteId, runner);\n * ```\n *\n * @since 1.0.0\n */\n\n private async executeInRunner(testCode: string, suiteId: string, runner: TestRunnerInterface): Promise<void> {\n const runtimeContext: Record<string, RuntimeConfigInterface> = {\n runtime: {\n bail: this.config.bail,\n path: this.suites.get(suiteId)!,\n filter: this.config.filter,\n timeout: this.config.timeout,\n suiteId: suiteId,\n runnerId: runner.id!,\n randomize: this.config.randomize\n }\n };\n\n const preparedTestCode = this.prepareTestCodeWithContext(testCode, runtimeContext);\n await withTimeout(\n runner?.dispatch?.(Buffer.from(preparedTestCode), suiteId),\n runner?.dispatchTimeout ?? 5000,\n `dispatch of runner \"${ runner.name }\"`\n );\n }\n\n /**\n * Injects a runtime context into the test code.\n *\n * @param testCode - The original transpiled test code.\n * @param context - The runtime context to inject, including configuration and suite/runner metadata.\n *\n * @returns A string containing the test code with the injected `__XJET` context variable.\n *\n * @remarks\n * This method prepends the test code with a `const __XJET` declaration containing\n * the provided context. The runner can access this context during execution to\n * determine runtime options like `bail`, `timeout`, `suiteId`, `runnerId`, etc.\n *\n * The resulting code is suitable for direct dispatch to a test runner environment.\n *\n * @example\n * ```ts\n * const preparedCode = this.prepareTestCodeWithContext(testCode, {\n * runtime: { suiteId, runnerId, bail: true }\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n private prepareTestCodeWithContext(testCode: string, context: Record<string, RuntimeConfigInterface>): string {\n const __filename = context.runtime.path;\n const __dirname = dirname(__filename);\n\n return `globalThis.import_meta = { url: \"${ pathToFileURL(__filename) }\", dirname: \"${ __dirname }\", filename: \"${ __filename }\" };` +\n `__dirname=${ JSON.stringify(__dirname) };` +\n `__filename=${ JSON.stringify(__filename) };` +\n `globalThis.__XJET = ${ JSON.stringify(context) }; ${ testCode }`;\n }\n}\n", "export class TimeoutError extends Error {\n constructor(timeout: number, at: string, stack: string = '') {\n super(`Exceeded timeout of ${ timeout } ms at ${ at }`);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'xJetTimeoutError';\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n\n this.name = 'xJetFailingError';\n if(stack) {\n this.stack = `${ this.name }: ${ this.message }\\n${ stack }`;\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { FunctionLikeType } from '@remotex-labs/xjet-expect';\nimport type { TimerInterface } from '@shared/services/interfaces/timer-service.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable, inject } from '@symlinks/services/inject.service';\n\n/**\n * Provides a virtual timer system that mimics native `setTimeout`/`setInterval`\n * while allowing controlled execution for deterministic tests.\n *\n * @remarks\n * This service replaces the global timing functions with fake timers so that\n * time can be manually advanced and callbacks triggered predictably.\n * It is intended for unit testing scenarios where you need full control over\n * asynchronous timing without waiting in real time.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 1000);\n * advanceTimersByTime(1000); // logs 'done' immediately\n * useRealTimers();\n * ```\n *\n * @since 1.1.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class TimerService {\n /**\n * Active timers managed by the fake timer engine.\n * @since 1.1.0\n */\n\n readonly timers = new Map<number, TimerInterface>();\n\n /**\n * Stores original `Date.now` to restore when real timers are re-enabled.\n * @since 1.1.0\n */\n\n readonly originalDateNow = Date.now;\n\n /**\n * Stores original global `setTimeout`.\n * @since 1.1.0\n */\n\n readonly originalSetTimeout = globalThis.setTimeout;\n\n /**\n * Stores original global `setInterval`.\n * @since 1.1.0\n */\n\n readonly originalSetInterval = globalThis.setInterval;\n\n /**\n * Stores original global `clearTimeout`.\n * @since 1.1.0\n */\n\n readonly originalClearTimeout = globalThis.clearTimeout;\n\n /**\n * Stores original global `clearInterval`.\n * @since 1.1.0\n */\n\n readonly originalClearInterval = globalThis.clearInterval;\n\n /**\n * Simulated current timestamp for the fake timers.\n * @since 1.1.0\n */\n\n private now = 0;\n\n /**\n * Incremental id used to register timers uniquely.\n * @since 1.1.0\n */\n\n private nextId = 1;\n\n /**\n * Replaces the global timer functions with in-memory fakes.\n *\n * @remarks\n * After calling this method, any calls to `setTimeout`, `setInterval`,\n * `clearTimeout`, or `clearInterval` will be intercepted and stored in the\n * {@link timers} map instead of scheduling real OS timers.\n * This allows tests to control time progression manually using\n * {@link advanceTimersByTime}, {@link runAllTimers}, or\n * {@link runOnlyPendingTimers}.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * const id = setTimeout(() => console.log('done'), 1000);\n * timerService.advanceTimersByTime(1000); // logs \"done\" immediately\n * ```\n *\n * @since 1.1.0\n */\n\n useFakeTimers(): void {\n const setTimeout = (cb: FunctionLikeType<void>, delay: number = 0, ...args: Array<unknown>): number => {\n const id = this.nextId++;\n this.timers.set(id, { id, callback: cb, time: this.now + delay, interval: null, args: args ?? [] });\n\n return id;\n };\n\n const setInterval = (cb: FunctionLikeType<void>, interval: number = 0): number => {\n const id = this.nextId++;\n this.timers.set(id, { id, callback: cb, time: this.now + interval, interval, args: [] });\n\n return id;\n };\n\n const clearTimeout = (id: number): void => {\n this.timers.delete(id);\n };\n\n\n const clearInterval = (id: number): void => {\n this.timers.delete(id);\n };\n\n const global = <Record<string, unknown>> globalThis;\n global.setTimeout = setTimeout;\n global.setInterval = setInterval;\n global.clearTimeout = clearTimeout;\n global.clearInterval = clearInterval;\n }\n\n /**\n * Restores the original global timer APIs and `Date.now`.\n *\n * @remarks\n * This method undoes the effects of {@link useFakeTimers}, re-binding\n * the native implementations of `setTimeout`, `setInterval`,\n * `clearTimeout`, `clearInterval`, and `Date.now`.\n * After calling this, timers once again behave according to real system\n * time and manual advancement methods such as\n * {@link advanceTimersByTime} no longer apply.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * // ...run tests with controlled time...\n * timerService.useRealTimers(); // restore native timers\n * ```\n *\n * @since 1.1.0\n */\n\n useRealTimers(): void {\n this.timers.clear();\n globalThis.setTimeout = this.originalSetTimeout;\n globalThis.clearTimeout = this.originalClearTimeout;\n globalThis.setInterval = this.originalSetInterval;\n globalThis.clearInterval = this.originalClearInterval;\n Date.now = this.originalDateNow;\n }\n\n /**\n * Clears all active fake timers.\n *\n * @remarks\n * This method removes every timer currently stored in {@link timers},\n * effectively resetting the fake timer state without advancing time.\n * It is useful for cleaning up between tests to ensure no lingering\n * scheduled callbacks remain.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * clearAllTimers(); // removes all scheduled timers\n * advanceTimersByTime(100); // nothing happens\n * ```\n *\n * @since 1.3.0\n */\n\n clearAllTimers(): void {\n this.timers.clear();\n }\n\n /**\n * Advances the simulated clock by a specific number of milliseconds and\n * executes all timers whose scheduled time has elapsed.\n *\n * @remarks\n * Use this method after calling {@link useFakeTimers} to fast-forward the\n * internal clock without waiting in real time.\n * Any `setTimeout` or `setInterval` callbacks scheduled within the\n * advanced period will run immediately in order of their scheduled time.\n *\n * @param ms - The number of milliseconds to move the simulated time forward.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => console.log('done'), 500);\n * timerService.advanceTimersByTime(500); // logs \"done\"\n * ```\n *\n * @since 1.1.0\n */\n\n advanceTimersByTime(ms: number) : void {\n this.now += ms;\n this.runDueTimers();\n }\n\n /**\n * Executes every scheduled timer until none remain.\n *\n * @remarks\n * This method repeatedly advances the simulated clock to the next\n * scheduled timer and runs its callback until the {@link timers} map\n * is empty.\n * It is useful when you want to immediately flush **all** pending\n * `setTimeout` or `setInterval` callbacks regardless of their delay,\n * without specifying a time increment.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n * timerService.runAllTimers(); // logs \"A\" then \"B\"\n * ```\n *\n * @since 1.1.0\n */\n\n runAllTimers(): void {\n while (this.timers.size > 0) {\n this.now = Math.min(...Array.from(this.timers.values()).map(t => t.time));\n this.runDueTimers();\n }\n }\n\n /**\n * Executes only the timers that are currently pending at the time of call,\n * without running any new timers that may be scheduled by those callbacks.\n *\n * @remarks\n * Unlike {@link runAllTimers}, this method captures the set of timers\n * that exist when the method is invoked and restricts execution to that\n * initial set.\n * If any of those timers schedule additional timers while running,\n * the newly scheduled ones will **not** be executed during this call.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n *\n * timerService.runOnlyPendingTimers();\n * // Logs only \"first\" because \"second\" was created afterward.\n * ```\n *\n * @since 1.1.0\n */\n\n runOnlyPendingTimers(): void {\n const pendingTimers = new Set(this.timers.keys());\n\n while (pendingTimers.size > 0) {\n const nextTimerTimes = Array.from(this.timers.values())\n .filter(t => pendingTimers.has(t.id))\n .map(t => t.time);\n\n if (nextTimerTimes.length === 0) break;\n\n this.now = Math.min(...nextTimerTimes);\n this.runDueTimers(pendingTimers);\n\n for (const id of pendingTimers) {\n if (!this.timers.has(id)) pendingTimers.delete(id);\n }\n }\n }\n\n /**\n * Asynchronous equivalent of {@link runAllTimers}.\n *\n * @remarks\n * This method first yields to the event loop to allow any pending promises\n * to resolve before executing all remaining fake timers.\n * It ensures a deterministic sequence when timers and microtasks coexist.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * Promise.resolve().then(() => console.log('microtask'));\n * setTimeout(() => console.log('timer'), 0);\n * await timerService.runAllTimersAsync();\n * // Logs:\n * // microtask\n * // timer\n * ```\n *\n * @since 1.3.0\n */\n\n async runAllTimersAsync(): Promise<void> {\n await Promise.resolve();\n this.runAllTimers();\n }\n\n /**\n * Asynchronous equivalent of {@link runOnlyPendingTimers}.\n *\n * @remarks\n * This method first yields to the event loop to allow any pending promises\n * to resolve before executing only currently pending fake timers.\n * Timers scheduled during execution will not run until explicitly advanced later.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n * await timerService.runOnlyPendingTimersAsync();\n * // Logs:\n * // first\n * ```\n *\n * @since 1.3.0\n */\n\n async runOnlyPendingTimersAsync(): Promise<void> {\n await Promise.resolve();\n this.runOnlyPendingTimers();\n }\n\n /**\n * Executes all timers whose scheduled time is less than or equal to the\n * current simulated time (`this.now`).\n *\n * @remarks\n * This internal method is called by {@link advanceTimersByTime},\n * {@link runAllTimers}, and {@link runOnlyPendingTimers} to trigger\n * due timers.\n * If `limitTimers` are provided, only timers included in that set are executed.\n * Repeating timers (`setInterval`) are rescheduled automatically until\n * their next execution time exceeds the current simulated time.\n *\n * @param limitTimers - Optional set of timer IDs to restrict execution.\n *\n * @internal\n * @since 1.1.0\n */\n\n private runDueTimers(limitTimers?: Set<number>): void {\n let executed = true;\n while (executed) {\n executed = false;\n\n const timers = Array.from(this.timers.values()).sort((a, b) => a.time - b.time);\n\n for (const timer of timers) {\n if (!this.timers.has(timer.id)) continue;\n if (limitTimers && !limitTimers.has(timer.id)) continue;\n\n if (timer.time <= this.now) {\n if (timer.interval !== null) {\n while (timer.time <= this.now) {\n timer.callback();\n timer.time += timer.interval;\n }\n } else {\n timer.callback();\n this.timers.delete(timer.id);\n }\n executed = true;\n }\n }\n }\n }\n}\n\n/**\n * Globally enables fake timers using the shared {@link TimerService}.\n *\n * @remarks\n * After calling this function, all calls to `setTimeout`, `setInterval`,\n * `clearTimeout`, and `clearInterval` will be intercepted by the\n * {@link TimerService} and stored in-memory instead of executing in real time.\n * This allows deterministic testing by manually advancing time with\n * {@link advanceTimersByTime}, {@link runAllTimers}, or\n * {@link runOnlyPendingTimers}.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 1000);\n * advanceTimersByTime(1000); // logs \"done\" immediately\n * ```\n *\n * @since 1.1.0\n */\n\nexport function useFakeTimers(): void {\n inject(TimerService).useFakeTimers();\n}\n\n/**\n * Restores real timers globally using the shared {@link TimerService}.\n *\n * @remarks\n * This function undoes the effects of {@link useFakeTimers}, restoring the\n * native implementations of `setTimeout`, `setInterval`, `clearTimeout`,\n * `clearInterval`, and `Date.now`.\n * After calling this, timers once again behave according to real system time,\n * and manual advancement methods like {@link advanceTimersByTime} no longer apply.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * // ...run tests with controlled time...\n * useRealTimers(); // restore native timers\n * ```\n *\n * @since 1.1.0\n */\n\nexport function useRealTimers(): void {\n inject(TimerService).useRealTimers();\n}\n\n/**\n * Executes all timers currently registered in the {@link TimerService}.\n *\n * @remarks\n * This function repeatedly runs all pending `setTimeout` and `setInterval`\n * callbacks until no timers remain.\n * It is equivalent to calling {@link TimerService.runAllTimers} on the\n * injected service instance and is useful for immediately flushing\n * all scheduled timers in tests.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n * runAllTimers(); // logs \"A\" then \"B\"\n * ```\n *\n * @since 1.1.0\n */\n\nexport function runAllTimers(): void {\n inject(TimerService).runAllTimers();\n}\n\n/**\n * Removes all scheduled fake timers from the {@link TimerService}.\n *\n * @remarks\n * This function clears all active timers registered in the shared timer service,\n * effectively canceling any pending callbacks that would have run during\n * timer advancement.\n *\n * It's useful for resetting the fake timer state between test cases to ensure\n * no lingering timers affect further tests or for scenarios where you\n * need to abort all pending operations.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n *\n * clearAllTimers(); // removes all scheduled timers\n * advanceTimersByTime(1000); // nothing happens, not show any logs\n * ```\n *\n * @since 1.3.0\n */\n\nexport function clearAllTimers(): void {\n inject(TimerService).clearAllTimers();\n}\n\n/**\n * Executes only the timers that are pending at the time of invocation.\n *\n * @remarks\n * This function runs the callbacks of timers that exist when the function\n * is called, without executing any new timers that may be scheduled\n * during their execution.\n * It delegates to {@link TimerService.runOnlyPendingTimers} on the injected\n * service instance.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n *\n * runOnlyPendingTimers();\n * // Logs only \"first\"; \"second\" is not executed yet\n * ```\n *\n * @since 1.1.0\n */\n\nexport function runOnlyPendingTimers(): void {\n inject(TimerService).runOnlyPendingTimers();\n}\n\n/**\n * Advances the simulated time by a specified number of milliseconds and\n * executes all timers that are due.\n *\n * @remarks\n * This function delegates to {@link TimerService.advanceTimersByTime}\n * on the injected service instance.\n * It is intended to be used after {@link useFakeTimers} to fast-forward\n * time in tests without waiting for real timers.\n *\n * @param ms - The number of milliseconds to advance (default is `0`).\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 500);\n * advanceTimersByTime(500); // logs \"done\"\n * ```\n *\n * @since 1.1.0\n */\n\nexport function advanceTimersByTime(ms: number = 0): void {\n inject(TimerService).advanceTimersByTime(ms);\n}\n\n/**\n * Asynchronous equivalent of {@link runAllTimers}.\n *\n * @remarks\n * Yields to the event loop before running all pending fake timers.\n * Useful when working with both Promises and fake timers.\n *\n * @example\n * ```ts\n * xJet.useFakeTimers();\n * Promise.resolve().then(() => console.log('promise done'));\n * setTimeout(() => console.log('timeout done'), 0);\n * await xJet.runAllTimersAsync();\n * // Logs:\n * // promise done\n * // timeout done\n * ```\n *\n * @since 1.3.0\n */\n\nexport async function runAllTimersAsync(): Promise<void> {\n await inject(TimerService).runAllTimersAsync();\n}\n\n/**\n * Asynchronous equivalent of {@link runOnlyPendingTimers}.\n *\n * @remarks\n * Yields to the event loop before running only timers that are currently pending.\n * Any timers scheduled by those callbacks will not be executed until a later call.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n * await runOnlyPendingTimersAsync();\n * // Logs only \"first\"\n * ```\n *\n * @since 1.3.0\n */\n\nexport async function runOnlyPendingTimersAsync(): Promise<void> {\n await inject(TimerService).runOnlyPendingTimersAsync();\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { FunctionLikeType } from '@remotex-labs/xjet-expect';\n\n/**\n * Imports\n */\n\nimport { TimeoutError } from '@errors/timeout.error';\nimport { inject } from '@symlinks/services/inject.service';\nimport { TimerService } from '@shared/services/timer.service';\n\n\n/**\n * Executes a given asynchronous or synchronous task with an optional timeout constraint.\n *\n * @typeParam T - The resolved value type.\n *\n * @param task - Either a function that returns a value or promise, or a promise itself.\n * @param delay - Timeout in milliseconds, or `-1` to disable the timeout.\n * @param at - A contextual label (e.g., method name or operation name) to aid debugging.\n * @param stack - Optional stack trace to provide more detailed error context.\n *\n * @throws {@link TimeoutError} If the task does not complete within the specified `delay`\n * (only when `delay` is not `-1`).\n *\n * @remarks\n * The function accepts either:\n * - a function returning a value or a promise, or\n * - a promise directly.\n *\n * If `delay` is `-1`, no timeout is applied. Otherwise the task is raced against\n * a timer and a {@link TimeoutError} is thrown on expiry.\n *\n * @example\n * ```ts\n * // Passing a function\n * await withTimeout(\n * () => fetchData(),\n * 5000,\n * 'fetchData'\n * );\n *\n * // Passing a promise directly\n * await withTimeout(\n * fetchData(),\n * 5000,\n * 'fetchDataDirect'\n * );\n *\n * // No timeout\n * await withTimeout(fetchData(), -1, 'fetchDataNoTimeout');\n * ```\n *\n * @since 1.1.0\n */\n\nexport async function withTimeout<T>(\n task: FunctionLikeType<T | Promise<T>> | Promise<T> | T, delay: number, at: string, stack?: string\n): Promise<T> {\n const timers = inject(TimerService);\n\n const taskPromise =\n typeof task === 'function'\n ? Promise.resolve((task as FunctionLikeType<T | Promise<T>>)())\n : Promise.resolve(task);\n\n if (delay === -1 || !timers.originalSetTimeout) {\n return taskPromise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = timers.originalSetTimeout?.(\n () => reject(new TimeoutError(delay, at, stack)),\n delay\n );\n });\n\n try {\n return await Promise.race([ taskPromise, timeoutPromise ]);\n } finally {\n timers.originalClearTimeout?.(timeoutId!);\n }\n}\n\n", "#!/usr/bin/env node\n\n/**\n * Imports\n */\n\nimport '@errors/uncaught.error';\nimport { parseArguments } from '@providers/cli.provider';\nimport { SuitesService } from '@services/suites.service';\nimport { bannerComponent } from '@components/banner.component';\nimport { configuration } from '@providers/configuration.provider';\n\n/**\n * Main entry point for the xJet library.\n *\n * @since 1.0.0\n */\n\nasync function main(argv: Array<string>): Promise<void> {\n const cli = await parseArguments(argv);\n if (cli.verbose) globalThis.VERBOSE = true;\n\n const config = await configuration(cli.config, cli);\n if (config.verbose) globalThis.VERBOSE = true;\n\n if (![ 'json', 'junit' ].includes(config.reporter)) {\n console.log(bannerComponent());\n } else {\n globalThis.NO_COLOR = true;\n }\n\n const suites = new SuitesService(config);\n await suites.executeSuites();\n}\n\n/**\n * Run entrypoint of xJet cli\n */\n\nmain(process.argv);\n"],
6
- "mappings": "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",
4
+ "sourceRoot": "https://github.com/remotex-lab/xJet/tree/v1.0.0-local/",
5
+ "sourcesContent": ["/**\n * Import will remove at compile time\n */\n\nimport type { StackInterface, StackContextInterface } from '@providers/interfaces/stack-provider.interface';\nimport type { StackMetadataInterface, StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { dirname, join, relative } from 'path';\nimport { inject } from '@symlinks/symlinks.module';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { FrameworkService } from '@services/framework.service';\nimport { Bias, type SourceOptionsInterface } from '@remotex-labs/xmap';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\nimport { parseErrorStack, type StackFrameInterface } from '@remotex-labs/xmap/parser.component';\nimport { formatErrorCode, type PositionWithCodeInterface } from '@remotex-labs/xmap/formatter.component';\n\n/**\n * Regular expression to match multiple consecutive spaces.\n *\n * @remarks\n * Used to normalize spacing in formatted strings by replacing sequences\n * of two or more spaces with a single space.\n *\n * @since 1.0.0\n */\n\nconst MULTIPLE_SPACES = /\\s{2,}/g;\n\n/**\n * Regular expression to detect HTTP or HTTPS URLs.\n *\n * @remarks\n * Used to identify URL-based source paths in stack traces or source maps.\n *\n * @since 1.0.0\n */\n\nconst URL_PATTERN = /^https?:\\/\\//;\n\n/**\n * Regular expression to detect HTTP or HTTPS URLs.\n *\n * @remarks\n * Used to identify URL-based source paths in stack traces or source maps.\n *\n * @since 1.0.0\n */\n\nconst FILE_PROTOCOL = /^file:\\/\\//;\n\n/**\n * Formats a single stack frame into a readable string.\n *\n * @param frame - The stack frame to format\n * @returns A string representing the formatted stack frame, including function name,\n * file path, and optional line/column information\n *\n * @remarks\n * - Shortens paths inside the framework root.\n * - Adds line and column information in gray if available.\n * - Applies coloring to the file path using {@link xterm.darkGray}.\n * - Normalizes multiple spaces in the output.\n *\n * @example\n * ```ts\n * const line = formatStackFrame.call(context, frame);\n * console.log(line); // at myFunction file.js [10:5]\n * ```\n *\n * @see xterm\n * @see MULTIPLE_SPACES\n *\n * @since 1.0.0\n */\n\nexport function formatStackFrame(this: StackContextInterface, frame: StackFrameInterface): string {\n if (frame.fileName?.includes(this.framework.rootPath)) {\n frame.fileName = relative(this.framework.rootPath, frame.fileName);\n }\n\n if (!frame.fileName) {\n return frame.source ?? '';\n }\n\n const position = (frame.line && frame.column)\n ? xterm.gray(`[${ frame.line }:${ frame.column }]`)\n : '';\n\n return `at ${ frame.functionName ?? '' } ${ xterm.darkGray(frame.fileName) } ${ position }`\n .replace(MULTIPLE_SPACES, ' ')\n .trim();\n}\n\n/**\n * Constructs a location string for a stack frame, suitable for links or display.\n *\n * @param frame - The stack frame being processed\n * @param position - The resolved source position with code\n * @returns A string representing the source location, including line number\n *\n * @remarks\n * - Handles HTTP/HTTPS URLs and file paths.\n * - Prepends the source root if available and normalizes path separators.\n * - Appends the line number using `#L` format.\n * - Falls back to the frame's fileName if no source is provided, stripping `file://` prefixes.\n *\n * @example\n * ```ts\n * const location = getSourceLocation.call(context, frame, position);\n * console.log(location); // src/utils/file.js#L12\n * ```\n *\n * @see URL_PATTERN\n * @see FILE_PROTOCOL\n *\n * @since 1.0.0\n */\n\nexport function getSourceLocation(this: StackContextInterface, frame: StackFrameInterface, position: Required<PositionWithCodeInterface>): string {\n const { source, sourceRoot, line } = position;\n\n if (source) {\n const lastIndex = source.lastIndexOf('http://');\n const lastHttpsIndex = source.lastIndexOf('https://');\n\n if (Math.max(lastIndex, lastHttpsIndex) !== -1)\n return `${ source.substring(Math.max(lastIndex, lastHttpsIndex)) }#L${ line }`;\n\n if (URL_PATTERN.test(source))\n return `${ source }#L${ line }`;\n\n if (sourceRoot) {\n const path = relative(\n dirname(this.framework.distPath),\n join(this.framework.distPath, source)\n ).replace(/\\\\/g, '/');\n\n return `${ sourceRoot }${ path }#L${ line }`;\n }\n\n return `${ source }#L${ line }`;\n }\n\n return frame.fileName ? frame.fileName.replace(FILE_PROTOCOL, '') : '';\n}\n\n/**\n * Highlights code at a specific position with syntax coloring.\n *\n * @param position - The position object containing the code to highlight\n * @returns The code string with applied syntax highlighting and formatting\n *\n * @remarks\n * - Uses {@link highlightCode} to apply syntax highlighting to the `position.code`.\n * - Wraps the highlighted code with {@link formatErrorCode} for additional formatting.\n * - Default highlight color is {@link xterm.brightPink}.\n *\n * @example\n * ```ts\n * const highlighted = highlightPositionCode({ code: 'const x = 1;', line: 1, column: 0 });\n * console.log(highlighted); // Outputs syntax-highlighted code string\n * ```\n *\n * @see highlightCode\n * @see formatErrorCode\n * @see xterm.brightPink\n *\n * @since 1.0.0\n */\n\nexport function highlightPositionCode(position: PositionWithCodeInterface): string {\n return formatErrorCode(\n { ...position, code: highlightCode(position.code) },\n { color: xterm.brightPink }\n );\n}\n\n/**\n * Formats a stack frame using position information and highlights the relevant code.\n *\n * @param frame - The stack frame to format\n * @param position - The resolved source position containing line, column, and code\n * @returns A formatted string representing the stack frame with function, file, and line information\n *\n * @remarks\n * - Caches the code and formatted code on the context for reuse.\n * - Uses {@link highlightPositionCode} to apply syntax highlighting.\n * - Builds the file location using {@link getSourceLocation}.\n * - Delegates final formatting to {@link formatStackFrame}.\n *\n * @example\n * ```ts\n * const formatted = formatFrameWithPosition.call(context, frame, position);\n * console.log(formatted); // at myFunction src/utils/file.js [10:5]\n * ```\n *\n * @see formatStackFrame\n * @see getSourceLocation\n * @see highlightPositionCode\n *\n * @since 1.0.0\n */\n\nexport function formatFrameWithPosition(this: StackContextInterface, frame: StackFrameInterface, position: Required<PositionWithCodeInterface>): string {\n if (!this.code) {\n this.code = position.code;\n this.source = position.source;\n this.formatCode = highlightPositionCode(position);\n }\n\n return formatStackFrame.call(this, {\n ...frame,\n line: position.line,\n column: position.column,\n functionName: position.name ?? frame.functionName,\n fileName: getSourceLocation.call(this, frame, position)\n });\n}\n\n/**\n * Processes a single stack frame and formats it for display, optionally including source map information.\n *\n * @param frame - The stack frame to process\n * @param options - Optional {@link SourceOptionsInterface} for retrieving source positions\n * @returns A formatted string representing the stack frame, or an empty string if filtered out\n *\n * @remarks\n * - Skips native frames if {@link StackContextInterface.withNativeFrames} is false.\n * - Skips framework files if {@link StackContextInterface.withFrameworkFrames} is false.\n * - Attempts to resolve source positions using {@link FrameworkService.getSourceMap} and\n * {@link getPositionWithCode}.\n * - Delegates formatting to {@link formatFrameWithPosition} or {@link formatStackFrame} depending on availability of position information.\n *\n * @example\n * ```ts\n * const formatted = stackEntry.call(context, frame, { includeCode: true });\n * console.log(formatted);\n * ```\n *\n * @see formatStackFrame\n * @see StackContextInterface\n * @see formatFrameWithPosition\n * @see FrameworkService.getSourceMap\n * @see SourceService.getPositionWithCode\n *\n * @since 1.0.0\n */\n\nexport function stackEntry(this: StackContextInterface, frame: StackFrameInterface, options?: SourceOptionsInterface): string {\n if (!this.withNativeFrames && frame.native) return '';\n if (!frame.line && !frame.column && !frame.fileName && !frame.functionName) return '';\n\n const source = this.framework.getSourceMap(frame.fileName ?? '');\n if (!source) {\n return formatStackFrame.call(this, frame);\n }\n\n const position = source.getPositionWithCode(\n frame.line ?? 0,\n frame.column ?? 0,\n Bias.LOWER_BOUND,\n options\n );\n\n if (position && (!this.withFrameworkFrames && this.framework.isFrameworkFile(position)))\n return '';\n\n if (position) {\n this.line = position.line;\n this.column = position.column;\n\n return formatFrameWithPosition.call(this, frame, position);\n }\n\n return formatStackFrame.call(this, frame);\n}\n\n/**\n * Parses an error stack trace into a structured and formatted representation.\n *\n * @param error - The {@link Error} object to parse\n * @param options - Optional {@link StackTraceInterface} configuration for controlling stack parsing\n * @returns A {@link StackInterface} object containing structured stack frames and formatted code\n *\n * @remarks\n * - Creates a {@link StackContextInterface} using the {@link FrameworkService} for resolving source maps.\n * - Uses {@link parseErrorStack} to convert the error into individual stack frames.\n * - Each frame is processed via {@link stackEntry}, applying filtering for native and framework files.\n * - Returns the fully formatted stack with code snippets and line/column metadata.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (error) {\n * const stackData = parseStackTrace(error);\n * console.log(stackData.stacks); // Array of formatted stack lines\n * console.log(stackData.formatCode); // Highlighted code snippet\n * }\n * ```\n *\n * @see stackEntry\n * @see StackInterface\n * @see parseErrorStack\n * @see StackTraceInterface\n * @see StackContextInterface\n *\n * @since 1.0.0\n */\n\nexport function parseStackTrace(error: Error, options: StackTraceInterface = {}): StackInterface {\n const context: StackContextInterface = {\n code: '',\n source: '',\n framework: inject(FrameworkService),\n formatCode: '',\n withNativeFrames: false,\n withFrameworkFrames: false,\n ...options,\n ...(globalThis.VERBOSE && {\n withNativeFrames: true,\n withFrameworkFrames: true\n })\n };\n\n const parsedStack = parseErrorStack(error);\n const stacks = parsedStack.stack\n .map(frame => stackEntry.call(context, frame, options))\n .filter(Boolean);\n\n return {\n stacks,\n code: context.code,\n line: context.line ?? 0,\n column: context.column ?? 0,\n source: context.source,\n formatCode: context.formatCode\n };\n}\n\n/**\n * Formats an error and its stack trace into a human-readable string with enhanced styling.\n *\n * @param error - The {@link Error} object to format\n * @param options - Optional {@link StackTraceInterface} configuration for stack parsing\n * @returns A string containing the formatted error message, highlighted code, and enhanced stack trace\n *\n * @remarks\n * - Parses the error stack using {@link parseStackTrace}.\n * - Applies syntax highlighting and formatting to the code snippet and stack frames.\n * - Prepends the error name and message, followed by highlighted code (if available) and formatted stack frames.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (error) {\n * console.log(formatStack(error));\n * }\n * ```\n *\n * @see xterm\n * @see parseStackTrace\n * @see StackTraceInterface\n *\n * @since 1.0.0\n */\n\nexport function formatStack(error: Error, options: StackTraceInterface = {}): string {\n const metadata = parseStackTrace(error, options);\n const parts = [ `\\n${ error.name }: ${ error.message }\\n\\n` ];\n if (metadata.formatCode) {\n parts.push(`${ metadata.formatCode }\\n\\n`);\n }\n\n if (metadata.stacks.length > 0) {\n parts.push(`Enhanced Stack Trace:\\n ${ metadata.stacks.join('\\n ') }\\n`);\n }\n\n return parts.join('');\n}\n\n/**\n * Extracts structured metadata from an error's stack trace.\n *\n * @param error - The {@link Error} object to process\n * @param options - Optional {@link StackTraceInterface} configuration for parsing the stack\n * @returns A {@link StackMetadataInterface} object containing code, line/column positions, formatted code, and stack frames\n *\n * @remarks\n * - Internally calls {@link parseStackTrace} to generate a structured representation of the stack trace.\n * - Prepends each stack frame with indentation for better readability.\n * - Useful for logging, debugging, or programmatic analysis of error stacks.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Unexpected error\");\n * } catch (error) {\n * const meta = stackMetadata(error);\n * console.log(meta.stacks); // Indented stack frames\n * console.log(meta.formatCode); // Highlighted code snippet\n * }\n * ```\n *\n * @see parseStackTrace\n * @see StackTraceInterface\n * @see StackMetadataInterface\n *\n * @since 1.0.0\n */\n\nexport function stackMetadata(error: Error, options: StackTraceInterface = {}): StackMetadataInterface {\n let metadata = parseStackTrace(error, options);\n if(metadata.stacks.length < 1) metadata = parseStackTrace(error, { withFrameworkFrames: true });\n\n return {\n code: metadata.code,\n line: metadata.line,\n column: metadata.column,\n source: metadata.source,\n stacks: ' ' + metadata.stacks.join('\\n '),\n formatCode: metadata.formatCode\n };\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ConstructorType } from '@remotex-labs/xjet-expect';\nimport type { InjectableOptionsInterface, TokenElementType } from '@symlinks/interfaces/symlinks.interface';\n\n/**\n * Stores singleton instances of injectable classes.\n *\n * @since 1.0.0\n */\n\nconst SINGLETONS = new Map<ConstructorType, unknown>();\n\n/**\n * Stores metadata for classes marked as injectable via `@Injectable`.\n *\n * @internal\n * @since 1.0.0\n */\n\nconst INJECTABLES = new Map<ConstructorType, InjectableOptionsInterface>();\n\n/**\n * Marks a class as injectable and stores its configuration metadata.\n *\n * @template T - The type of the class instance\n * @template Args - The types of arguments accepted by the constructor, defaults to `unknown[]`\n *\n * @param options - Optional configuration for the injectable, including scope and factory\n *\n * @example\n * ```ts\n * @Injectable({ scope: 'singleton' })\n * class MyService {}\n * ```\n *\n * @see InjectableOptionsInterface\n * @since 1.0.0\n */\n\nexport function Injectable<T = unknown, Args extends Array<unknown> = unknown[]>(options?: InjectableOptionsInterface) {\n return function (target: new (...args: Args) => T): void {\n INJECTABLES.set(target, options || {});\n };\n}\n\n/**\n * Resolves and returns an instance of the given injectable token.\n *\n * @template T - The type of the instance to return\n * @template Args - The types of arguments passed to the constructor or factory\n *\n * @param token - The injectable class or token to resolve\n * @param args - Arguments to pass to the constructor or factory\n *\n * @returns The resolved instance of type `T`\n *\n * @throws Error - If the token is not registered as injectable via `@Injectable`\n *\n * @remarks\n * If the injectable is marked with scope `'singleton'`, the same instance will be returned\n * on the following calls. Otherwise, a new instance is created for each call.\n *\n * @example\n * ```ts\n * const service = inject(MyService);\n * ```\n *\n * @see TokenElementType\n * @since 1.0.0\n */\n\nexport function inject<T, Args extends Array<unknown>>(token: TokenElementType<T, Args>, ...args: Args): T {\n if (SINGLETONS.has(token)) return <T>SINGLETONS.get(token);\n\n const metadata = INJECTABLES.get(token);\n if (!metadata) throw new Error(`Cannot inject ${ token.name } \u2013 not marked @Injectable`);\n\n const instance: T = metadata.factory\n ? <T>metadata.factory(...args)\n : new token(...args);\n\n if (metadata?.scope === 'singleton') {\n SINGLETONS.set(token, instance);\n }\n\n return instance;\n}\n", "/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { normalize } from 'path';\nimport { readFileSync } from 'fs';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { type PositionInterface, SourceService } from '@remotex-labs/xmap';\n\n/**\n * Provides access to the framework's file paths and associated source maps.\n *\n * @remarks\n * This service manages the framework's source map files, including the main framework\n * file and any additional source files. It caches initialized {@link SourceService}\n * instances for performance.\n *\n * @example\n * ```ts\n * const frameworkService = new FrameworkService();\n * console.log(frameworkService.rootPath);\n * const sourceMap = frameworkService.sourceMap(frameworkService.filePath);\n * ```\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class FrameworkService {\n /**\n * Absolute path to the current file.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly filePath: string;\n\n /**\n * Absolute path to the distribution directory.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly distPath: string;\n\n /**\n * Absolute path to the project root directory.\n * @readonly\n *\n * @since 1.0.0\n */\n\n readonly rootPath: string;\n\n /**\n * Source service for the main framework file.\n * @readonly\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n readonly frameworkSourceMap: SourceService;\n\n /**\n * Cached {@link SourceService} instances for additional source files.\n * @since 1.0.0\n */\n\n private readonly sourceMaps = new Map<string, SourceService>();\n\n /**\n * Initializes a new {@link FrameworkService} instance.\n *\n * @remarks\n * Sets up the main framework source map, as well as root and distribution paths.\n *\n * @since 1.0.0\n */\n\n constructor() {\n this.filePath = import.meta.filename ?? __filename;\n this.setSourceFile(this.filePath);\n this.frameworkSourceMap = this.getSourceMap(this.filePath)!;\n\n this.rootPath = this.getRootDir();\n this.distPath = this.getDistDir();\n }\n\n /**\n * Determines whether a given {@link PositionInterface} refers to a framework file.\n *\n * @param position - The position information to check\n * @returns `true` if the position is from the framework (contains \"xJet\"), otherwise `false`\n *\n * @see PositionInterface\n * @since 1.0.0\n */\n\n isFrameworkFile(position: PositionInterface): boolean {\n const { source, sourceRoot } = position;\n const lowerCaseSource = source?.toLowerCase();\n\n return Boolean(\n (source && lowerCaseSource.includes('xjet') && !lowerCaseSource.includes('xjet.config')) ||\n (sourceRoot && sourceRoot.includes('xJet'))\n );\n }\n\n /**\n * Retrieves a cached {@link SourceService} for a given file path.\n *\n * @param path - Absolute path to the file\n * @returns A {@link SourceService} instance if found, otherwise `undefined`\n *\n * @remarks\n * Paths are normalized before lookup. Only previously initialized source maps\n * (via {@link setSource} or {@link setSourceFile}) are available in the cache.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n getSourceMap(path: string): SourceService | undefined {\n path = normalize(path);\n if (this.sourceMaps.has(path))\n return this.sourceMaps.get(path)!;\n\n return undefined;\n }\n\n /**\n * Registers and initializes a new {@link SourceService} for a provided source map string.\n *\n * @param source - The raw source map content\n * @param path - Absolute file path associated with the source map\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if initialization fails\n *\n * @remarks\n * If a source map for the given path is already cached, the cached instance is returned.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n setSource(source: string, path: string): void {\n const key = normalize(path);\n\n try {\n return this.initializeSourceMap(source, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Loads and initializes a {@link SourceService} for a file and its `.map` companion.\n *\n * @param path - Absolute path to the file\n * @returns A new or cached {@link SourceService} instance\n *\n * @throws Error if the `.map` file cannot be read or parsed\n *\n * @remarks\n * This method attempts to read the `.map` file located next to the provided file.\n * If already cached, returns the existing {@link SourceService}.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n setSourceFile(path: string): void {\n const key = normalize(path);\n const map = `${ path }.map`;\n\n if (this.sourceMaps.has(key))\n return;\n\n try {\n const sourceMapData = readFileSync(map, 'utf-8');\n\n return this.initializeSourceMap(sourceMapData, key);\n } catch (error) {\n throw new Error(\n `Failed to initialize SourceService: ${ key }\\n${ error instanceof Error ? error.message : String(error) }`\n );\n }\n }\n\n /**\n * Retrieves the project root directory.\n * @returns Absolute path to the project root\n *\n * @since 1.0.0\n */\n\n private getRootDir(): string {\n return process.cwd();\n }\n\n /**\n * Retrieves the distribution directory.\n * @returns Absolute path to the distribution folder\n *\n * @since 1.0.0\n */\n\n private getDistDir(): string {\n return dirname(this.filePath);\n }\n\n /**\n * Creates and caches a new {@link SourceService} instance for a given source map.\n *\n * @param source - Raw source map content\n * @param key - Normalized file path used as the cache key\n * @returns The newly created {@link SourceService} instance\n *\n * @remarks\n * This method is only used internally by {@link setSource} and {@link setSourceFile}.\n * The instance is cached in {@link sourceMaps} for reuse.\n *\n * @see SourceService\n * @since 1.0.0\n */\n\n private initializeSourceMap(source: string, key: string): void {\n if(source?.includes('\"mappings\": \"\"'))\n return;\n\n const sourceMap = new SourceService(source, this.filePath);\n this.sourceMaps.set(key, sourceMap);\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { formatStack } from '@providers/stack.provider';\n\n/**\n * Base an abstract error class for all xJet-specific errors.\n *\n * Extends the native `Error` class with improved stack trace handling,\n * optional formatted stack traces, and serialization capabilities.\n *\n * @remarks\n * This class is the foundation for all custom xJet error types.\n * It ensures consistent behavior, proper prototype chain setup, and\n * provides methods for serializing the error and accessing a formatted stack trace.\n *\n * @example\n * ```ts\n * // Extending the base error class\n * export class ValidationError extends xJetBaseError {\n * constructor(message: string) {\n * super(message);\n * this.name = 'ValidationError';\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport abstract class xJetBaseError extends Error {\n /**\n * Stores a pre-formatted stack trace for the error.\n * @since 1.0.0\n */\n\n protected formattedStack: string | undefined;\n\n /**\n * Creates a new instance of the base error class.\n *\n * @param message - The error message describing the problem.\n * @param name - Optional error name; defaults to `'xJetError'`.\n *\n * @remarks\n * Properly sets up the prototype chain to ensure `instanceof` works for derived classes.\n * Captures the stack trace if supported by the runtime environment.\n *\n * @example\n * ```ts\n * class MyError extends xJetBaseError {}\n * throw new MyError('Something went wrong');\n * ```\n *\n * @since 1.0.0\n */\n\n protected constructor(message: string, name: string = 'xJetError') {\n super(message);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = name;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Gets the formatted stack trace, if available.\n *\n * @returns The formatted stack trace, or `undefined` if not set.\n *\n * @since 1.0.0\n */\n\n get formatStack(): string | undefined {\n return this.formattedStack;\n }\n\n /**\n * Serializes the error instance to a plain object for JSON conversion.\n *\n * @returns A plain object containing all enumerable properties of the error,\n * including `name`, `message`, and `stack`.\n *\n * @remarks\n * Useful for logging, error reporting, or transmitting error details across processes.\n *\n * @example\n * ```ts\n * const error = new xJetError('Validation failed');\n * const json = JSON.stringify(error.toJSON());\n * ```\n *\n * @since 1.0.0\n */\n\n toJSON(): Record<string, unknown> {\n const json: Record<string, unknown> = {};\n\n // Copy all own (non-inherited) enumerable properties\n for (const key of Object.keys(this)) {\n const value = this[key as keyof this];\n if(value) json[key] = value;\n }\n\n // Ensure `name`, `message`, and `stack` are included\n json.name = this.name;\n json.stack = this.stack;\n json.message = this.message;\n\n return json;\n }\n\n /**\n * Custom inspect behavior for Node.js console output.\n *\n * @returns The formatted stack trace if available, otherwise the raw stack trace.\n *\n * @since 1.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n return this.formattedStack ?? this.stack;\n }\n\n /**\n * Generates a formatted stack trace using provided options and stores it in `formattedStack`.\n *\n * @param error - The error object to format.\n * @param options - Options controlling stack trace formatting.\n *\n * @remarks\n * This method is intended to be called by derived classes or internal code\n * to prepare a styled or enhanced stack trace for logging or display.\n *\n * @example\n * ```ts\n * class ValidationError extends xJetBaseError {\n * constructor(message: string) {\n * super(message);\n * this.reformatStack(this, { withFrameworkFrames: true });\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n protected reformatStack(error: Error, options?: StackTraceInterface): void {\n this.formattedStack = formatStack(error, options);\n }\n}\n", "/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\nimport { formatStack } from '@providers/stack.provider';\n\n/**\n * Formats and logs error output in a standardized way.\n *\n * @remarks\n * This utility is designed for use in global error handlers such as\n * `uncaughtException` and `unhandledRejection`.\n * - If the error is an {@link AggregateError}, all individual errors are iterated and logged.\n * - Errors extending {@link xJetBaseError} are logged directly without stack formatting.\n * - Standard {@link Error} instances are logged using {@link formatStack}, with both\n * framework and native frames included.\n * - Non-error values are logged as-is.\n *\n * @param reason - The error, aggregate error, or arbitrary value to log.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Something went wrong\");\n * } catch (err) {\n * formatErrors(err);\n * }\n * ```\n *\n * @see formatStack\n * @see xJetBaseError\n * @see AggregateError\n *\n * @since 1.0.0\n */\n\nexport function formatErrors(reason: unknown): void {\n if (reason instanceof AggregateError) {\n console.error('AggregateError:', reason.message);\n for (const err of reason.errors) {\n if (err instanceof Error && !(err instanceof xJetBaseError)) {\n console.error(formatStack(err, { withFrameworkFrames: true, withNativeFrames: true }));\n } else {\n console.error(err);\n }\n }\n\n return;\n }\n\n if (reason instanceof Error && !(reason instanceof xJetBaseError)) {\n console.error(formatStack(reason, { withFrameworkFrames: true, withNativeFrames: true }));\n } else {\n console.error(reason);\n }\n}\n\n/**\n * Global handler for uncaught exceptions in Node.js.\n *\n * @param reason - The value or error object representing the uncaught exception\n *\n * @throws This handler does not throw, but catches uncaught exceptions\n *\n * @remarks\n * When an uncaught exception occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`, signaling failure.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded,\n * throw new Error('This error will be logged and exit the process');\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#event-uncaughtexception | Node.js documentation on 'uncaughtException'}\n *\n * @since 1.0.0\n */\n\nprocess.on('uncaughtException', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n/**\n * Global handler for unhandled promise rejections in Node.js.\n *\n * @param reason - The value or error object representing the reason for the unhandled promise rejection\n *\n * @throws This handler does not throw, but catches unhandled promise rejections\n *\n * @remarks\n * When an unhandled promise rejection occurs, this handler logs the error using {@link formatStack}\n * with both framework and native frames included, and then terminates the process\n * with exit code `2`. Using a distinct exit code allows differentiating between uncaught exceptions\n * and unhandled promise rejections.\n *\n * @example\n * ```ts\n * // Automatically registered when this file is loaded\n * Promise.reject(new Error('This rejection will be logged and exit the process'));\n * ```\n *\n * @see formatStack\n * @see process.exit\n * @see {@link https://nodejs.org/api/process.html#process_event_unhandledrejection | Node.js documentation on 'unhandledRejection'}\n *\n * @since 1.0.0\n */\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n formatErrors(reason);\n process.exit(2);\n});\n\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Argv, Options } from 'yargs';\nimport type { CliOptionsInterface } from '@providers/interfaces/cli-provider.interface';\n\n/**\n * Imports\n */\n\nimport yargs from 'yargs';\nimport { resolve } from 'path';\nimport { hideBin } from 'yargs/helpers';\nimport { bannerComponent } from '@components/banner.component';\nimport { configuration } from '@providers/configuration.provider';\n\n/**\n * Default path to the xJet configuration file.\n *\n * @remarks\n * - Used as the fallback configuration file if the user does not specify `--config`.\n * - Can be overridden by CLI argument `--config` or `-c`.\n *\n * @example\n * ```ts\n * import { DEFAULT_CONFIG_PATH } from '@cli/parse-arguments';\n * console.log(DEFAULT_CONFIG_PATH); // 'xJet/xjet.config.ts'\n * ```\n *\n * @since 1.0.0\n */\n\nconst DEFAULT_CONFIG_PATH = 'xJet/config.xjet.ts';\n\n/**\n * Default command-line options for the xJet test runner.\n *\n * @remarks\n * Provides the baseline configuration for parsing CLI arguments using `yargs`.\n * Each property maps to a CLI flag, with type, aliases, and description.\n *\n * @since 1.0.0\n */\n\nconst DEFAULT_CLI_OPTIONS = {\n files: {\n describe: 'Glob patterns or file paths used to discover test files',\n type: 'string',\n array: true\n },\n suites: {\n alias: 's',\n describe: 'Filter pattern for test suite files. Only matching files from `files` will run.',\n type: 'string',\n array: true\n },\n filter: {\n alias: 'f',\n describe: 'Run only tests or suites matching these names',\n type: 'string',\n array: true\n },\n config: {\n alias: 'c',\n describe: 'Path to xJet configuration file (.ts or .js)',\n type: 'string',\n default: DEFAULT_CONFIG_PATH,\n normalize: true,\n coerce: (value: string) => resolve(value)\n },\n reporter: {\n alias: 'r',\n describe: 'Reporter for test results. Built-in: \"spec\", \"json\", \"junit\". Can also be a custom module path.',\n type: 'string'\n },\n outputFile: {\n describe: 'Optional file path to write reporter output (e.g., \"reports/junit.xml\")',\n type: 'string'\n },\n verbose: {\n alias: 'v',\n describe: 'Include full stack traces, including internal frames',\n type: 'boolean'\n },\n logLevel: {\n alias: 'l',\n describe: 'Set the logging verbosity level (Silent, Error, Warn, Info, Debug)',\n type: 'string',\n choices: [ 'Silent', 'Error', 'Warn', 'Info', 'Debug' ]\n },\n timeout: {\n alias: 't',\n describe: 'Maximum time (ms) a single test can run before failing',\n type: 'number'\n },\n bail: {\n alias: 'b',\n describe: 'Stop running tests after the first failure',\n type: 'boolean'\n },\n watch: {\n alias: 'w',\n describe: 'Watch files for changes and re-run tests automatically',\n type: 'boolean'\n },\n randomize: {\n describe: 'Randomize the order of test execution',\n type: 'boolean'\n }\n} as const;\n\n/**\n * Predefined command usage examples for xJet CLI.\n *\n * @remarks\n * Each tuple contains:\n * - The CLI command string.\n * - A short description of what the command does.\n *\n * These examples are used to populate the help output (`--help`) of the CLI.\n *\n * @example\n * ```bash\n * xJet --config ./xjet.config.ts # Run tests with custom configuration\n * xJet --filter \"auth.*\" --verbose # Run auth-related tests with verbose logging\n * xJet --suites \"src/**\\/*.test.ts\" # Run specific test suites\n * xJet --files \"src/**\\/*.test.ts\" # Run a pattern to collect test files\n * xJet --watch --coverage # Run tests in watch mode with coverage\n * ```\n *\n * @since 1.0.0\n */\n\nconst USAGE_EXAMPLES = [\n [ 'xJet --config ./xjet.config.ts', 'Run tests with custom configuration' ],\n [ 'xJet --filter \"auth.*\" --verbose', 'Run auth-related tests with verbose logging' ],\n [ 'xJet --suites \"src/**/*.test.ts\"', 'Run specific test suites' ],\n [ 'xJet --files \"src/**/*.test.ts\"', 'Run pattern to collect test files' ],\n [ 'xJet --watch --coverage', 'Run tests in watch mode with coverage' ]\n] as const;\n\n/**\n * Reads user-defined CLI options from the xJet configuration file.\n *\n * @remarks\n * - Parses only the `--config` option to locate the user configuration file.\n * - Loads the configuration via {@link configuration} and extracts `userArgv`.\n * - Returns an empty object if no user CLI options are defined.\n *\n * @returns A promise resolving to a record of CLI options conforming to {@link Options}.\n *\n * @example\n * ```ts\n * const userOptions = await getUserArgv();\n * console.log(userOptions.files, userOptions.suites);\n * ```\n *\n * @since 1.0.0\n */\n\nexport async function getUserArgv(): Promise<Record<string, Options>> {\n const argv = yargs(process.argv).options({\n config: DEFAULT_CLI_OPTIONS.config\n }).parseSync();\n\n return (await configuration(argv.config, argv as CliOptionsInterface)).userArgv ?? {};\n}\n\n/**\n * Parses command-line arguments for the xJet test runner.\n *\n * @param argv - Array of command-line arguments (typically `process.argv`).\n * @returns A promise resolving to {@link CliOptionsInterface} with fully parsed CLI options.\n *\n * @remarks\n * - Combines default CLI options (`DEFAULT_CLI_OPTIONS`) with user-defined options from {@link getUserArgv}.\n * - Overrides `showHelp` to display the xJet banner via {@link bannerComponent}.\n * - Supports glob patterns for `files` and `suites`, test filtering via `filter`, and custom reporters (`reporter` and `outputFile`).\n * - Supports execution flags: `verbose`, `silent`, `timeout`, `bail`, `watch`, `randomize`.\n * - Evaluation order for test selection:\n * 1. `files` \u2192 collect all test files matching patterns.\n * 2. `suites` \u2192 filter files by suite patterns.\n * 3. `filter` \u2192 filter individual tests or describes by name.\n * - Automatically registers usage examples defined in {@link USAGE_EXAMPLES}.\n *\n * @example\n * ```ts\n * import { parseArguments } from '@cli/parse-arguments';\n * const options = await parseArguments(process.argv);\n * console.log(options.files, options.suites, options.filter);\n * ```\n *\n * @see {@link getUserArgv} for loading user-defined CLI options from the configuration file.\n * @see {@link CliOptionsInterface} for the shape of returned options.\n *\n * @since 1.0.0\n */\n\nexport async function parseArguments(argv: Array<string>): Promise<CliOptionsInterface> {\n const userOptions = await getUserArgv();\n\n const parser = yargs(hideBin(argv));\n const originalShowHelp = parser.showHelp;\n parser.showHelp = function (consoleFunction?: string | ((s: string) => void)): Argv<unknown> {\n console.log(bannerComponent());\n this.group(Object.keys(DEFAULT_CLI_OPTIONS), 'xJet Options:');\n this.group(Object.keys(userOptions), 'user Options:');\n\n return originalShowHelp.call(this, consoleFunction as (s: string) => void);\n };\n\n const cli = parser\n .usage('Usage: xJet [files..] [options]')\n .command('* [files..]', 'Specific test files to run (supports glob patterns)', (yargs) => {\n return yargs.positional('files', {\n describe: 'Specific test files to run (supports glob patterns)',\n type: 'string',\n array: true\n });\n })\n .options(userOptions)\n .options(DEFAULT_CLI_OPTIONS)\n .epilogue('For more information, check the documentation')\n .help()\n .alias('help', 'h')\n .strict()\n .version();\n\n USAGE_EXAMPLES.forEach(([ command, description ]) => {\n cli.example(command, description);\n });\n\n return cli.parseSync() as CliOptionsInterface;\n}\n\n", "/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * ASCII art logo for the framework.\n *\n * @remarks\n * This logo is styled using {@link xterm} color utilities when displayed\n * via the {@link bannerComponent}.\n *\n * @example\n * ```ts\n * console.log(asciiLogo);\n * ```\n *\n * @since 1.0.0\n */\n\nexport const asciiLogo = `\n ___ _\n |_ | | |\n__ __ | | ___| |_\n\\\\ \\\\/ / | |/ _ \\\\ __|\n > </\\\\__/ / __/ |_\n/_/\\\\_\\\\____/ \\\\___|\\\\__|\n`;\n\n/**\n * Creates a colored ASCII banner including the framework version.\n *\n * @remarks\n * Uses {@link xterm} to render the ASCII logo and\n * {@link xterm} to highlight the `__VERSION` string.\n *\n * @returns A formatted string suitable for console output\n *\n * @example\n * ```ts\n * console.log(bannerComponent());\n * ```\n *\n * @see asciiLogo\n * @since 1.0.0\n */\n\nexport function bannerComponent(): string {\n return `${ xterm.burntOrange(asciiLogo) }\\nVersion: ${ xterm.brightPink(__VERSION) }\\n`;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { CliOptionsInterface } from '@providers/interfaces/cli-provider.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { defaultConfiguration } from '@configuration/default.configuration';\nimport { parseConfigurationFile } from '@configuration/parse.configuration';\n\n/**\n * Loads and merges the xJet configuration.\n *\n * @param configFile - Optional path to a user configuration file (e.g., 'xjet.config.ts').\n * @param cli - Command-line options provided by the user.\n * @returns A promise that resolves to the final {@link ConfigurationInterface} object.\n *\n * @remarks\n * This function performs the following steps:\n * 1. Starts with the default configuration.\n * 2. If a configuration file is provided and exists, it is parsed using {@link parseConfigurationFile}.\n * 3. The user configuration is merged with the default configuration. The `exclude` arrays from both\n * configurations are concatenated to preserve all exclusions.\n * 4. Finally, command-line options override any existing configuration values.\n *\n * This ensures that defaults, user configuration, and CLI flags are combined consistently,\n * giving priority to CLI arguments.\n *\n * @example\n * ```ts\n * import { configuration } from '@services/configuration.service';\n *\n * const cliOptions = { watch: true, verbose: true };\n * const config = await configuration('xjet.config.ts', cliOptions);\n * console.log(config);\n * ```\n *\n * @see parseConfigurationFile\n * @see ConfigurationInterface\n *\n * @since 1.0.0\n */\n\nexport async function configuration(configFile: string = '', cli: CliOptionsInterface): Promise<ConfigurationInterface> {\n let config = { ...defaultConfiguration };\n if (configFile && existsSync(configFile)) {\n const userConfig = await parseConfigurationFile(configFile);\n if (userConfig) {\n config = {\n ...config,\n ...userConfig,\n exclude: [ ...(config.exclude ?? []), ...(userConfig.exclude ?? []) ]\n };\n }\n }\n\n return <ConfigurationInterface> { ...config, ...cli };\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { version } from 'process';\n\n/**\n * The default settings for configuring a testing execution environment.\n *\n * @remarks\n * This configuration includes parameters such as file patterns to include/exclude,\n * timeout settings, verbosity levels, and others necessary for test orchestration.\n * These values can typically be overridden by user-defined configurations.\n *\n * @example\n * ```ts\n * import { defaultConfiguration } from './config';\n *\n * // Using default configuration with overrides\n * const config = {\n * ...defaultConfiguration,\n * timeout: 10000,\n * verbose: true\n * };\n * ```\n *\n * @see ConfigurationInterface\n * @since 1.0.0\n */\n\nexport const defaultConfiguration: Partial<ConfigurationInterface> = {\n bail: false,\n files: [ '**/*.test.ts', '**/*.spec.ts' ],\n watch: false,\n suites: [],\n filter: [],\n verbose: false,\n timeout: 5000,\n parallel: 1,\n exclude: [ /node_modules/ ],\n reporter: 'default',\n randomize: false,\n build: {\n target: [ `node${ version.slice(1) }` ],\n packages: 'bundle',\n platform: 'browser',\n external: []\n }\n};\n", "/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions } from 'esbuild';\nimport type { ModuleInterface } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { createRequire } from 'module';\nimport { sandboxExecute } from '@services/vm.service';\nimport { VMRuntimeError } from '@errors/vm-runtime.error';\nimport { transpileFile } from '@services/transpiler.service';\n\n/**\n * Parses and executes a JavaScript configuration file in a secure sandbox.\n *\n * @param file - The path to the configuration file (e.g., 'xjet.config.js').\n * @returns A promise that resolves to the exported configuration object.\n *\n * @remarks\n * This function performs the following steps:\n * 1. Transpiles the provided configuration file using esbuild with Node.js\n * compatible settings and without minification.\n * 2. Executes the transpiled code in a sandboxed environment using `sandboxExecute`.\n * Only a controlled set of globals (Error, Buffer, RegExp, require, console,\n * setTimeout, setInterval, and a module object) are exposed.\n * 3. Captures any errors thrown during execution and wraps them in a {@link VMRuntimeError}.\n * 4. Returns the exported configuration object from the module. If no default export\n * is found, it returns an empty object.\n *\n * @throws VMRuntimeError - If an error occurs during sandbox execution.\n *\n * @example\n * ```ts\n * import { parseConfigurationFile } from '@services/configuration-parser';\n *\n * const config = await parseConfigurationFile('xjet.config.js');\n * console.log(config);\n * ```\n *\n * @see transpileFile\n * @see sandboxExecute\n * @see VMRuntimeError\n *\n * @since 1.0.0\n */\n\nexport async function parseConfigurationFile(file: string): Promise<ConfigurationInterface> {\n const transpileOptions: BuildOptions = {\n minify: false,\n format: 'cjs',\n outdir: dirname(file),\n platform: 'node',\n logLevel: 'silent',\n packages: 'external',\n minifySyntax: true,\n preserveSymlinks: true,\n minifyWhitespace: true,\n minifyIdentifiers: false\n };\n\n const module: ModuleInterface<ConfigurationInterface> = { exports: {} };\n const { code, path } = await transpileFile(file, transpileOptions);\n const require = createRequire(path);\n\n try {\n await sandboxExecute(code, {\n Error,\n module,\n Buffer,\n RegExp,\n require,\n console,\n setTimeout,\n setInterval\n }, { filename: path });\n } catch (error: unknown) {\n if(error instanceof Error)\n throw new VMRuntimeError(<Error> error);\n\n throw error;\n }\n\n return <ConfigurationInterface> (module.exports.default ?? {});\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Context, ScriptOptions } from 'vm';\n\n/**\n * Imports\n */\n\nimport { Script, createContext } from 'vm';\n\n/**\n * Executes arbitrary code inside a Node.js VM sandbox.\n *\n * @param code - The JavaScript source code to execute\n * @param sandbox - Optional {@link Context} object to inject into the VM environment\n * @param options - Optional {@link ScriptOptions} used when compiling the script\n *\n * @returns A promise resolving to the result of the executed code\n *\n * @throws Error - If the provided code fails to compile or runtime execution throws\n *\n * @remarks\n * This function uses Node.js's {@link Script} and {@link createContext} APIs to safely run code in\n * an isolated environment. Execution is configured with `breakOnSigint` enabled and `displayErrors` disabled.\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"2 + 2\");\n * console.log(result); // 4\n * ```\n *\n * @example\n * ```ts\n * const result = await sandboxExecute(\"user.name\", { user: { name: \"Alice\" } });\n * console.log(result); // \"Alice\"\n * ```\n *\n * @see Context\n * @see ScriptOptions\n *\n * @since 1.0.0\n */\n\nexport async function sandboxExecute(code: string, sandbox: Context = {}, options: ScriptOptions = {}): Promise<unknown> {\n const script = new Script(code, options);\n const context = createContext(sandbox);\n\n return await script.runInContext(context, { breakOnSigint: true, displayErrors: false });\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\n\n/**\n * Represents an error that occurs during VM runtime execution.\n *\n * Extends {@link xJetBaseError} and adds support for wrapping native errors,\n * handling `AggregateError` instances, and preserving nested errors.\n *\n * @remarks\n * This class is designed to encapsulate runtime errors in a virtual machine context.\n * If the original error is already a `xJetBaseError`, it is returned as-is.\n * AggregateErrors are flattened into an array of `VMRuntimeError` instances.\n *\n * The formatted stack trace is automatically generated for both single and nested errors.\n *\n * @example\n * ```ts\n * try {\n * // Some VM execution code that throws\n * } catch (err) {\n * const vmError = new VMRuntimeError(err, { withFrameworkFrames: true });\n * console.error(vmError.formattedStack);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport class VMRuntimeError extends xJetBaseError {\n /**\n * If the original error is an AggregateError, contains nested VMRuntimeError instances.\n *\n * @since 1.0.0\n */\n\n errors?: Array<VMRuntimeError> = [];\n\n /**\n * Creates a new `VMRuntimeError` instance from a native or xJetBaseError.\n *\n * @param originalError - The original error object thrown during execution.\n * @param options - Optional stack trace formatting options.\n *\n * @remarks\n * - If `originalError` is already an instance of `xJetBaseError`, it is returned as-is.\n * - If `originalError` is an `AggregateError`, each nested error is converted into a `VMRuntimeError`.\n * - The message and stack of the original error are preserved.\n * - The formatted stack trace is generated via {@link xJetBaseError.reformatStack}.\n *\n * @since 1.0.0\n */\n\n constructor(private originalError: Error, options?: StackTraceInterface) {\n if (originalError instanceof xJetBaseError) {\n return <VMRuntimeError> originalError;\n }\n\n // Pass the message to the base class Error\n super(originalError.message, 'VMRuntimeError');\n\n // Handle AggregateError\n if (originalError instanceof AggregateError && Array.isArray(originalError.errors)) {\n // Process nested errors\n this.errors = originalError.errors.map(error =>\n new VMRuntimeError(error, options)\n );\n }\n\n this.stack = originalError.stack;\n this.message = originalError.message;\n this.reformatStack(originalError, options);\n }\n\n /**\n * Custom Node.js inspect method for displaying the error in the console.\n *\n * @returns A string representation of the formatted stack trace, or\n * a concatenated list of nested errors if present.\n *\n * @remarks\n * Overrides the Node.js default inspection behavior.\n * If this instance contains nested errors, they are listed with their formatted stacks.\n *\n * @since 1.0.0\n */\n\n [Symbol.for('nodejs.util.inspect.custom')](): string | undefined {\n if (this.errors && this.errors.length > 0) {\n const errorList = this.errors.map(\n (error) => `${ error.formattedStack ?? error.stack }`\n ).join('');\n\n return `VMRuntimeError Contains ${ this.errors.length } nested errors:\\n${ errorList }\\n`;\n }\n\n return this.formattedStack ?? this.stack;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { BuildOptions, BuildResult, Metafile } from 'esbuild';\nimport type { ESBuildErrorInterface } from '@errors/interfaces/esbuild-error.interface';\nimport type { TranspileFileInterface, TranspileFileType } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport { cwd } from 'process';\nimport { build } from 'esbuild';\nimport { xJetError } from '@errors/xjet.error';\nimport { esBuildError } from '@errors/esbuild.error';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * Default ESBuild options used when building or transpiling files.\n *\n * @remarks\n * These defaults bundle, minify, preserve symlinks, and generate external sourcemaps\n * targeting modern browser environments.\n *\n * see BuildOptions\n * @since 1.0.0\n */\n\nexport const defaultBuildOptions: BuildOptions = {\n write: false,\n bundle: true,\n minify: true,\n outdir: `${ cwd() }`,\n format: 'esm',\n target: 'esnext',\n platform: 'browser',\n sourcemap: 'external',\n mangleQuoted: true,\n sourcesContent: true,\n preserveSymlinks: true\n};\n\n/**\n * Builds multiple files using ESBuild with specified options.\n *\n * @param filePaths - Array of entry points to build\n * @param buildOptions - Optional override build options\n *\n * @returns A promise resolving to an ESBuild BuildResult including metafile information\n *\n * @throws esBuildError - Thrown if ESBuild encounters errors during build\n *\n * @remarks\n * This function merges user-provided options with default options and ensures\n * that a metafile is generated. If any errors occur during the build, they are\n * wrapped in a {@link esBuildError} for consistent error reporting.\n *\n * @example\n * ```ts\n * const result = await buildFiles(['src/index.ts'], { minify: false });\n * console.log(result.outputFiles);\n * ```\n *\n * @see esBuildError\n * @since 1.0.0\n */\n\nexport async function buildFiles(filePaths: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<BuildResult<BuildOptions & Metafile>> {\n try {\n return await build({\n absWorkingDir: cwd(),\n ...defaultBuildOptions,\n ...buildOptions,\n metafile: true,\n entryPoints: filePaths\n }) as BuildResult<BuildOptions & Metafile>;\n } catch (esbuildErrors) {\n throw new esBuildError(<ESBuildErrorInterface> esbuildErrors);\n }\n}\n\n/**\n * Transpiles multiple files and returns their output code and paths.\n *\n * @param filePaths - Array of files to transpile\n * @param buildOptions - Optional override ESBuild options\n *\n * @returns A promise resolving to an array of transpiled files with paths and code\n *\n * @remarks\n * Output files ending with `.js.map` are registered with the {@link FrameworkService}.\n * Only `.js` files are returned in the result array for further processing.\n *\n * @example\n * ```ts\n * const transpiled = await transpileFiles(['src/index.ts']);\n * console.log(transpiled[0].path, transpiled[0].code);\n * ```\n *\n * @see buildFiles\n * @see FrameworkService\n *\n * @since 1.0.0\n */\n\nexport async function transpileFiles(filePaths: BuildOptions['entryPoints'], buildOptions: BuildOptions = {}): Promise<TranspileFileType> {\n const result = await buildFiles(filePaths, buildOptions);\n\n const transpiled: TranspileFileType = [];\n const outputFiles = result.outputFiles ?? [];\n const framework = inject(FrameworkService);\n\n for (const file of outputFiles) {\n const basePath = file.path.replace(/\\.(map)$/, '');\n const isSourceMap = file.path.endsWith('.js.map');\n const isJsFile = file.path.endsWith('.js');\n\n if (isSourceMap) {\n framework.setSource(file.text, basePath);\n } else if (isJsFile) {\n transpiled.push({\n path: basePath,\n code: file.text\n });\n }\n }\n\n return transpiled;\n}\n\n/**\n * Transpiles a single file and returns its output code and path.\n *\n * @param filePath - The path of the file to transpile\n * @param buildOptions - Optional override ESBuild options\n *\n * @returns A promise resolving to a single transpiled file object\n *\n * @throws xJetError - Thrown if no output is generated for the file\n *\n * @remarks\n * Internally calls {@link transpileFiles} with a single-element array and returns\n * the first result. Ensures consistent error reporting if the transpilation fails.\n *\n * @example\n * ```ts\n * const file = await transpileFile('src/index.ts');\n * console.log(file.path, file.code);\n * ```\n *\n * @see xJetError\n * @see transpileFiles\n *\n * @since 1.0.0\n */\n\nexport async function transpileFile(filePath: string, buildOptions: BuildOptions = {}): Promise<TranspileFileInterface> {\n const files = await transpileFiles([ filePath ], buildOptions);\n const result = files.shift();\n if (!result) {\n throw new xJetError('Failed to transpile file: No output generated');\n }\n\n return result;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\n\n/**\n * Represents a generic xJet framework error.\n *\n * Extends {@link xJetBaseError} and automatically formats the stack trace\n * according to the provided options.\n *\n * @remarks\n * This class is intended for general-purpose errors within the xJet framework.\n * The stack trace is formatted automatically during construction, with\n * framework-specific frames included by default.\n *\n * @example\n * ```ts\n * throw new xJetError('An unexpected error occurred');\n * ```\n *\n * @since 1.0.0\n */\n\nexport class xJetError extends xJetBaseError {\n\n /**\n * Creates a new instance of `xJetError`.\n *\n * @param message - The error message to display\n * @param options - Optional stack trace formatting options (default includes framework frames)\n *\n * @remarks\n * The constructor passes the message to the base `xJetBaseError` class,\n * then reformats the stack trace using {@link xJetBaseError.reformatStack}.\n *\n * @since 1.0.0\n */\n\n constructor(message: string, options: StackTraceInterface = { withFrameworkFrames: true }) {\n // Pass the message to the base class Error\n super(message);\n this.reformatStack(this, options);\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { ESBuildErrorInterface, ESBuildAggregateErrorInterface } from '@errors/interfaces/esbuild-error.interface';\n\n/**\n * Imports\n */\n\nimport { xJetBaseError } from '@errors/base.error';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { formatCode } from '@remotex-labs/xmap/formatter.component';\nimport { highlightCode } from '@remotex-labs/xmap/highlighter.component';\n\n/**\n * Represents an error produced by ESBuild during the build process.\n *\n * Extends {@link xJetBaseError} and provides formatted output for\n * individual or aggregated ESBuild errors.\n *\n * @remarks\n * If the error contains aggregate errors (`aggregateErrors`), each error\n * is formatted with colorized output, code highlighting, and positional\n * information. Otherwise, a standard stack trace is generated.\n *\n * @example\n * ```ts\n * import { esBuildError } from '@errors/esbuild.error';\n *\n * try {\n * // some ESBuild operation\n * } catch (error) {\n * throw new esBuildError(error as ESBuildErrorInterface);\n * }\n * ```\n *\n * @see xJetBaseError\n * @see ESBuildErrorInterface\n * @see ESBuildAggregateErrorInterface\n *\n * @since 1.0.0\n */\n\nexport class esBuildError extends xJetBaseError {\n /**\n * Creates a new `esBuildError` instance.\n *\n * @param error - The ESBuild error object to wrap\n *\n * @remarks\n * The constructor checks if the error contains `aggregateErrors` and\n * formats each entry with syntax highlighting and positional information.\n * If not, the error is reformatted using the base error's stack formatting.\n *\n * @since 1.0.0\n */\n\n constructor(error: ESBuildErrorInterface) {\n super('esBuildError build failed', 'esBuildError');\n\n if (error.aggregateErrors) this.formatAggregateErrors(error.aggregateErrors);\n else this.reformatStack(error, { withFrameworkFrames: true });\n }\n\n /**\n * Formats a list of ESBuild aggregate errors into a single, colorized stack string.\n *\n * @param errors - Array of ESBuild aggregate errors\n *\n * @remarks\n * Each error is highlighted using {@link highlightCode} and {@link formatCode},\n * and includes file location, line, and column for easier debugging.\n *\n * @since 1.0.0\n */\n\n private formatAggregateErrors(errors: Array<ESBuildAggregateErrorInterface>): void {\n this.formattedStack = '';\n\n for (const error of errors) {\n this.formattedStack += `\\n${ this.name }: \\n${ xterm.lightCoral(`${ error.text }: ${ error.notes.pop()?.text }`) }\\n\\n`;\n this.formattedStack += formatCode(highlightCode(error.location.lineText.trim()), {\n startLine: error.location.line\n });\n\n this.formattedStack += '\\n\\n';\n this.formattedStack += `at ${ xterm.dim(error.location.file) } ${\n xterm.gray(`[${ error.location.line }:${ error.location.column }]`)\n }\\n\\n`;\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractTarget } from '@targets/abstract/target.abstract';\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { join } from 'path';\nimport { exit } from 'process';\nimport { WatchService } from '@services/watch.service';\nimport { getSpecFiles } from '@providers/specs.provider';\nimport { inject } from '@symlinks/services/inject.service';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { transpileFiles } from '@services/transpiler.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { getReporter } from '@messages/services/reports.service';\nimport { MessageService } from '@messages/services/message.service';\nimport { ExternalService, LocalService } from '@targets/target.module';\n\n/**\n * Code banner injected at the top of transpiled JavaScript files.\n *\n * @remarks\n * This is passed to the transpiler (esbuild) to ensure a clean newline\n * at the start of each bundled file. It can also be extended later to\n * include configuration headers, metadata, or runtime bootstrap code.\n *\n * @since 1.0.0\n */\n\nconst banner = {\n js: '\\n'\n};\n\n/**\n * Code footer injected at the bottom of transpiled JavaScript files.\n *\n * @remarks\n * Ensures that once the suite code is fully bundled and loaded,\n * the `state.run({})` function is invoked to start the test execution lifecycle.\n *\n * @since 1.0.0\n */\n\nconst footer = {\n js: 'state.run({})'\n};\n\n/**\n * Service responsible for executing, transpiling, and managing test suites.\n *\n * @remarks\n * The `SuitesService` class handles the lifecycle of test execution:\n * - Locating and transpiling spec files.\n * - Initializing the target environment (local or external).\n * - Managing reporters and error states.\n * - Optionally watching for changes and re-running tests.\n *\n * It uses injected services like {@link FrameworkService}, {@link MessageService},\n * and target services ({@link LocalService} / {@link ExternalService}) to orchestrate the process.\n *\n * @example\n * ```ts\n * const service = new SuitesService(config);\n * await service.executeSuites();\n * ```\n *\n * @since 1.0.0\n */\n\nexport class SuitesService {\n /**\n * Reference to the currently active test target.\n *\n * @remarks\n * This property is initialized once during construction\n * and cannot be reassigned afterward due to the `readonly` modifier.\n * It resolves to either a `LocalService` or `ExternalService`,\n * both of which extend the abstract target contract (`AbstractTarget`).\n *\n * @since 1.0.0\n */\n\n private readonly target: AbstractTarget;\n\n /**\n * Instance of the {@link FrameworkService} injected via the DI container.\n *\n * @remarks\n * This property is resolved once during class instantiation and cannot\n * be reassigned due to the `readonly` modifier. It provides access to\n * framework-level paths, configuration, and shared utilities.\n *\n * @since 1.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Creates an instance of {@link SuitesService}.\n *\n * @param config - The runtime configuration object that defines\n * suite files, build options, runners, and other\n * execution parameters.\n *\n * @remarks\n * The constructor initializes the {@link target} by invoking\n * {@link SuitesService.createTarget | createTarget}, ensuring the\n * appropriate execution environment (local or external) is selected\n * based on the provided configuration.\n *\n * @since 1.0.0\n */\n\n constructor(private config: ConfigurationInterface) {\n this.target = this.createTarget();\n }\n\n /**\n * Executes all discovered test suites based on the current configuration.\n *\n * @remarks\n * This method orchestrates the end-to-end lifecycle of test execution:\n *\n * - Discovers suite files using {@link getSpecFiles}.\n * - Validates that test files are available, throwing an error if none are found.\n * - Initializes the configured {@link AbstractTarget}, such as a local or external runner.\n * - Creates a {@link MessageService} with the selected reporter to handle\n * event reporting and error tracking.\n * - Transpiles and executes suites via {@link SuitesService.exec}.\n * - Optionally watches for file changes when `watch` mode is enabled.\n * - Frees target resources after execution completes.\n * - Terminates the process with exit codes depending on test outcomes:\n * - `0` if all suites passed.\n * - `1` if any test error occurred.\n * - `2` if any suite-level error occurred.\n *\n * @throws Error If no test files matching the configuration are found.\n *\n * @example\n * ```ts\n * const service = new SuitesService(config);\n * await service.executeSuites();\n * ```\n *\n * @since 1.0.0\n */\n\n async executeSuites(): Promise<void> {\n const specsFiles = getSpecFiles(this.framework.rootPath, this.config);\n if (Object.keys(specsFiles).length === 0) {\n if(this.config.suites.length > 0)\n throw xterm.redBright('No test files found for ') + xterm.greenBright(this.config.suites.join(', '));\n\n throw xterm.redBright('No test files found for ') + xterm.greenBright(this.config.files.join(', '));\n }\n\n await this.target.initTarget?.();\n const message = new MessageService(this.target, await getReporter(this.config));\n await this.exec(message, specsFiles);\n\n if (this.config.watch) {\n await this.watchForChanges(message, specsFiles);\n }\n\n await this.target.freeTarget?.();\n\n if (message.hasError) exit(1);\n if (message.hasSuiteError) exit(2);\n exit(0);\n }\n\n /**\n * Executes a single run of the provided test suites.\n *\n * @remarks\n * This method performs the following tasks in sequence:\n * - Initializes the reporter with discovered suite file paths and available runners.\n * - Transpiles the test suite files into executable format.\n * - Delegates execution to the configured {@link AbstractTarget}.\n * - Finalizes reporting by calling the reporter\u2019s `finish` method.\n *\n * @param message - The {@link MessageService} instance responsible for reporting\n * events and aggregating errors during execution.\n * @param specsFiles - A record mapping suite identifiers to their file system paths.\n *\n * @example\n * ```ts\n * const message = new MessageService(target, reporter);\n * await this.exec(message, { 'suite1': '/path/to/suite1.spec.ts' });\n * ```\n *\n * @since 1.0.0\n */\n\n private async exec(message: MessageService, specsFiles: Record<string, string>): Promise<void> {\n message.reporter.init?.(Object.values(specsFiles), message.target.getRunners());\n const transpiled = await this.transpileSuites(specsFiles);\n await this.target.executeSuites(transpiled, specsFiles);\n message.reporter.finish?.();\n }\n\n /**\n * Creates and returns the appropriate test execution target.\n *\n * @remarks\n * This method determines whether to use an {@link ExternalService}\n * or {@link LocalService} as the execution target based on the presence\n * of configured test runners in {@link ConfigurationInterface.testRunners}.\n *\n * - If one or more `testRunners` are specified, an {@link ExternalService} is injected.\n * - Otherwise, a {@link LocalService} is injected.\n *\n * @returns An {@link AbstractTarget} instance configured according to the current setup.\n *\n * @example\n * ```ts\n * const target = this.createTarget();\n * await target.initTarget?.();\n * ```\n *\n * @see AbstractTarget\n * @see ExternalService\n * @see LocalService\n *\n * @since 1.0.0\n */\n\n private createTarget(): AbstractTarget {\n return (this.config.testRunners && this.config.testRunners.length > 0)\n ? inject(ExternalService, this.config)\n : inject(LocalService, this.config);\n }\n\n /**\n * Initializes a watch mode to monitor test files for changes.\n *\n * @remarks\n * This method sets up a {@link WatchService} that observes the provided\n * test specification files (`specsFiles`).\n * When a change is detected, the suite execution is re-triggered\n * using the {@link SuitesService.exec | exec} method bound to the given {@link MessageService}.\n *\n * This enables continuous testing in development environments when\n * the `watch` option is enabled in {@link ConfigurationInterface}.\n *\n * @param message - The active {@link MessageService} used for reporting\n * and coordinating suite execution.\n * @param specsFiles - A record of spec file identifiers mapped to their file paths.\n *\n * @returns A `Promise` that resolves when the {@link WatchService} is fully initialized.\n *\n * @example\n * ```ts\n * if (this.config.watch) {\n * await this.watchForChanges(message, specsFiles);\n * }\n * ```\n *\n * @see WatchService\n * @see SuitesService.exec\n *\n * @since 1.0.0\n */\n\n private async watchForChanges(message: MessageService, specsFiles: Record<string, string>): Promise<void> {\n const watcher = new WatchService(this.config, specsFiles, this.exec.bind(this, message));\n await watcher.init();\n }\n\n /**\n * Transpiles the given test specification files according to the configured build options.\n *\n * @remarks\n * This method uses {@link transpileFiles} to process the test files, applying\n * the build configuration from {@link ConfigurationInterface.build}.\n * It automatically injects shared dependencies, applies a banner and footer, and\n * enforces the CommonJS module format (`cjs`).\n * Minification is disabled, but syntax and whitespace optimizations are applied.\n *\n * @param filePaths - A record mapping identifiers to the absolute paths of the test files\n * that need to be transpiled.\n *\n * @returns A `Promise` resolving to a {@link TranspileFileType} object containing\n * the transpiled outputs.\n *\n * @example\n * ```ts\n * const transpiled = await this.transpileSuites({\n * 'example.test.ts': '/path/to/example.test.ts'\n * });\n * ```\n *\n * @see transpileFiles\n * @see ConfigurationInterface.build\n *\n * @since 1.0.0\n */\n\n private async transpileSuites(filePaths: Record<string, string>): Promise<TranspileFileType> {\n return await transpileFiles(filePaths, {\n ...this.config.build,\n banner,\n footer,\n format: 'cjs',\n minify: false,\n inject: [ join(this.framework.distPath, 'shared.js') ],\n logLevel: 'silent',\n sourcemap: true,\n minifySyntax: true,\n preserveSymlinks: true,\n minifyWhitespace: true,\n minifyIdentifiers: false,\n define: {\n 'import.meta': 'import_meta'\n }\n });\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TestExecutionType } from '@services/interfaces/watch-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { accessSync } from 'fs';\nimport { readFile, watch } from 'fs/promises';\nimport { dirname, join, normalize } from 'path';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { compilePatterns, matchesAny } from '@components/glob.component';\nimport { resolveImport, updateAliases } from '@providers/import-resolver.provider';\n\n/**\n * Service for watching the project filesystem and re-running only the tests\n * affected by file changes.\n *\n * @remarks\n * The service maintains a dependency graph that maps source files to test files.\n * When a file changes:\n * - If it's a test file, that file is re-executed.\n * - If it's a dependency of one or more test files, all dependent test files are re-executed.\n * - Deleted files are removed from the graph automatically.\n *\n * The watcher uses a debounced handler (default 400 ms) to batch multiple\n * filesystem changes before re-running tests.\n *\n * @example\n * ```ts\n * const service = new WatchService(config, specFiles, async (suites) => {\n * console.log('Re-running tests:', suites);\n * });\n * await service.init();\n * ```\n *\n * @see compilePatterns\n * @see matchesAny\n * @since 1.0.0\n */\n\nexport class WatchService {\n /**\n * Regular expression for matching ESM-style import paths.\n *\n * @remarks\n * Captures module specifiers from statements such as\n * - `import x from 'module'`\n * - `import { y } from \"module\"`\n *\n * The named capture group `path` contains the module specifier string.\n *\n * @example\n * ```ts\n * const code = \"import { readFile } from 'fs';\";\n * const match = WatchService.IMPORT_REGEX.exec(code);\n * console.log(match?.groups?.path); // \"fs\"\n * ```\n *\n * @since 1.0.0\n */\n\n private static readonly IMPORT_REGEX = /(?:from|import)\\s+['\"](?<path>[^'\"]+)['\"]/g;\n\n /**\n * Regular expression for matching a file extension.\n *\n * @remarks\n * Matches the last dot (`.`) in a file name and all following characters,\n * excluding additional dots or path separators.\n * Effectively isolates the extension from a file path.\n *\n * @example\n * ```ts\n * const file = \"example.test.ts\";\n * const match = WatchService.FILE_EXTENSION_REGEX.exec(file);\n * console.log(match?.[0]); // \".ts\"\n * ```\n *\n * Useful for stripping extensions when normalizing or mapping test files.\n *\n * @since 1.0.0\n */\n\n private static readonly FILE_EXTENSION_REGEX = /\\.[^/.]+$/;\n\n /**\n * Reference to the core {@link FrameworkService}.\n *\n * @remarks\n * Injected via the {@link inject} helper, this service provides access to\n * framework-level configuration such as the project root path, runtime\n * environment, and shared utilities.\n * It is used here for resolving relative paths and coordinating with the\n * broader testing infrastructure.\n *\n * @see inject\n * @see FrameworkService\n *\n * @since 1.0.0\n */\n\n private readonly framework: FrameworkService = inject(FrameworkService);\n\n /**\n * Tracks the dependency relationships between source files and test files.\n *\n * @remarks\n * Each key is a file path (either a source or test file), and its value is a set of\n * test files that depend on it. This graph is used to determine which tests\n * need to be re-executed when a file changes.\n *\n * @example\n * ```ts\n * // If \"utils.ts\" changes, all dependent tests are retrieved:\n * const affectedTests = dependencyGraph.get('src/utils.ts');\n * ```\n *\n * @since 1.0.0\n */\n\n private readonly dependencyGraph: Map<string, Set<string>> = new Map();\n\n /**\n * Caches the list of direct dependencies for each file.\n *\n * @remarks\n * Each key is a file path, and the corresponding value is an array of file paths\n * that the key file directly imports. This cache avoids repeated parsing of\n * files when tracking changes in the dependency graph.\n *\n * @example\n * ```ts\n * const deps = dependenciesCache.get('src/test/example.spec.ts');\n * // deps might be ['src/utils.ts', 'src/helpers.ts']\n * ```\n *\n * @since 1.0.0\n */\n\n private readonly dependenciesCache: Map<string, Array<string>> = new Map();\n\n /**\n * Timer used for debouncing file change events.\n *\n * @remarks\n * When multiple file changes occur in quick succession, this timer ensures that\n * the `handleChangedFiles` method is called only once after a short delay,\n * preventing redundant executions and improving performance.\n *\n * @since 1.0.0\n */\n\n private debounceTimer: NodeJS.Timeout | null = null;\n\n /**\n * Compiled regular expressions for test file inclusion.\n *\n * @remarks\n * These patterns are derived from the user's configuration (`config.files`) and\n * are used to determine which files should be treated as test/spec files during\n * watch or execution.\n *\n * @since 1.0.0\n */\n\n private readonly patterns: Array<RegExp>;\n\n /**\n * Compiled regular expressions for file exclusion.\n *\n * @remarks\n * These patterns are derived from the user's configuration (`config.exclude`) and\n * are used to ignore files or directories when scanning for test files or\n * tracking dependencies.\n *\n * @since 1.0.0\n */\n\n private readonly excludes: Array<RegExp>;\n\n /**\n * Initializes the WatchService for monitoring test files and their dependencies.\n *\n * @param config - Configuration object containing `files` and `exclude` patterns.\n * @param testsFile - Map of test file relative paths to absolute paths.\n * @param exec - Callback invoked with the changed suites when a relevant file changes.\n *\n * @remarks\n * The constructor compiles the provided file inclusion and exclusion patterns\n * and prepares internal caches for dependency tracking. This sets up the service\n * for watching test files and their imported dependencies for changes.\n *\n * @since 1.0.0\n */\n\n constructor(config: ConfigurationInterface, private testsFile: Record<string, string>, private exec: TestExecutionType) {\n updateAliases();\n this.patterns = compilePatterns(config?.files ?? []);\n this.excludes = compilePatterns(config?.exclude ?? []);\n }\n\n /**\n * Initializes the file watcher and builds the initial dependency graph.\n *\n * @remarks\n * This method performs the following steps:\n * 1. Updates the dependency graph for all known test files.\n * 2. Sets up a recursive file system watcher on the framework's root directory.\n * 3. On file changes, normalizes paths, filters excluded files, and schedules\n * handling of changed files with a debouncing to avoid excessive executions.\n *\n * @returns A promise that resolves when the watcher is ready.\n *\n * @since 1.0.0\n */\n\n async init(): Promise<void> {\n await Promise.all(Object.values(this.testsFile).map(\n (testFile) => this.updateGraph(testFile))\n );\n\n const changedFilesSet = new Set<string>();\n const watcher = watch(this.framework.rootPath, { recursive: true });\n for await (const { filename } of watcher) {\n if (!filename) continue;\n\n const fullPath = normalize(filename);\n if (matchesAny(fullPath, this.excludes)) continue;\n\n changedFilesSet.add(fullPath);\n this.debounce(() => this.handleChangedFiles([ ...changedFilesSet ], changedFilesSet));\n }\n }\n\n /**\n * Debounce the execution of a function to limit how frequently it runs.\n *\n * @param fn - The function to execute after the debounce delay.\n * @param delay - Optional debounce delay in milliseconds (default is 400 ms).\n *\n * @remarks\n * If multiple calls are made within the delay period, only the last one will execute.\n * This is used in the file watcher to prevent excessive calls to handle file changes\n * when multiple filesystem events occur in quick succession.\n *\n * @since 1.0.0\n */\n\n private debounce(fn: () => void, delay = 400): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(fn, delay);\n }\n\n /**\n * Checks whether a file exists on the filesystem.\n *\n * @param file - Absolute or relative path to the file.\n * @returns `true` if the file exists and is accessible, otherwise `false`.\n *\n * @remarks\n * This method uses synchronous filesystem access to determine the file's existence.\n * It is primarily used by the watcher to verify that a changed file still exists\n * before processing it.\n *\n * @since 1.0.0\n */\n\n private fileExists(file: string): boolean {\n try {\n accessSync(file);\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Removes a file and all its associations from the dependency graph.\n *\n * @param file - The absolute path of the file to remove.\n *\n * @remarks\n * This method removes the file from both the main `dependencyGraph` and the\n * `dependenciesCache`. It also ensures that any other files that depend on this\n * file no longer reference it as a dependency. This is useful when a file is\n * deleted or no longer relevant to the test execution.\n *\n * @since 1.0.0\n */\n\n private removeFileFromGraph(file: string): void {\n this.dependencyGraph.delete(file);\n this.dependenciesCache.delete(file);\n\n for (const dependents of this.dependencyGraph.values()) {\n dependents.delete(file);\n }\n }\n\n /**\n * Processes a batch of changed files, updates the dependency graph, and triggers test execution.\n *\n * @param changedFiles - Array of absolute paths for files that have changed.\n * @param changedFilesSet - Set used for debouncing and tracking currently changed files.\n *\n * @remarks\n * For each file in `changedFiles`:\n * 1. If the file no longer exists, it is removed from the dependency graph.\n * 2. If the file matches test patterns, the dependency graph is updated and the file is queued for execution.\n * 3. If the file is a dependency of any test files, those dependent test files are also updated and queued.\n *\n * Once all relevant test files are collected, the `exec` function is called with a map of suite IDs to their absolute file paths.\n *\n * @since 1.0.0\n */\n\n private async handleChangedFiles(changedFiles: string[], changedFilesSet: Set<string>): Promise<void> {\n changedFilesSet.clear();\n const suites: Record<string, string> = {};\n\n for (const file of changedFiles) {\n if (!this.fileExists(file)) {\n this.removeFileFromGraph(file);\n continue;\n }\n\n if (matchesAny(file, this.patterns)) {\n await this.updateGraph(file);\n const key = file.replace(WatchService.FILE_EXTENSION_REGEX, '');\n suites[key] = file;\n }\n\n if (this.dependencyGraph.has(file)) {\n await this.updateGraph(file);\n this.dependencyGraph.get(file)?.forEach(suite => {\n const key = suite.replace(WatchService.FILE_EXTENSION_REGEX, '');\n suites[key] = suite;\n });\n }\n }\n\n if (Object.keys(suites).length > 0) {\n await this.exec(suites);\n }\n }\n\n /**\n * Extracts and returns all TypeScript dependencies for a given test file.\n *\n * @param target - Absolute path of the file to analyze for imports.\n * @param force - If `true`, bypasses the cache and recomputes dependencies.\n * @returns An array of absolute paths representing the imported files.\n *\n * @remarks\n * This function reads the file content, matches all `import` or `from` statements\n * using the {@link WatchService.IMPORT_REGEX}, and resolves relative paths to absolute paths.\n * Results are cached in {@link dependenciesCache} for faster lookups.\n *\n * @example\n * ```ts\n * const deps = await getTestDependencies('/project/tests/unit/example.spec.ts');\n * console.log(deps); // ['/project/src/util.ts', '/project/src/helper.ts', ...]\n * ```\n *\n * @since 1.0.0\n */\n\n private async getTestDependencies(target: string, force: boolean = false): Promise<Array<string>> {\n if (!force && this.dependenciesCache.has(target)) {\n return this.dependenciesCache.get(target)!;\n }\n\n try {\n const content = await readFile(target, 'utf-8');\n const dependencies: string[] = [];\n\n for (const match of content.matchAll(WatchService.IMPORT_REGEX)) {\n const importPath = match.groups?.path;\n if (!importPath) continue;\n\n const path = resolveImport(importPath) ?? join(dirname(target), importPath);\n dependencies.push(path.endsWith('.ts') ? path : `${ path }.ts`);\n }\n\n this.dependenciesCache.set(target, dependencies);\n\n return dependencies;\n } catch {\n this.dependenciesCache.set(target, []);\n\n return [];\n }\n }\n\n /**\n * Recursively links a set of test files to their dependencies in the dependency graph.\n *\n * @param testFiles - Array of test file paths that depend on the given dependencies.\n * @param dependencies - Array of dependency file paths to link to the test files.\n *\n * @remarks\n * This function ensures that any changes in a dependency file can trigger re-execution\n * of all test files that depend on it. It also recursively processes nested dependencies\n * by calling {@link getTestDependencies} for each dependency.\n *\n * @example\n * ```ts\n * await linkDependency(['tests/unit/example.spec.ts'], ['src/util.ts']);\n * ```\n *\n * @since 1.0.0\n */\n\n private async linkDependency(testFiles: Array<string>, dependencies: Array<string>): Promise<void> {\n for (const dep of dependencies) {\n const depSet = this.dependencyGraph.get(dep) ?? new Set<string>();\n const originalSize = depSet.size;\n testFiles.forEach((test) => depSet.add(test));\n\n if (!this.dependencyGraph.has(dep)) {\n this.dependencyGraph.set(dep, depSet);\n }\n\n if (depSet.size > originalSize) {\n const nestedDeps = await this.getTestDependencies(dep);\n if (nestedDeps.length > 0) {\n await this.linkDependency(testFiles, nestedDeps);\n }\n }\n }\n }\n\n /**\n * Updates the dependency graph for a changed file.\n *\n * @param changedFile - The absolute path of the file that has changed.\n *\n * @remarks\n * This method ensures that the dependency graph remains up to date when a file changes:\n * - If the changed file is a test file (matches the configured patterns), its direct dependencies\n * are retrieved using {@link getTestDependencies} and linked via {@link linkDependency}.\n * - If the changed file is a dependency for other test files, all dependent test files are updated\n * recursively to include the changed file's dependencies.\n *\n * The dependency graph allows the watch service to re-run only affected test files when a source\n * or test file changes, improving efficiency during watch mode.\n *\n * @example\n * ```ts\n * await updateGraph('tests/unit/example.spec.ts');\n * ```\n *\n * @since 1.0.0\n */\n\n private async updateGraph(changedFile: string): Promise<void> {\n const isTestFile = matchesAny(changedFile, this.patterns);\n\n if (isTestFile) {\n const deps = await this.getTestDependencies(changedFile, true);\n await this.linkDependency([ changedFile ], deps);\n } else if (this.dependencyGraph.has(changedFile)) {\n const testFiles = [ ...this.dependencyGraph.get(changedFile)! ];\n const deps = await this.getTestDependencies(changedFile, true);\n await this.linkDependency(testFiles, deps);\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Dirent } from 'fs';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\n\n/**\n * Imports\n */\n\nimport { join, relative } from 'path';\nimport { existsSync, readdirSync } from 'fs';\nimport { inject } from '@symlinks/symlinks.module';\nimport { FrameworkService } from '@services/framework.service';\nimport { compilePatterns, matchesAny } from '@components/glob.component';\n\n/**\n * Computes the relative path of a file from the project root.\n *\n * @param path - The full absolute path of the file.\n * @returns The file path relative to the root.\n *\n * @since 1.0.0\n */\n\nexport function getRelativePath(path: string): string {\n return relative(inject(FrameworkService).rootPath, path);\n}\n\n/**\n * Recursively collects test files from a directory matching include patterns and not matching exclude patterns.\n *\n * @param dir - Directory to scan.\n * @param patterns - Regex patterns for files to include.\n * @param excludes - Regex patterns for files to exclude.\n * @param suites - Regex patterns for test suites to include (temp suite filter).\n * @param specFiles - Optional accumulator for collected files.\n * @returns A map of relative file paths to absolute paths.\n *\n * @remarks\n * This function traverses the directory tree, skips excluded paths early, and collects files that\n * match both suite and file patterns. The `FrameworkService` is used to compute relative paths.\n *\n * @since 1.0.0\n */\n\nexport function collectFilesFromDir(\n dir: string, patterns: Array<RegExp>, excludes: Array<RegExp>, suites: Array<RegExp>, specFiles: Record<string, string> = {}\n): Record<string, string> {\n if (!existsSync(dir)) return {};\n const entries: Array<Dirent> = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = getRelativePath(fullPath);\n\n if (matchesAny(relativePath, excludes))\n continue;\n\n if (entry.isDirectory()) {\n collectFilesFromDir(fullPath, patterns, excludes, suites, specFiles);\n continue;\n }\n\n const allowSuite = suites.length === 0 || matchesAny(relativePath, suites);\n if (allowSuite && matchesAny(fullPath, patterns)) {\n const relativeFilePath = relativePath;\n const key = relativeFilePath.replace(/\\.[^/.]+$/, '');\n\n specFiles[key] = relativeFilePath;\n }\n }\n\n return specFiles;\n}\n\n/**\n * Retrieves all test files from a directory based on the provided configuration and suite filters.\n *\n * @param dir - Root directory to scan for test files.\n * @param config - Configuration object containing `files` and `exclude` patterns.\n * @returns A map of relative file paths to absolute paths.\n *\n * @remarks\n * This function compiles configuration patterns into regular expressions and delegates\n * a file collection to {@link collectFilesFromDir}.\n * It supports filtering by:\n * - **files** \u2192 which files to include\n * - **exclude** \u2192 which files or directories to skip\n * - **suites** \u2192 optional suite-specific filters;\n *\n * @example\n * ```ts\n * const specFiles = getSpecFiles('/project/tests', config, [/unit/]);\n * console.log(specFiles);\n * // { 'unit/test1.spec.ts': '/project/tests/unit/test1.spec.ts', ... }\n * ```\n *\n * @see collectFilesFromDir\n * @since 1.0.0\n */\n\nexport function getSpecFiles(dir: string, config: ConfigurationInterface): Record<string, string> {\n const suitesRegex = compilePatterns(config?.suites ?? []);\n const patternsRegex = compilePatterns(config?.files ?? []);\n const excludesRegex = compilePatterns(config?.exclude ?? []);\n\n return collectFilesFromDir(dir, patternsRegex, excludesRegex, suitesRegex);\n}\n", "/**\n * Constants\n */\n\nimport { getRelativePath } from '@providers/specs.provider';\n\n/**\n * Matches a single-character glob symbol (`?`).\n *\n * @remarks\n * In glob patterns, `?` matches exactly one character.\n *\n * @since 1.0.0\n */\n\nconst QUESTION_MARK = /\\?/g;\n\n/**\n * Matches brace expansion groups in glob patterns (e.g. `{a,b,c}`).\n *\n * @remarks\n * Brace groups expand into multiple alternatives separated by commas.\n *\n * @since 1.0.0\n */\n\nconst BRACE_PATTERN = /\\{([^}]+)\\}/g;\n\n/**\n * Matches double asterisks (`**`) used in glob patterns.\n *\n * @remarks\n * `**` typically represents recursive directory matching.\n *\n * @since 1.0.0\n */\n\nconst DOUBLE_ASTERISK = /(?:\\/|^)\\*{2}(?:\\/|$)/g;\n\n/**\n * Matches a single asterisk (`*`) in glob patterns.\n *\n * @remarks\n * `*` matches zero or more characters within a single directory segment.\n *\n * @since 1.0.0\n */\n\nconst SINGLE_ASTERISK = /(?<!\\.)\\*/g;\n\n/**\n * Matches escaped character classes in glob patterns (e.g. `[abc]`).\n *\n * @remarks\n * Used to translate character class expressions into regex equivalents.\n *\n * @since 1.0.0\n */\n\nconst CHARACTER_CLASS = /\\\\\\[([^\\]]+)\\\\\\]/g;\n\n/**\n * Matches special regex characters that need escaping.\n *\n * @remarks\n * Ensures that characters like `.`, `+`, `$`, `|`, `[]`, `\\`\n * are properly escaped when compiling glob patterns.\n *\n * @since 1.0.0\n */\n\nconst REGEX_SPECIAL_CHARS = /[.+$|[\\]\\\\]/g;\n\n/**\n * Compiles a glob pattern into a corresponding regular expression.\n *\n * @param globPattern - The glob pattern string to convert.\n * @returns A `RegExp` instance that matches the given glob pattern.\n *\n * @remarks\n * This function converts common glob syntax into equivalent\n * regular expression syntax. It supports:\n * - `*` to match zero or more characters (excluding `/`)\n * - `**` to match across directories\n * - `?` to match exactly one character\n * - Character classes like `[abc]`\n * - Brace expansions like `{a,b,c}`\n *\n * Escapes regex-special characters before applying glob conversions\n * to ensure the resulting expression is valid.\n *\n * @example\n * ```ts\n * const regex = compileGlobPattern(\"src/**\\/*.ts\");\n * console.log(regex.test(\"src/utils/helpers.ts\")); // true\n * console.log(regex.test(\"dist/index.js\")); // false\n * ```\n *\n * @since 1.0.0\n */\n\nexport function compileGlobPattern(globPattern: string): RegExp {\n const escapeRegexChars = (pattern: string): string =>\n pattern.replace(REGEX_SPECIAL_CHARS, '\\\\$&');\n\n const convertGlobToRegex = (pattern: string): string => {\n return pattern\n .replace(QUESTION_MARK, '.')\n .replace(DOUBLE_ASTERISK, '.*\\/?')\n .replace(SINGLE_ASTERISK, '[^/]+')\n .replace(CHARACTER_CLASS, (_, chars) => `[${ chars }]`)\n .replace(BRACE_PATTERN, (_, choices) =>\n `(${ choices.split(',').join('|') })`);\n };\n\n return new RegExp(`^${ convertGlobToRegex(escapeRegexChars(globPattern)) }$`);\n}\n\n/**\n * Determines whether a given string is a glob pattern.\n *\n * @param str - The string to test.\n * @returns `true` if the string contains glob-like syntax, otherwise `false`.\n *\n * @remarks\n * This function checks for the presence of common glob syntax\n * characters (`*`, `?`, `[]`, `{}`, `!`, `@`, `+`, `()`, `|`),\n * brace expressions (e.g. `{a,b}`), and extglob patterns\n * (e.g. `@(pattern)`).\n *\n * It is useful for distinguishing between literal file paths\n * and glob patterns when working with file matching or build\n * tools.\n *\n * @example\n * ```ts\n * isGlob(\"src/**\\/*.ts\"); // true\n * isGlob(\"file.txt\"); // false\n * isGlob(\"lib/@(a|b).js\"); // true\n * ```\n *\n * @since 1.0.0\n */\n\nexport function isGlob(str: string): boolean {\n // Checks for common glob patterns including:\n // * ? [ ] { } ! @ + ( ) |\n const globCharacters = /[*?[\\]{}!@+()|\\]]/.test(str);\n\n // Check for brace expressions like {a,b}\n const hasBraces = /{[^}]+}/.test(str);\n\n // Check for extglob patterns like @(pattern)\n const hasExtglob = /@\\([^)]+\\)/.test(str);\n\n return globCharacters || hasBraces || hasExtglob;\n}\n\n/**\n * Determines whether a given path matches any of the provided regular expression patterns.\n *\n * @param path - The string path to check against the patterns.\n * @param patterns - An array of RegExp objects to test the path against.\n * @returns A boolean indicating whether the path matches any of the patterns.\n *\n * @remarks This function is commonly used in file filtering operations like\n * in the `collectFilesFromDir` function to determine which files to include\n * or exclude based on pattern matching.\n *\n * @example\n * ```ts\n * const isMatch = matchesAny('src/file.ts', [/\\.ts$/, /\\.js$/]);\n * console.log(isMatch); // true\n * ```\n *\n * @since 1.6.0\n */\n\nexport function matchesAny(path: string, patterns: Array<RegExp>): boolean {\n return patterns.some(regex => regex.test(path));\n}\n\n/**\n * Compiles an array of string/glob/regex patterns into {@link RegExp} objects.\n *\n * @remarks\n * - If an entry is already a `RegExp`, it is returned as-is.\n * - If an entry is a glob pattern (e.g. `src/**\\/*.test.ts`), it is compiled into a regex\n * using {@link compileGlobPattern}.\n * - Otherwise, literal file paths are converted into an exact-match regex,\n * with regex metacharacters properly escaped.\n *\n * @param patterns - A list of strings (paths, globs) or regular expressions.\n * @returns An array of {@link RegExp} objects ready for matching.\n *\n * @example\n * ```ts\n * const regexes = compilePatterns([\n * /\\.test\\.ts$/, // already a regex\n * \"src/utils/helper.ts\", // literal file path\n * \"tests/**\\/*.spec.ts\" // glob pattern\n * ]);\n *\n * matchesAnyRegex(\"src/utils/helper.ts\", regexes); // true\n * ```\n *\n * @since 1.0.0\n */\n\nexport function compilePatterns(patterns: Array<string | RegExp>): Array<RegExp> {\n return patterns.map(pattern => {\n if (pattern instanceof RegExp) {\n return pattern;\n }\n\n if (isGlob(pattern)) {\n return compileGlobPattern(pattern);\n }\n\n const escapedPattern = getRelativePath(pattern).replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n return new RegExp(`^${ escapedPattern }$`);\n });\n}\n", "/**\n * Imports\n */\n\nimport { relative } from 'path';\nimport { readFileSync } from 'fs';\nimport { pathToFileURL } from 'url';\nimport { createRequire } from 'module';\nimport { inject } from '@symlinks/symlinks.module';\nimport { FrameworkService } from '@services/framework.service';\n\n/**\n * A map storing TypeScript path aliases.\n *\n * @remarks\n * The keys are the alias patterns (with '*' removed), and the values are\n * the corresponding target paths (also with '*' removed).\n *\n * @example\n * ```ts\n * typescriptAlias.set('@app/', 'src/app/');\n * ```\n */\n\nexport const typescriptAlias = new Map<string, string>();\n\n/**\n * Updates the `typescriptAlias` map based on a `tsconfig.json` file.\n *\n * @param tsconfigPath - The path to the TypeScript configuration file.\n * Defaults to `'tsconfig.json'`.\n *\n * @remarks\n * Reads the `compilerOptions.paths` section and populates the alias map.\n * Only the first path in each entry is used, and any trailing '*' are removed.\n *\n * @example\n * ```ts\n * updateAliases(); // Uses default 'tsconfig.json'\n * updateAliases('configs/tsconfig.app.json'); // Custom path\n * ```\n */\n\nexport function updateAliases(tsconfigPath: string = 'tsconfig.json'): void {\n const raw = readFileSync(tsconfigPath, 'utf8');\n const json = JSON.parse(raw);\n const paths = json.compilerOptions?.paths;\n\n if (!paths) return;\n\n for (const [ key, value ] of Object.entries(paths)) {\n if (Array.isArray(value) && value.length > 0) {\n typescriptAlias.set(key.replace('*', ''), value[0].replace('*', ''));\n }\n }\n}\n\n/**\n * Resolves an import path to its relative path from the framework root.\n *\n * @param importPath - The import path to resolve.\n *\n * @returns The resolved relative path if found, otherwise `undefined`.\n *\n * @remarks\n * This function first checks the `typescriptAlias` map for a matching pattern.\n * If none is found, it attempts to resolve the module using Node's `require.resolve`.\n * The returned path is always relative to the framework's root path.\n *\n * @example\n * ```ts\n * const resolved = resolveImport('@app/utils');\n * // might return 'src/app/utils.ts' relative to framework root\n * ```\n */\n\nexport function resolveImport(importPath: string): string | undefined {\n const framework = inject(FrameworkService);\n for (const [ pattern, target ] of typescriptAlias.entries()) {\n if (importPath.includes(pattern)) {\n const resolved = importPath.replace(pattern, target);\n\n return relative(framework.rootPath, resolved);\n }\n }\n\n try {\n const require = createRequire(pathToFileURL(framework.rootPath + '/__placeholder__.js').href);\n const path = require.resolve(importPath);\n if(path) return relative(framework.rootPath, path);\n } catch {\n return;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractReporter } from '@messages/abstract/report.abstract';\nimport type { ReporterConstructorType } from '@messages/interfaces/abstract.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\nimport type { TranspileFileInterface } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport { existsSync } from 'fs';\nimport { createRequire } from 'module';\nimport { xJetError } from '@errors/xjet.error';\nimport { sandboxExecute } from '@services/vm.service';\nimport { VMRuntimeError } from '@errors/vm-runtime.error';\nimport { transpileFile } from '@services/transpiler.service';\nimport { LogLevel } from '@messages/constants/report.constant';\nimport { JsonReporter } from '@messages/reports/json.reporter';\nimport { JunitReporter } from '@messages/reports/junit.reporter';\nimport { ConsoleReporter } from '@messages/reports/console.report';\n\n/**\n * Transpiles a reporter file into a CommonJS module.\n *\n * @param reporterPath - Path to the reporter file to transpile\n * @returns A promise that resolves to a {@link TranspileFileInterface} containing the transpiled file\n *\n * @remarks\n * Uses the `transpileFile` utility with predefined options:\n * - `minify: false`\n * - `format: 'cjs'`\n * - `platform: 'node'`\n * - `logLevel: 'silent'`\n * - `packages: 'external'`\n *\n * @see TranspileFileInterface\n * @since 1.0.0\n */\n\nexport async function transpile(reporterPath: string): Promise<TranspileFileInterface> {\n return transpileFile(reporterPath, {\n minify: false,\n format: 'cjs',\n platform: 'node',\n logLevel: 'silent',\n packages: 'external'\n });\n}\n\n/**\n * Loads and parses an external reporter file.\n *\n * @param reporterPath - Path to the external reporter file\n * @returns A promise that resolves to the reporter constructor ({@link ReporterConstructorType}) if successful, otherwise `undefined`\n *\n * @throws VMRuntimeError - If an error occurs during sandboxed execution\n *\n * @remarks\n * This function first transpiles the reporter using {@link transpile} and then executes it\n * in a sandboxed environment. The module's default export is expected to be a subclass of {@link AbstractReporter}.\n * Throws a {@link VMRuntimeError} if execution fails.\n *\n * @see transpile\n * @see ReporterConstructorType\n *\n * @since 1.0.0\n */\n\nexport async function parseExternalReporter(reporterPath: string): Promise<ReporterConstructorType | undefined> {\n const { code, path } = await transpile(reporterPath);\n\n try {\n const module = { exports: { default: undefined } };\n const require = createRequire(path);\n const context = { Error, Buffer, RegExp, module, process, console, require, setTimeout, setInterval };\n\n await sandboxExecute(code, context, { filename: path });\n\n return module.exports.default;\n } catch (error) {\n throw new VMRuntimeError(error as Error);\n }\n}\n\n/**\n * Retrieves a reporter instance based on the provided configuration.\n *\n * @param config - Configuration object containing reporter settings\n * @returns A promise that resolves to an {@link AbstractReporter} instance\n *\n * @throws xJetError - If the reporter path does not export a valid reporter class\n * @throws VMRuntimeError - If instantiation of a custom reporter fails\n *\n * @remarks\n * This function supports both built-in and custom external reporters:\n * - Built-in reporters: `json`, `junit`, `default` (console).\n * - Custom reporters: dynamically loaded via {@link parseExternalReporter}.\n * The reporter is instantiated with `LogLevel.Debug` and an optional output file path.\n *\n * @see LogLevel\n * @see AbstractReporter\n * @see parseExternalReporter\n *\n * @since 1.0.0\n */\n\nexport async function getReporter(config: ConfigurationInterface): Promise<AbstractReporter> {\n const { reporter, outputFile } = config;\n\n // Built-in reporters\n const builtInReporters: Record<string, new (level: LogLevel, path?: string) => AbstractReporter> = {\n json: JsonReporter,\n junit: JunitReporter,\n default: ConsoleReporter\n };\n\n if (builtInReporters[reporter] || !existsSync(reporter)) {\n const Reporter = builtInReporters[reporter] || ConsoleReporter;\n\n return new Reporter(LogLevel[config.logLevel] ?? 0, outputFile);\n }\n\n const CustomReporter = await parseExternalReporter(reporter);\n if (!CustomReporter) {\n throw new xJetError(`Reporter at \"${ reporter }\" does not have a valid default export`);\n }\n\n if (typeof CustomReporter !== 'function') {\n throw new xJetError(`Reporter at \"${ reporter }\" is not a valid constructor`);\n }\n\n try {\n return new CustomReporter(LogLevel.Debug, outputFile);\n } catch (error) {\n throw new VMRuntimeError(error as Error);\n }\n}\n", "/**\n * Defines the log verbosity levels for reporters and test execution.\n *\n * @remarks\n * Each level represents the minimum severity of messages that should be\n * captured or displayed. Higher levels include all messages from lower levels.\n *\n * @example\n * ```ts\n * if (log.level >= LogLevel.Warn) {\n * console.warn(log.message);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport enum LogLevel {\n Silent = 0,\n Error = 1,\n Warn = 2,\n Info = 3,\n Debug = 4\n}\n\n/**\n * Defines the types of messages emitted during test execution.\n *\n * @remarks\n * These message types are used internally by reporters, runners,\n * and event emitters to categorize test events. Each type corresponds\n * to a specific stage or element of the test lifecycle.\n *\n * @example\n * ```ts\n * if (message.type === MessageType.Test) {\n * console.log('Test event received');\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport const enum MessageType {\n Test = 1,\n Describe = 2,\n EndSuite = 3,\n StartSuite = 4\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { EndMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { JsonTestInterface } from '@messages/reports/interfaces/json-reporter.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { JsonDescribeInterface, JsonSuiteInterface } from '@messages/reports/interfaces/json-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { AbstractReporter } from '@messages/abstract/report.abstract';\n\n/**\n * Reporter implementation that generates a JSON representation of test execution results.\n *\n * @remarks\n * The {@link JsonReporter} class extends {@link AbstractReporter} and is responsible for\n * capturing suite, describe, and test events during execution.\n * Results are aggregated in memory as a nested object structure and written to disk\n * (and `stdout`) when {@link finish} is called.\n * This allows external tools to consume structured test output for analysis, dashboards,\n * or CI integrations.\n *\n * @example\n * ```ts\n * const reporter = new JsonReporter();\n * reporter.init(['math.spec.ts'], [runner]);\n * // events will populate `reporter.testResults`\n * reporter.finish(); // writes JSON file if `outFilePath` is set\n * ```\n *\n * @see AbstractReporter\n * @see JsonTestInterface\n * @see JsonSuiteInterface\n * @see JsonDescribeInterface\n *\n * @since 1.0.0\n */\n\nexport class JsonReporter extends AbstractReporter {\n /**\n * Holds aggregated results, keyed by runner and suite name.\n *\n * @remarks\n * Structure:\n * ```ts\n * {\n * runnerName: {\n * suiteName: JsonSuiteInterface\n * }\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n protected testResults: Record<string, Record<string, JsonSuiteInterface>> = {};\n\n /**\n * Initializes result containers for all suites and runners prior to execution.\n *\n * @param suites - An array of suite names (usually file paths or identifiers)\n * that will be executed.\n * @param runners - An array of runner instances, each implementing {@link RunnerInterface},\n * representing the environments in which the suites will run.\n *\n * @remarks\n * This method pre-populates the {@link JsonReporter.testResults | `testResults`} map\n * with an entry for every suite\u2013runner combination.\n * Each entry is initialized with an empty {@link JsonSuiteInterface} structure,\n * including a root {@link JsonDescribeInterface}, so that subsequent events\n * (such as tests and describes) can be safely appended without requiring null checks.\n *\n * @example\n * ```ts\n * reporter.init(['math.spec.ts'], [ { name: 'node' } ]);\n * console.log(reporter.testResults.node['math.spec.ts']);\n * // {\n * // runner: 'node',\n * // suiteName: 'math.spec.ts',\n * // timestamp: Date,\n * // rootDescribe: { tests: [], describes: [], ... }\n * // }\n * ```\n *\n * @since 1.0.0\n */\n\n init(suites: Array<string>, runners: Array<RunnerInterface>): void {\n for (const suiteName of suites) {\n for (const runner of runners) {\n this.testResults[runner.name] = this.testResults[runner.name] ?? {};\n this.testResults[runner.name][suiteName] = {\n runner: runner.name,\n suiteName: suiteName,\n timestamp: new Date(),\n rootDescribe: {\n tests: [],\n ancestry: [],\n describes: [],\n description: '',\n timestamp: new Date()\n }\n };\n }\n }\n }\n\n /**\n * Marks the start of a test suite execution and initializes its result container.\n *\n * @remarks\n * This method creates a fresh {@link JsonSuiteInterface} entry in\n * {@link JsonReporter.testResults | `testResults`} for the specified runner\u2013suite pair.\n * It ensures that any prior results are replaced with a clean structure,\n * containing a root {@link JsonDescribeInterface} to collect nested describes and tests.\n *\n * Typically called when the reporter receives a {@link StartMessageInterface} event\n * signaling the beginning of a suite.\n *\n * @param event - The suite start event, containing the suite name,\n * runner identifier, and timestamp of the start.\n *\n * @example\n * ```ts\n * reporter.suiteStart({\n * runner: 'node',\n * suite: 'math.spec.ts',\n * timestamp: new Date()\n * });\n *\n * console.log(reporter.testResults.node['math.spec.ts']);\n * // {\n * // runner: 'node',\n * // suiteName: 'math.spec.ts',\n * // timestamp: Date,\n * // rootDescribe: { tests: [], describes: [], ... }\n * // }\n * ```\n *\n * @see JsonSuiteInterface\n * @see JsonDescribeInterface\n *\n * @since 1.0.0\n */\n\n suiteStart(event: StartMessageInterface): void {\n const key = event.suite;\n const name = event.runner;\n\n this.testResults[name][key] = {\n runner: event.runner,\n suiteName: key,\n timestamp: event.timestamp,\n rootDescribe: {\n tests: [],\n ancestry: [],\n describes: [],\n description: '',\n timestamp: event.timestamp\n }\n };\n }\n\n /**\n * Handles the completion of a test suite and updates its metadata.\n *\n * @param event - The event object containing details about the completed suite.\n *\n * @remarks\n * This method is invoked when a test suite finishes execution. It updates the suite's\n * duration, the root describe block's duration, and records any errors that occurred\n * during the suite's execution. If the suite already has errors, the new error is\n * appended to the existing list; otherwise, a new errors array is created.\n *\n * @example\n * ```ts\n * suiteEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * duration: 1250,\n * error: new Error('Test failed')\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n suiteEnd(event: EndMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n\n suite.duration = event.duration;\n suite.rootDescribe.duration = event.duration;\n\n if (event.error) {\n suite.errors = suite.errors ?? [];\n suite.errors.push(event.error);\n }\n }\n\n /**\n * Handles the start of a `describe` block in a test suite and registers it in the suite hierarchy.\n *\n * @param event - The event object containing information about the `describe` block.\n *\n * @remarks\n * This method is called when a `describe` block begins execution. It constructs a JSON\n * representation of the `describe` block, including its ancestry, description, timestamp,\n * and skipped status. The block is then inserted into the appropriate parent within the\n * suite's structure. If no parent exists, it is added to the suite's `rootDescribe`.\n *\n * @example\n * ```ts\n * describeStart({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login functionality',\n * timestamp: Date.now(),\n * skipped: false\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n describeStart(event: StartAssertionMessageInterface): void {\n if(event.description === '') return;\n const describeJson: JsonDescribeInterface = {\n tests: [],\n describes: [],\n skipped: event.skipped ?? false,\n ancestry: event.ancestry,\n timestamp: event.timestamp,\n description: event.description\n };\n\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (parent) parent.describes.push(describeJson);\n else suite.rootDescribe.describes.push(describeJson);\n }\n\n /**\n * Handles the completion of a `describe` block and updates its metadata.\n *\n * @param event - The event object containing details about the completed `describe` block.\n *\n * @remarks\n * This method is invoked when a `describe` block finishes execution. It updates the block's\n * duration and records any errors that occurred during its execution. If the block already\n * has errors, new errors are appended to the existing list; otherwise, a new errors array\n * is created. If the specified `describe` block cannot be found in the suite, the method\n * exits silently.\n *\n * @example\n * ```ts\n * describeEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * duration: 320,\n * errors: [new Error('Login failed')]\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n describeEnd(event: EndAssertionMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n const describe = this.findParentDescribe(suite, event.ancestry);\n if (!describe) return;\n\n if (event.errors && event.errors.length > 0) {\n describe.errors = describe.errors ?? [];\n describe.errors.push(...event.errors);\n }\n\n describe.duration = event.duration;\n }\n\n /**\n * Handles the start of a test that is either skipped or marked as `todo` and registers it under its parent `describe`.\n *\n * @param event - The event object containing details about the test.\n *\n * @remarks\n * This method is invoked when a test begins execution but is either skipped or flagged as `todo`.\n * It constructs a JSON representation of the test, including its ancestry, description, timestamp,\n * skipped status, and todo status, and then inserts it into the appropriate parent `describe` block\n * within the suite. If the parent cannot be found, the method exits silently.\n *\n * @example\n * ```ts\n * testStart({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login with invalid credentials',\n * timestamp: Date.now(),\n * skipped: true,\n * todo: false\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n testStart(event: StartAssertionMessageInterface): void {\n if(!event.skipped && !event.todo) return;\n\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (!parent) return;\n\n const testJson: JsonTestInterface = {\n todo: event.todo,\n skipped: event.skipped,\n ancestry: event.ancestry,\n timestamp: event.timestamp,\n description: event.description\n };\n\n parent.tests.push(testJson);\n }\n\n /**\n * Handles the completion of a test and registers its results under the appropriate parent `describe`.\n *\n * @param event - The event object containing details about the completed test.\n *\n * @remarks\n * This method is called when a test finishes execution. It constructs a JSON representation\n * of the test, including its pass/fail status, errors, ancestry, duration, timestamp, and description.\n * The test result is then added to the parent `describe` block within the suite. If the parent\n * cannot be found, the method exits silently.\n *\n * @example\n * ```ts\n * testEnd({\n * runner: 'jest',\n * suite: 'UserService tests',\n * ancestry: ['Authentication tests'],\n * description: 'Login with invalid credentials',\n * timestamp: Date.now(),\n * duration: 120,\n * passed: false,\n * errors: [new Error('Invalid credentials')]\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n testEnd(event: EndAssertionMessageInterface): void {\n const suite = this.getSuite(event.runner, event.suite);\n const parent = this.findParentDescribe(suite, event.ancestry);\n if (!parent) return;\n\n const testJson: JsonTestInterface = {\n passed: event.passed,\n errors: event.errors ?? [],\n ancestry: event.ancestry,\n duration: event.duration,\n timestamp: event.timestamp,\n description: event.description\n };\n\n parent.tests.push(testJson);\n }\n\n /**\n * Finalizes the test run, outputs the results, and optionally writes them to a file.\n *\n * @remarks\n * This method serializes all collected test results into a JSON string with indentation\n * for readability. If an output file path (`outFilePath`) is specified, it writes the JSON\n * results to that file. Regardless of file output, the results are also logged to the console.\n *\n * @example\n * ```ts\n * // Finish a test run and write results to a file\n * testTracker.outFilePath = './results.json';\n * testTracker.finish();\n * ```\n *\n * @since 1.0.0\n */\n\n finish(): void {\n const result = JSON.stringify(this.testResults, null, 4);\n if(this.outFilePath) {\n const folderPath = dirname(this.outFilePath);\n mkdirSync(folderPath, { recursive: true });\n writeFileSync(this.outFilePath, result);\n }\n\n console.log(result);\n }\n\n /**\n * Retrieves a test suite by its runner and suite name from the collected test results.\n *\n * @param runner - The name or identifier of the test runner.\n * @param suiteName - The name or identifier of the suite to retrieve.\n * @returns The `JsonSuiteInterface` object representing the requested suite.\n *\n * @throws Will throw an error if the specified suite does not exist for the given runner.\n *\n * @remarks\n * This method looks up a suite within `testResults` using the provided runner and suite name.\n * If the suite does not exist, it throws an error. This ensures that any operations on suites\n * are performed on valid, existing data.\n *\n * @example\n * ```ts\n * const suite = this.getSuite('jest', 'UserService tests');\n * console.log(suite.rootDescribe.tests);\n * ```\n *\n * @since 1.0.0\n */\n\n private getSuite(runner: string, suiteName: string): JsonSuiteInterface {\n if(!this.testResults[runner] || !this.testResults[runner][suiteName])\n throw new Error(`Suite not found: ${ runner } -> ${ suiteName }`);\n\n return this.testResults[runner][suiteName];\n }\n\n /**\n * Finds the parent `describe` block within a suite based on the provided ancestry.\n *\n * @param suite - The suite in which to search for the parent `describe`.\n * @param ancestry - An array of strings representing the hierarchy of parent `describe` names.\n * @returns The `JsonDescribeInterface` representing the found parent `describe` block.\n * If no matching parent is found, returns the suite's `rootDescribe`.\n *\n * @remarks\n * This method traverses the hierarchy of `describe` blocks in a suite using the\n * `ancestry` array, which contains the sequence of parent descriptions leading\n * to the target block. If the ancestry is empty, the suite's `rootDescribe` is returned.\n * If any ancestor in the path is not found, the method returns the `rootDescribe`\n * as a fallback. This ensures tests and nested `describe` blocks are always attached\n * to a valid parent.\n *\n * @example\n * ```ts\n * const parentDescribe = this.findParentDescribe(suite, ['Authentication tests', 'Login tests']);\n * parentDescribe.tests.push(newTestJson);\n * ```\n *\n * @since 1.0.0\n */\n\n private findParentDescribe(suite: JsonSuiteInterface, ancestry: Array<string>): JsonDescribeInterface & JsonTestInterface {\n if (ancestry.length === 0) return suite.rootDescribe;\n let currentDescribes = suite.rootDescribe.describes ?? [];\n let parent: JsonDescribeInterface | undefined;\n\n for (const name of ancestry) {\n parent = currentDescribes.find(d => d.description === name);\n if (!parent) return suite.rootDescribe;\n currentDescribes = parent.describes;\n }\n\n return <JsonDescribeInterface> parent;\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { LogLevel } from '@messages/constants/report.constant';\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { StartAssertionMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { StartMessageInterface, LogMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, EndMessageInterface } from '@messages/interfaces/messages.interface';\n\n/**\n * Base class for implementing custom reporters.\n *\n * @remarks\n * The `AbstractReporter` defines lifecycle hooks that can be implemented\n * by concrete reporter classes to customize how test results are reported.\n *\n * Reporters receive structured event messages during test execution,\n * including suite start/end, describe/test assertions, logs, and finalization.\n *\n * Each method is optional (`?`) and may be implemented depending on\n * the reporter\u2019s needs (e.g., console logging, file output, JSON reporting).\n *\n * @example\n * ```ts\n * class ConsoleReporter extends AbstractReporter {\n * log(log: LogMessageInterface): void {\n * console.log(`[LOG] ${log.message}`);\n * }\n *\n * suiteStart(event: StartMessageInterface): void {\n * console.log(`Suite started: ${event.suiteName}`);\n * }\n * }\n * ```\n *\n * @see RunnerInterface\n * @see LogMessageInterface\n * @see StartMessageInterface\n * @see EndMessageInterface\n *\n * @since 1.0.0\n */\n\nexport abstract class AbstractReporter {\n /**\n * Creates a new reporter.\n *\n * @param logLevel - The minimum log level this reporter should handle.\n * @param outFilePath - Optional file path where logs or reports should be written.\n */\n\n constructor(\n protected readonly logLevel: LogLevel,\n protected readonly outFilePath?: string\n ) {}\n\n /**\n * Initializes the reporter before test execution starts.\n *\n * @remarks\n * This method is called at the beginning of each test session.\n * In **watch mode**, it will be invoked for every new session restart.\n * Reporters can use this hook to reset the internal state, prepare output files,\n * or print session headers.\n *\n * @param suites - A list of suite names to be executed in this session.\n * @param runners - A list of configured runners available in this session.\n *\n * @since 1.0.0\n */\n\n init?(suites: Array<string>, runners: Array<RunnerInterface>): void;\n\n /**\n * Handles log messages emitted during test execution.\n *\n * @param log - The structured log message including level, text,\n * and optional metadata.\n *\n * @remarks\n * This method is triggered whenever the test code calls\n * `xJet.log()`, `xJet.error()`, or similar logging helpers.\n * Reporters can use this hook to capture, format, and\n * output logs to the console, files, or custom UIs.\n *\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n log?(log: LogMessageInterface): void;\n\n /**\n * Signals the start of a test suite execution.\n *\n * @param event - The structured event containing suite metadata\n * such as its ID, name, and runner.\n *\n * @remarks\n * Called when a suite begins running. Reporters can use this\n * hook to display suite headers, initialize timers, or log\n * contextual information about the suite.\n *\n * @see StartMessageInterface\n * @since 1.0.0\n */\n\n suiteStart?(event: StartMessageInterface): void;\n\n /**\n * Signals the completion of a test suite execution.\n *\n * @param event - The structured event containing final suite\n * metadata such as its ID, name, duration, and\n * aggregated results.\n *\n * @remarks\n * Called after a suite has finished running. Reporters can use\n * this hook to display summary information, update progress,\n * or finalize suite-level reporting.\n *\n * @see EndMessageInterface\n * @since 1.0.0\n */\n\n suiteEnd?(event: EndMessageInterface): void;\n\n /**\n * Signals the start of a `describe` block execution.\n *\n * @param event - The structured event containing metadata\n * about the `describe` block, including its\n * ID, name, and parent context.\n *\n * @remarks\n * Called when a `describe` block begins running. Reporters\n * can use this hook to display section headers, indent logs,\n * or prepare contextual grouping in the output.\n *\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n describeStart?(event: StartAssertionMessageInterface): void;\n\n /**\n * Signals the completion of a `describe` block execution.\n *\n * @param event - The structured event containing metadata\n * about the `describe` block, including its\n * ID, name, duration, and results.\n *\n * @remarks\n * Called after a `describe` block has finished running.\n * Reporters can use this hook to close sections, summarize\n * grouped tests, or adjust indentation and formatting.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n describeEnd?(event: EndAssertionMessageInterface): void;\n\n /**\n * Signals the start of an individual test execution.\n *\n * @param event - The structured event containing metadata\n * about the test, including its ID, name,\n * and parent suite or `describe` block.\n *\n * @remarks\n * Called when a test begins running. Reporters can use this\n * hook to display test-level headers, start timers, or\n * track progress.\n *\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n testStart?(event: StartAssertionMessageInterface): void;\n\n /**\n * Signals the completion of an individual test execution.\n *\n * @param event - The structured event containing metadata\n * about the test, including its ID, name,\n * duration, and result status.\n *\n * @remarks\n * Called after a test has finished running. Reporters can use\n * this hook to display test results, update progress bars,\n * or log assertion summaries.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n testEnd?(event: EndAssertionMessageInterface): void;\n\n /**\n * Called when all suites have finished executing.\n *\n * @remarks\n * This method is invoked at the **end of each test session**.\n * In watch mode, it will be called after every session completes,\n * allowing reporters to finalize logs, write summary files, or\n * perform cleanup for that session.\n *\n * @since 1.0.0\n */\n\n finish?(): void;\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { JsonDescribeInterface } from '@messages/reports/interfaces/json-reporter.interface';\nimport type { JsonSuiteInterface, JsonTestInterface } from '@messages/reports/interfaces/json-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { dirname } from 'path';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { JsonReporter } from '@messages/reports/json.reporter';\n\n/**\n * JunitReporter converts test results into JUnit-compatible XML format.\n *\n * @remarks\n * Extends the `JsonReporter` to output test results as XML. This reporter\n * traverses the suites, describes, and tests collected during the run,\n * producing a hierarchical XML representation suitable for CI tools.\n *\n * @example\n * ```ts\n * const reporter = new JunitReporter();\n * reporter.testStart({ ... });\n * reporter.testEnd({ ... });\n * reporter.finish(); // Outputs JUnit XML to console or file\n * ```\n *\n * @since 1.0.0\n */\n\nexport class JunitReporter extends JsonReporter {\n /**\n * Parts of the XML document being built during test result conversion.\n *\n * @remarks\n * This array stores fragments of the JUnit XML output as strings. The final XML\n * is constructed by joining these parts together in `finish()`. It is initialized\n * with the XML declaration and grows as suites, describes, and tests are converted\n * to XML.\n *\n * @example\n * ```ts\n * this.xmlParts.push('<testsuite name=\"ExampleSuite\">');\n * this.xmlParts.push('</testsuite>');\n * const xmlContent = this.xmlParts.join('\\n');\n * ```\n *\n * @since 1.0.0\n */\n\n protected xmlParts: Array<string> = [ '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' ];\n\n /**\n * Finalizes the JUnit XML report and outputs it.\n *\n * @remarks\n * This method constructs the complete JUnit XML document from the collected test results.\n * It iterates over all test runners and their suites, converts them into XML format,\n * and appends them to the internal `xmlParts` array. After building the full XML:\n * - If `outFilePath` is defined, the XML is written to the specified file.\n * - The XML is also logged to the console.\n *\n * @example\n * ```ts\n * reporter.finish(); // Generates and outputs the complete JUnit XML\n * ```\n *\n * @since 1.0.0\n */\n\n finish(): void {\n this.xmlParts.push('<testsuites>');\n Object.entries(this.testResults).forEach(([ runnerName, suitesByName ]) => {\n this.xmlParts.push(`<testsuites name=\"${ runnerName }\">`);\n\n Object.values(suitesByName).forEach(suite => {\n this.convertSuiteToXml(suite);\n });\n\n this.xmlParts.push('</testsuites>');\n });\n\n this.xmlParts.push('</testsuites>');\n const xmlContent = this.xmlParts.join('\\n');\n if(this.outFilePath) {\n const folderPath = dirname(this.outFilePath);\n mkdirSync(folderPath, { recursive: true });\n writeFileSync(this.outFilePath, xmlContent);\n }\n\n console.log(xmlContent);\n }\n\n /**\n * Converts a test suite into a JUnit `<testsuite>` XML element and appends it to `xmlParts`.\n *\n * @param suite - The test suite to convert to XML.\n *\n * @remarks\n * This method calculates the total number of tests, failures, skipped tests, and the suite duration.\n * It constructs the `<testsuite>` element with these attributes and recursively converts\n * the root describe block and all nested describes/tests into XML. The resulting XML\n * fragments are appended to the `xmlParts` array.\n *\n * @example\n * ```ts\n * this.convertSuiteToXml(suite);\n * // xmlParts will now include <testsuite> with all tests nested inside\n * ```\n *\n * @since 1.0.0\n */\n\n private convertSuiteToXml(suite: JsonSuiteInterface): void {\n const rootDescribe = suite.rootDescribe;\n const tests = this.countTests(rootDescribe);\n const failures = this.countFailures(rootDescribe);\n const skipped = this.countSkipped(rootDescribe);\n const duration = this.formatDuration(suite.duration);\n\n const suiteAttrs = [\n `name=\"${ suite.suiteName }\"`,\n `tests=\"${ tests }\"`,\n `failures=\"${ failures }\"`,\n `skipped=\"${ skipped }\"`,\n `time=\"${ duration }\"`\n ].join(' ');\n\n this.xmlParts.push(`<testsuite ${ suiteAttrs }>`);\n this.convertDescribeToXml(rootDescribe);\n this.xmlParts.push('</testsuite>');\n }\n\n /**\n * Recursively converts a `describe` block and its nested describes/tests into XML.\n *\n * @param describe - The `describe` block to convert.\n *\n * @remarks\n * This method traverses the hierarchy of a `describe` block:\n * - Converts all tests in the current describe using `convertTestToXml`.\n * - Recursively processes all nested describes.\n *\n * The resulting XML fragments are appended to the `xmlParts` array.\n *\n * @example\n * ```ts\n * this.convertDescribeToXml(rootDescribe);\n * // All tests and nested describes are appended to xmlParts\n * ```\n *\n * @since 1.0.0\n */\n\n private convertDescribeToXml(describe: JsonDescribeInterface): void {\n describe.tests.forEach(test => this.convertTestToXml(test));\n describe.describes.forEach(nested => this.convertDescribeToXml(nested));\n }\n\n /**\n * Converts a single test into a JUnit `<testcase>` XML element and appends it to `xmlParts`.\n *\n * @param test - The test to convert.\n *\n * @remarks\n * This method constructs the XML representation of a test including:\n * - `classname` based on its ancestry\n * - `name` from the test description\n * - `time` from the test duration in seconds\n *\n * It handles different test statuses:\n * - Skipped or TODO tests generate a `<skipped>` child element.\n * - Passed tests generate a self-closing `<testcase>` element.\n * - Failed tests include one or more `<failure>` elements created by `formatErrors`.\n *\n * @example\n * ```ts\n * this.convertTestToXml(test);\n * // xmlParts will include a <testcase> element representing this test\n * ```\n *\n * @since 1.0.0\n */\n\n private convertTestToXml(test: JsonTestInterface): void {\n const duration = this.formatDuration(test.duration);\n const name = test.description;\n const classname = test.ancestry.join('.') || 'root';\n const baseAttributes = `classname=\"${ classname }\" name=\"${ name }\" time=\"${ duration }\"`;\n\n if (test.skipped || test.todo) {\n const reason = test.todo ? 'TODO' : 'Skipped';\n this.xmlParts.push(`<testcase ${ baseAttributes }><skipped message=\"${ reason }\" /></testcase>`);\n\n return;\n }\n\n if (test.passed) {\n this.xmlParts.push(`<testcase ${ baseAttributes } />`);\n\n return;\n }\n\n const errors = this.formatErrors(test.errors);\n this.xmlParts.push(`<testcase ${ baseAttributes }>${ errors }</testcase>`);\n }\n\n /**\n * Formats an array of test errors into JUnit `<failure>` XML elements.\n *\n *\n * @param errors - Array of errors from a test.\n * @returns A string containing one or more `<failure>` XML elements concatenated.\n *\n * @remarks\n * Each error is converted into a `<failure>` element with:\n * - `message` attribute from the error name\n * - Escaped error message and stack trace inside the element\n * - Optional `formatCode` content if provided\n *\n * If the errors array is empty or undefined, an empty string is returned.\n *\n * @example\n * ```ts\n * const xmlErrors = this.formatErrors(test.errors);\n * // xmlErrors contains <failure> elements for each test error\n * ```\n *\n * @since 1.0.0\n */\n\n private formatErrors(errors: JsonTestInterface['errors']): string {\n if (!errors?.length) return '';\n\n return errors.map(e =>\n `<failure message=\"${ e.name }\">${ this.escapeXml(e.message) }\\n${ e.formatCode }\\n\\n${ this.escapeXml(e.stack) }</failure>`\n ).join('');\n }\n\n /**\n * Converts a duration from milliseconds to seconds as a string with three decimal places.\n *\n * @param duration - The duration in milliseconds.\n * @returns The duration in seconds as a string with three decimal places.\n *\n * @remarks\n * If the input duration is `undefined`, it defaults to `0`. The output is formatted\n * as a string suitable for inclusion in JUnit XML `time` attributes.\n *\n * @example\n * ```ts\n * const seconds = this.formatDuration(1234); // \"1.234\"\n * const zero = this.formatDuration(); // \"0.000\"\n * ```\n *\n * @since 1.0.0\n */\n\n private formatDuration(duration?: number): string {\n return ((duration ?? 0) / 1000).toFixed(3);\n }\n\n /**\n * Counts the total number of tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count tests in.\n * @returns The total number of tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks to calculate\n * the total number of tests. Only actual test entries in the `tests` array are counted;\n * skipped or todo tests are included in this count.\n *\n * @example\n * ```ts\n * const totalTests = this.countTests(rootDescribe);\n * console.log(totalTests); // e.g., 15\n * ```\n *\n * @since 1.0.0\n */\n\n private countTests(describe: JsonDescribeInterface): number {\n return describe.tests.length + describe.describes.reduce((sum, nested) => sum + this.countTests(nested), 0);\n }\n\n /**\n * Counts the total number of skipped or TODO tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count skipped or TODO tests in.\n * @returns The total number of skipped or TODO tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks. A test is counted as skipped\n * if its `skipped` or `todo` property is `true`.\n *\n * @example\n * ```ts\n * const skippedTests = this.countSkipped(rootDescribe);\n * console.log(skippedTests); // e.g., 3\n * ```\n *\n * @since 1.0.0\n */\n\n private countSkipped(describe: JsonDescribeInterface): number {\n const skippedInCurrent = describe.tests.filter(t => t.skipped || t.todo).length;\n\n return skippedInCurrent + describe.describes.reduce((sum, nested) => sum + this.countSkipped(nested), 0);\n }\n\n /**\n * Counts the total number of failed tests within a `describe` block, including nested describes.\n *\n * @param describe - The `describe` block to count failed tests in.\n * @returns The total number of failed tests including all nested describes.\n *\n * @remarks\n * This method recursively traverses all nested `describe` blocks. A test is counted as a failure\n * if it is not passed, not skipped, and not marked as TODO.\n *\n * @example\n * ```ts\n * const failedTests = this.countFailures(rootDescribe);\n * console.log(failedTests); // e.g., 2\n * ```\n *\n * @since 1.0.0\n */\n\n private countFailures(describe: JsonDescribeInterface): number {\n const failuresInCurrent = describe.tests.filter(t => !t.passed && !t.skipped && !t.todo).length;\n\n return failuresInCurrent + describe.describes.reduce((sum, nested) => sum + this.countFailures(nested), 0);\n }\n\n /**\n * Escapes special XML characters in a string to ensure valid XML output.\n *\n * @param str - The string to escape.\n * @returns The escaped string safe for XML content.\n *\n * @remarks\n * This method replaces the following characters with their corresponding XML entities:\n * - `&` \u2192 `&amp;`\n * - `\"` \u2192 `&quot;`\n * - `'` \u2192 `&apos;`\n * - `<` \u2192 `&lt;`\n * - `>` \u2192 `&gt;`\n *\n * @example\n * ```ts\n * const safeXml = this.escapeXml('<div class=\"example\">Hello & Welcome</div>');\n * console.log(safeXml);\n * // &lt;div class=&quot;example&quot;&gt;Hello &amp; Welcome&lt;/div&gt;\n * ```\n *\n * @since 1.0.0\n */\n\n private escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { SuiteMapInterface } from '@messages/reports/interfaces/console-reporter.interface';\nimport type { EndMessageInterface, LogMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, SuiteErrorInterface } from '@messages/interfaces/messages.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { SuiteStatsInterface, TestStatsInterface } from '@messages/reports/interfaces/console-reporter.interface';\n\n/**\n * Imports\n */\n\nimport { ANSI, writeRaw } from '@remotex-labs/xansi';\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\nimport { LogLevel } from '@messages/constants/report.constant';\nimport { ShadowRenderer } from '@remotex-labs/xansi/shadow.service';\nimport { AbstractReporter } from '@messages/abstract/report.abstract';\nimport { ConsoleState, formatStatus, statePrefix, STATIC_HEIGHT } from '@messages/reports/constants/console.constant';\n\n/**\n * Reporter that renders test suite and test results in the console.\n *\n * @remarks\n * The `ConsoleReporter` extends {@link AbstractReporter} and is responsible for:\n * - Rendering suite and test results in real-time using ANSI colors and cursor control.\n * - Tracking per-suite and per-test statistics via {@link SuiteStatsInterface} and {@link TestStatsInterface}.\n * - Maintaining per-suite content for rendering with {@link ShadowRenderer}.\n * - Showing summary of suites and tests, including totals, passed, failed, skipped, and TODO counts.\n *\n * It uses:\n * - `ShadowRenderer` for managing console regions (info and status blocks).\n * - `formatStatus` and `statePrefix` for ANSI-colored output.\n * - `STATIC_HEIGHT` to reserve space for status display at the bottom.\n *\n * @example\n * ```ts\n * const reporter = new ConsoleReporter(LogLevel.Info);\n * reporter.init(['MySuite'], runners);\n * reporter.testStart(testEvent);\n * reporter.testEnd(testEndEvent);\n * reporter.suiteEnd(suiteEndEvent);\n * reporter.finish();\n * ```\n *\n * @since 1.0.0\n */\n\nexport class ConsoleReporter extends AbstractReporter {\n /**\n * Timestamp when the reporter started.\n * @since 1.0.0\n */\n\n private startTime: number = Date.now();\n\n /**\n * Whether there is only a single runner executing tests.\n * @since 1.0.0\n */\n\n private isSingleRunner = false;\n\n /**\n * Interval ID for periodic state updates.\n * @since 1.0.0\n */\n\n private updateInterval: NodeJS.Timeout | undefined;\n\n /**\n * Maximum length of runner names, used for padding in the console display.\n * @since 1.0.0\n */\n\n private maxRunnerNameLength = 0;\n\n /**\n * ShadowRenderer for displaying per-suite detailed output.\n * @since 1.0.0\n */\n\n private readonly info: ShadowRenderer;\n\n /**\n * ShadowRenderer for displaying a summary of all suites and tests.\n * @since 1.0.0\n */\n\n private readonly status: ShadowRenderer;\n\n /**\n * Aggregated test counters across all suites.\n * @since 1.0.0\n */\n\n private tests: Required<TestStatsInterface> = this.createTests();\n\n /**\n * Aggregated suite counters across all suites.\n * @since 1.0.0\n */\n\n private suites: Required<SuiteStatsInterface> = this.createSuites();\n\n /**\n * Map of suite name + runner to per-suite rendering content and stats.\n * @since 1.0.0\n */\n\n private readonly suiteMap: Map<string, Required<SuiteMapInterface>> = new Map();\n\n /**\n * Initializes the console reporter.\n *\n * @param logLevel - The log level threshold for output.\n * @param outFilePath - Optional path for writing logs to a file.\n *\n * @remarks\n * Creates `ShadowRenderer` instances for info and status blocks based on terminal size.\n *\n * @since 1.0.0\n */\n\n constructor(logLevel: LogLevel, outFilePath?: string) {\n super(logLevel, outFilePath);\n\n const height = process.stdout.rows ?? 24;\n const width = process.stdout.columns ?? 80;\n\n this.info = new ShadowRenderer(height - STATIC_HEIGHT - 1, width, 1, 0);\n this.status = new ShadowRenderer(STATIC_HEIGHT, width, height - STATIC_HEIGHT, 0);\n }\n\n /**\n * Initializes the console reporter with suites and runners.\n *\n * @param suites - Array of suite names to track and render.\n * @param runners - Array of runner objects executing the tests.\n *\n * @remarks\n * This method performs the following actions:\n * - Clears the console and hides the cursor using ANSI sequences.\n * - Resets internal start time, test and suite counters.\n * - Determines if only a single runner is executing to adjust formatting.\n * - Starts a periodic interval to update the summary status at the bottom.\n * - Initializes `suiteMap` with per-suite content and counters for each runner.\n * - Prepares each suite title with a pending status using {@link getPrefix}.\n * - Renders all suites immediately using {@link renderSuites}.\n *\n * Each suite in `suiteMap` includes:\n * - `todo`, `total`, `passed`, `failed`, `skipped` counters initialized to `0`.\n * - `title` with `[ Pending ]` status prefix.\n * - Empty `details` array for storing log lines and error messages.\n *\n * @example\n * ```ts\n * reporter.init(['Suite1', 'Suite2'], runners);\n * ```\n *\n * @since 1.0.0\n */\n\n init(suites: Array<string>, runners: Array<RunnerInterface>): void {\n writeRaw(ANSI.HIDE_CURSOR);\n writeRaw(ANSI.CLEAR_SCREEN);\n\n this.suiteMap.clear();\n this.startTime = Date.now();\n this.tests = this.createTests();\n this.suites = this.createSuites();\n this.isSingleRunner = runners.length < 2;\n this.updateInterval = setInterval(this.updateState.bind(this), 230);\n this.maxRunnerNameLength = Math.max(...runners.map(r => r.name.length));\n\n for (const suiteName of suites) {\n for (const runner of runners) {\n const key = this.getSuiteKey(runner.name, suiteName);\n const title = this.getPrefix(ConsoleState.Pending, runner.name, suiteName);\n this.suiteMap.set(key, {\n todo: 0,\n total: 0,\n passed: 0,\n failed: 0,\n skipped: 0,\n title: title,\n details: []\n });\n }\n }\n\n this.renderSuites();\n }\n\n /**\n * Handles a log message emitted by a test or suite and appends it to the corresponding suite details.\n *\n * @param log - The structured log message containing the message, level, ancestry, and optional invocation.\n *\n * @remarks\n * This method performs the following actions:\n * - Ignores the message if its level is below the reporter's `logLevel` or if `LogLevel.Silent` is set.\n * - Ensures the suite exists in `suiteMap` using {@link ensureSuite}.\n * - Formats the log message with:\n * - Level prefix using {@link getLogPrefix}.\n * - Ancestry path of the test/describe block.\n * - Indented multi-line message.\n * - Optional source code location if `log.invocation` is provided.\n * - Appends each formatted line to the suite's `details` array.\n * - Adds an empty line after each log for separation.\n * - Renders all suites immediately using {@link renderSuites}.\n *\n * @example\n * ```ts\n * reporter.log({\n * level: 'info',\n * levelId: LogLevel.Info,\n * message: 'This is a log message',\n * runner: 'runner1',\n * suite: 'MySuite',\n * ancestry: ['describe1', 'test1'],\n * timestamp: new Date()\n * });\n * ```\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n log(log: LogMessageInterface): void {\n if (log.levelId > this.logLevel || this.logLevel === LogLevel.Silent) return;\n const suite = this.ensureSuite(log.runner, log.suite);\n\n const lines: Array<string> = [ '' ];\n lines.push(this.getLogPrefix(log) + xterm.gray(` [${ log.ancestry.join(' > ') }]`));\n lines.push(...log.message.split('\\n').map(line => ' '.repeat(2) + line));\n\n if (log.invocation) {\n lines.push(\n xterm.gray(`at (${ log.invocation.source }:${ log.invocation.line }:${ log.invocation.column })`)\n );\n }\n\n for (const line of lines) {\n suite.details.push(line);\n }\n\n suite.details.push('');\n this.renderSuites();\n }\n\n /**\n * Handles the start of a test suite and updates the console display accordingly.\n *\n * @param event - Structured event data containing the runner and suite information.\n *\n * @remarks\n * This method performs the following actions:\n * - Ensures the suite exists in `suiteMap` using {@link ensureSuite}.\n * - Updates the suite title with a running status prefix using {@link getPrefix}.\n * - Renders the updated suites to the console using {@link renderSuites}.\n *\n * This is typically called when the reporter receives a {@link StartMessageInterface} from a test runner.\n *\n * @see StartMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#getPrefix - Generates the status-prefixed suite title.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see ConsoleReporter#renderSuites - Renders the suite map to the terminal.\n *\n * @since 1.0.0\n */\n\n suiteStart(event: StartMessageInterface): void {\n const suite = this.ensureSuite(event.runner, event.suite);\n suite.title = this.getPrefix(ConsoleState.Run, event.runner, event.suite);\n this.renderSuites();\n }\n\n /**\n * Handles the completion of a test suite and updates the console display accordingly.\n *\n * @param event - Structured event data containing suite results, runner information, duration, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Increments the global suite counter.\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - Determines the suite's final status based on errors, skipped/todo tests, or failed tests.\n * - Updates the suite title with a status prefix and duration using {@link getPrefix}.\n * - Adds formatted error details to the suite if present using {@link parseError}.\n * - Renders the updated suites to the console using {@link renderSuites}.\n *\n * This is typically called when the reporter receives an {@link EndMessageInterface} from a test runner.\n *\n * @see EndMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#getPrefix - Generates the status-prefixed suite title.\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see ConsoleReporter#renderSuites - Renders the suite map to the terminal.\n *\n * @since 1.0.0\n */\n\n suiteEnd(event: EndMessageInterface): void {\n this.suites.total += 1;\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n let prefix = ConsoleState.Passed;\n if (event.error) {\n this.suites.failed += 1;\n prefix = ConsoleState.Failed;\n } else if (suiteStats.total === suiteStats.skipped + suiteStats.todo) {\n this.suites.skipped += 1;\n prefix = ConsoleState.Skipped;\n } else if (suiteStats.failed > 0) {\n this.suites.failed += 1;\n prefix = ConsoleState.Failed;\n } else {\n this.suites.passed += 1;\n }\n\n let title = this.getPrefix(prefix, event.runner, event.suite);\n title += ` ${ (event.duration / 1000).toFixed(3) } s`;\n suiteStats.title = title;\n\n if (event.error) {\n suiteStats.details.push(...this.parseError(event.error));\n }\n\n this.renderSuites();\n }\n\n /**\n * Handles the completion of a `describe` block within a suite and updates its status.\n *\n * @param event - Structured event data containing `describe` block results, runner, suite, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - If errors are present, increments the `failed` counter for the suite.\n * - Appends formatted error details to the suite using {@link parseError}.\n *\n * This is typically called when the reporter receives an {@link EndAssertionMessageInterface}\n * event for a `describe` block.\n *\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see EndAssertionMessageInterface - Structure of the event data passed to this method.\n *\n * @since 1.0.0\n */\n\n describeEnd(event: EndAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.errors?.length) {\n suiteStats['failed'] += 1;\n for (const err of event.errors) {\n suiteStats.details.push(...this.parseError(err));\n }\n }\n }\n\n /**\n * Handles the start of a test case and updates the suite counters for `todo` or skipped tests.\n *\n * @param event - Structured event data containing test start information, runner, suite, and optional `todo`/`skipped` flags.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - If the test is marked `todo` or `skipped`, increments the corresponding counters in both\n * the suite and overall test statistics using {@link incrementTestCounters}.\n *\n * This is typically called when the reporter receives a {@link StartAssertionMessageInterface}\n * event for a test case.\n *\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see StartAssertionMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#incrementTestCounters - Updates the test counters for the suite and global stats.\n *\n * @since 1.0.0\n */\n\n testStart(event: StartAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.todo || event.skipped) {\n this.incrementTestCounters(event.todo ? 'todo' : 'skipped', suiteStats);\n }\n }\n\n /**\n * Handles the completion of a test case, updates counters, and appends formatted output for the suite.\n *\n * @param event - Structured event data containing test results, runner, suite, duration, ancestry, description, and optional errors.\n *\n * @remarks\n * This method performs the following actions:\n * - Retrieves the suite stats from {@link ensureSuite}.\n * - Increments the total test counters for the suite and global stats.\n * - If the test has errors:\n * - Marks the test as `failed` via {@link incrementTestCounters}.\n * - Appends a formatted test line with the ancestry path, description, and duration.\n * - Adds parsed error details using {@link parseError}.\n * - If no errors are present, marks the test as `passed` via {@link incrementTestCounters}.\n *\n * This is typically called when the reporter receives an {@link EndAssertionMessageInterface}\n * event for a test case.\n *\n * @see ConsoleReporter#parseError - Formats and extracts error details for console display.\n * @see ConsoleReporter#ensureSuite - Ensures the suite exists in the internal map.\n * @see EndAssertionMessageInterface - Structure of the event data passed to this method.\n * @see ConsoleReporter#incrementTestCounters - Updates the test counters for the suite and global stats.\n *\n * @since 1.0.0\n */\n\n testEnd(event: EndAssertionMessageInterface): void {\n const suiteStats = this.ensureSuite(event.runner, event.suite);\n\n if (event.errors && event.errors.length > 0) {\n this.incrementTestCounters('failed', suiteStats);\n\n let testLine = formatStatus.failed(`\u25CF ${ event.ancestry.join(' > ') } > ${ event.description }`);\n testLine += xterm.gray(` (${ (event.duration / 1000).toFixed(3) } s)`);\n suiteStats.details.push(testLine);\n\n for (const err of event.errors) {\n suiteStats.details.push(...this.parseError(err));\n }\n } else {\n this.incrementTestCounters('passed', suiteStats);\n }\n }\n\n /**\n * Finalizes the console reporter, clears the display, and flushes all pending output.\n *\n * @remarks\n * This method performs the following actions:\n * - Stops the periodic state update interval if it is running.\n * - Updates the console state one last time using {@link updateState}.\n * - Clears both the `info` and `status` {@link ShadowRenderer} buffers.\n * - Flushes all content from the `info` and `status` renderers to the terminal.\n *\n * Typically called after all suites and tests have completed to ensure\n * the console displays the final test results cleanly.\n *\n * @see ConsoleReporter#updateState - Updates the rendered state for suites and tests.\n * @see ShadowRenderer#clearScreen - Clears the renderer buffer.\n * @see ShadowRenderer#flushToTerminal - Outputs the buffered content to the terminal.\n *\n * @since 1.0.0\n */\n\n finish(): void {\n this.updateInterval?.close();\n this.updateState();\n\n this.info.clearScreen();\n this.status.clearScreen();\n this.info.flushToTerminal();\n this.status.flushToTerminal();\n }\n\n /**\n * Generates a unique key for a suite based on the runner name and suite name.\n *\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the test suite.\n * @returns A string key in the format `{runner}::{suiteName}` used to store and retrieve suite data.\n *\n * @remarks\n * This key is used internally to map each suite per runner in {@link suiteMap}.\n *\n * @see ConsoleReporter#suiteMap - Internal map storing per-suite information.\n *\n * @since 1.0.0\n */\n\n private getSuiteKey(runner: string, suiteName: string): string {\n return `${ runner }::${ suiteName }`;\n }\n\n /**\n * Retrieves the suite stats object for a given runner and suite name.\n *\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the test suite.\n * @returns The corresponding {@link SuiteMapInterface} containing counters, title, and details.\n *\n * @remarks\n * This method uses {@link getSuiteKey} to construct the key for the internal\n * {@link suiteMap} and retrieves the suite information.\n *\n * The returned object is guaranteed to exist if the suite was initialized via {@link init}.\n *\n * @see ConsoleReporter#getSuiteKey - Generates the key used to index the suite map.\n * @see ConsoleReporter#suiteMap - Internal storage of suite stats and details.\n *\n * @since 1.0.0\n */\n\n private ensureSuite(runner: string, suiteName: string): SuiteMapInterface {\n return this.suiteMap.get(this.getSuiteKey(runner, suiteName))!;\n }\n\n /**\n * Initializes and returns a fresh test statistics object.\n *\n * @returns A {@link TestStatsInterface} object with all counters set to `0`.\n *\n * @remarks\n * This method is used to reset or initialize the global test counters before\n * execution begins, ensuring all test counts start from zero.\n *\n * @see TestStatsInterface - Defines the counters for tests across all suites.\n *\n * @since 1.0.0\n */\n\n private createTests(): TestStatsInterface {\n return { total: 0, passed: 0, failed: 0, skipped: 0, todo: 0 };\n }\n\n /**\n * Creates a new suite statistics object with all counters initialized to zero.\n *\n * @returns A {@link SuiteStatsInterface} object representing the initial state of suite counters.\n *\n * @remarks\n * This method is used to reset or initialize the global suite counters before\n * execution begins. All counters (`total`, `passed`, `failed`, `skipped`) start from `0`.\n *\n * @see SuiteStatsInterface - Interface defining counters for suite execution.\n *\n * @since 1.0.0\n */\n\n private createSuites(): SuiteStatsInterface {\n return { total: 0, passed: 0, failed: 0, skipped: 0 };\n }\n\n /**\n * Converts a {@link SuiteErrorInterface} into an array of formatted strings for console output.\n *\n * @param error - The error object containing message, formatted code, and stack trace.\n * @returns An array of strings representing the error, formatted for display in the console.\n *\n * @remarks\n * The returned array contains:\n * - An empty line at the start\n * - The error message split by line\n * - The formatted code lines dimmed using {@link xterm.dim}\n * - The stack trace lines\n * - An empty line at the end\n *\n * This is used internally by the {@link ConsoleReporter} to render detailed error information\n * for failed tests or suites in the shadowed console output.\n *\n * @see SuiteErrorInterface - Structure of the error object.\n * @see xterm.dim - Utility to dim text in console output.\n *\n * @since 1.0.0\n */\n\n private parseError(error: SuiteErrorInterface): Array<string> {\n const lines = [ '', ...error.message.split('\\n'), '' ];\n lines.push(...error.formatCode.split('\\n').map(data => xterm.dim(data)), '');\n lines.push(...error.stack.split('\\n'), '');\n\n return lines;\n }\n\n /**\n * Increments the specified test counter for both the global test stats and the given suite stats.\n *\n * @param counter - The specific counter to increment (`total`, `passed`, `failed`, `skipped`, or `todo`).\n * @param suiteStats - The {@link TestStatsInterface} object representing the suite's current test statistics.\n *\n * @remarks\n * This method updates both the per-suite counters and the overall counters maintained\n * by the {@link ConsoleReporter}. The `total` counter is always incremented alongside\n * the specified counter.\n *\n * @see TestStatsInterface - Interface defining the available test counters.\n *\n * @since 1.0.0\n */\n\n private incrementTestCounters(counter: keyof TestStatsInterface, suiteStats: TestStatsInterface): void {\n suiteStats.total += 1;\n this.tests.total += 1;\n suiteStats[counter] += 1;\n this.tests[counter] += 1;\n }\n\n private updateState(): void {\n const suitesParts: Array<string> = [];\n const testsParts: Array<string> = [];\n\n if (this.suites.failed > 0) suitesParts.push(formatStatus.failed(`${ this.suites.failed } failed`));\n if (this.suites.passed > 0) suitesParts.push(formatStatus.passed(`${ this.suites.passed } passed`));\n if (this.suites.skipped > 0) suitesParts.push(formatStatus.skipped(`${ this.suites.skipped } skipped`));\n if (this.suites.total > 0) suitesParts.push(`${ this.suites.total } total`);\n\n if (this.tests.failed > 0) testsParts.push(formatStatus.failed(`${ this.tests.failed } failed`));\n if (this.tests.passed > 0) testsParts.push(formatStatus.passed(`${ this.tests.passed } passed`));\n if (this.tests.skipped > 0) testsParts.push(formatStatus.skipped(`${ this.tests.skipped } skipped`));\n if (this.tests.todo > 0) testsParts.push(formatStatus.todo(`${ this.tests.todo } todo`));\n if (this.tests.total > 0) testsParts.push(`${ this.tests.total } total`); // total at the end\n\n const elapsedSeconds = ((Date.now() - this.startTime) / 1000).toFixed(3);\n this.status.writeBlock(\n 0,\n 0,\n `Suites: ${ suitesParts.length ? suitesParts.join(', ') : 'No suites yet' }\\n` +\n `Tests: ${ testsParts.length ? testsParts.join(', ') : 'No tests yet' }\\n` +\n `Time: ${ xterm.lightOrange(`${ elapsedSeconds } s`) }`,\n true\n );\n this.status.render();\n }\n\n /**\n * Renders the current state of all suites and their test details to the console.\n *\n * @remarks\n * This method iterates over all suites in {@link suiteMap} and writes:\n * - The suite title at the current row\n * - Each suite detail (e.g., test logs, errors) indented by 2 spaces\n *\n * It uses the {@link ShadowRenderer} instances (`info`) to render the content\n * and handles scrolling if the number of rows exceeds the renderer's height.\n * After rendering suites, it calls {@link updateState} to refresh the summary of global counters.\n *\n * @see suiteMap - Map containing per-suite statistics and details.\n * @see ShadowRenderer - Handles writing text to a shadow buffer and flushing to the terminal.\n * @see updateState - Updates the global summary of test and suite counters.\n *\n * @since 1.0.0\n */\n\n private renderSuites(): void {\n let row = 0;\n for (const [ , suite ] of this.suiteMap) {\n this.info.writeText(row++, 0, suite.title, true);\n\n for (const detail of suite.details) {\n this.info.writeText(row++, 2, ANSI.CLEAR_LINE + detail, true);\n }\n }\n\n if (row > this.info.height) {\n this.info.scroll = row - this.info.height;\n } else {\n this.info.render();\n }\n\n this.updateState();\n }\n\n /**\n * Generates a formatted prefix for a suite, including its status and runner name.\n *\n * @param status - The current {@link ConsoleState} of the suite (e.g., Run, Passed, Failed).\n * @param runner - The name of the runner executing the suite.\n * @param suiteName - The name of the suite.\n * @returns A formatted string with the suite status, optional runner name, and dimmed suite name.\n *\n * @remarks\n * - If `isSingleRunner` is true, the runner name is omitted.\n * - Uses {@link statePrefix} to map {@link ConsoleState} to a colored label.\n * - Suite name is dimmed for readability using {@link xterm.dim}.\n * - Runner name is colored with `xterm.burntOrange` when multiple runners are present.\n *\n * @see statePrefix\n * @see ConsoleState\n *\n * @since 1.0.0\n */\n\n private getPrefix(status: ConsoleState, runner: string, suiteName: string): string {\n const runnerPrefix = this.isSingleRunner ? '' :\n xterm.burntOrange(` [ ${ runner.padEnd(this.maxRunnerNameLength) } ]`);\n\n return `${ statePrefix[status] }${ runnerPrefix } ${ xterm.dim(suiteName) }`;\n }\n\n /**\n * Generates a formatted ANSI-colored prefix for a log message based on its level.\n *\n * @param log - The {@link LogMessageInterface} containing log level and details.\n * @returns A string representing the log level wrapped with the appropriate ANSI color codes.\n *\n * @remarks\n * - Maps {@link LogLevel} values to {@link formatStatus} or {@link xterm} colors:\n * - `Error` \u2192 `formatStatus.failed`\n * - `Warn` \u2192 `formatStatus.skipped`\n * - `Info` \u2192 `xterm.cyanBright`\n * - `Debug` \u2192 `formatStatus.running`\n * - Any other or default \u2192 `formatStatus.pending`\n * - The returned string is formatted as `[level]` in lowercase, colored according to its severity.\n *\n * @see LogMessageInterface\n * @see LogLevel\n * @see formatStatus\n * @see xterm\n *\n * @since 1.0.0\n */\n\n private getLogPrefix(log: LogMessageInterface): string {\n let statusPrefix = formatStatus.pending;\n\n switch (log.levelId) {\n case LogLevel.Error:\n statusPrefix = formatStatus.failed;\n break;\n case LogLevel.Warn:\n statusPrefix = formatStatus.skipped;\n break;\n case LogLevel.Info:\n statusPrefix = xterm.cyanBright;\n break;\n case LogLevel.Debug:\n statusPrefix = formatStatus.running;\n break;\n }\n\n return statusPrefix(`[ ${ log.level.toLowerCase() } ]`);\n }\n}\n", "/**\n * Imports\n */\n\nimport { xterm } from '@remotex-labs/xansi/xterm.component';\n\n/**\n * The fixed height in rows reserved for the console status display.\n *\n * @remarks\n * Used by {@link ConsoleReporter} and {@link ShadowRenderer} to reserve\n * space for the summary of suites and tests at the bottom of the terminal.\n *\n * @since 1.0.0\n */\n\nexport const STATIC_HEIGHT = 4;\n\n/**\n * ANSI color functions for rendering different statuses in the console.\n *\n * @remarks\n * Each property is a function that wraps a string in the corresponding color using `xterm.hex`.\n *\n * @example\n * ```ts\n * console.log(formatStatus.passed('Test Passed'));\n * ```\n *\n * @since 1.0.0\n */\n\nexport const formatStatus = {\n todo: xterm.hex('#da5aec'),\n failed: xterm.hex('#F08080'),\n passed: xterm.hex('#90EE90'),\n skipped: xterm.hex('#fcaa63'),\n running: xterm.hex('#FFD966'),\n pending: xterm.hex('#808080')\n} as const;\n\n/**\n * Mapping of {@link ConsoleState} to their corresponding display string with ANSI styling.\n *\n * @remarks\n * Used for rendering the status prefix of each suite in the console output.\n *\n * @example\n * ```ts\n * console.log(statePrefix[ConsoleState.Failed]); // Outputs a red \"[ FAILED ]\"\n * ```\n *\n * @since 1.0.0\n */\n\nexport const statePrefix: Record<ConsoleState, string> = {\n [ConsoleState.Pending]: formatStatus.pending('[ Pending ]'),\n [ConsoleState.Run]: formatStatus.running('[ RUNNING ]'),\n [ConsoleState.Skipped]: formatStatus.skipped('[ SKIPPED ]'),\n [ConsoleState.Passed]: formatStatus.passed('[ PASSED ]'),\n [ConsoleState.Failed]: formatStatus.failed('[ FAILED ]')\n};\n\n/**\n * Represents the possible states of a suite or test in the console reporter.\n *\n * @remarks\n * Used to determine which ANSI color and prefix to display for each suite or test.\n *\n * @example\n * ```ts\n * if (state === ConsoleState.Failed) {\n * console.log('This suite failed!');\n * }\n * ```\n *\n * @since 1.0.0\n */\n\nexport const enum ConsoleState {\n Run = 0,\n Failed = 2,\n Passed = 3,\n Skipped = 4,\n Pending = 5\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { AbstractTarget } from '@targets/abstract/target.abstract';\nimport type { ErrorType } from '@messages/interfaces/abstract.interface';\nimport type { AbstractReporter } from '@messages/abstract/report.abstract';\nimport type { PacketKind } from '@packets/constants/packet-schema.constants';\nimport type { DecodedPacketType } from '@packets/interfaces/packets.interface';\nimport type { LogMessageInterface, SuiteErrorInterface } from '@messages/interfaces/messages.interface';\nimport type { EndAssertionMessageInterface, EndMessageInterface } from '@messages/interfaces/messages.interface';\nimport type { StackMetadataInterface, StackTraceInterface } from '@providers/interfaces/stack-provider.interface';\nimport type { StartAssertionMessageInterface, StartMessageInterface } from '@messages/interfaces/messages.interface';\n\n/**\n * Imports\n */\n\nimport { stackMetadata } from '@providers/stack.provider';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { LogLevel, MessageType } from '@messages/constants/report.constant';\n\n/**\n * Service for translating low-level {@link AbstractTarget} events into structured reporter messages.\n *\n * @remarks\n * The `MessageService` subscribes to a given execution target and transforms its raw\n * events (logs, errors, suite lifecycle, test events) into structured messages.\n * These messages are forwarded to an {@link AbstractReporter} implementation.\n *\n * Responsibilities:\n * - Logging events (`log`) \u2192 {@link handleLog}\n * - Suite errors (`error`) \u2192 {@link handleSuiteError}\n * - Suite lifecycle (`status`) \u2192 {@link handleSuiteStatus}\n * - Assertions & describes (`events`) \u2192 {@link handleSuiteEvent}\n *\n * @example\n * ```ts\n * const service = new MessageService(target);\n * await service.init(['suite.spec.ts'], config);\n * ```\n *\n * @see AbstractTarget\n * @see AbstractReporter\n * @since 1.0.0\n */\n\nexport class MessageService {\n /**\n * Framework service reference for resolving source maps and code metadata.\n *\n * @remarks\n * Injected via the DI system. Used mainly to map logs and errors to their\n * original code positions for more precise reporting.\n *\n * @since 1.0.0\n */\n\n private readonly framework = inject(FrameworkService);\n\n /**\n * Indicates whether any test-level error has occurred.\n * @private\n */\n\n private error = false;\n\n /**\n * Indicates whether any suite-level error has occurred.\n * @private\n */\n\n private suiteError = false;\n\n /**\n * Creates a new `MessageService` and subscribes to target events.\n *\n * @param target - The execution target emitting logs, errors, and lifecycle events.\n * @param reporter - The active reporter receiving structured messages.\n *\n * @remarks\n * Binds the following listeners:\n * - `'log'` \u2192 {@link handleLog}\n * - `'error'` \u2192 {@link handleSuiteError}\n * - `'status'` \u2192 {@link handleSuiteStatus}\n * - `'events'` \u2192 {@link handleSuiteEvent}\n *\n * @since 1.0.0\n */\n\n constructor(readonly target: AbstractTarget, readonly reporter: AbstractReporter) {\n this.target.on('log', this.handleLog.bind(this));\n this.target.on('error', this.handleSuiteError.bind(this));\n this.target.on('status', this.handleSuiteStatus.bind(this));\n this.target.on('events', this.handleSuiteEvent.bind(this));\n }\n\n /**\n * Returns `true` if **any suite-level error** has been detected.\n * @returns `true` if a suite error occurred, otherwise `false`.\n *\n * @since 1.0.0\n */\n\n get hasSuiteError(): boolean {\n return this.suiteError;\n }\n\n /**\n * Returns `true` if **any test** has been detected.\n * @returns `true` if there is any error, otherwise `false`.\n *\n * @since 1.0.0\n */\n\n get hasError(): boolean {\n return this.error;\n }\n\n /**\n * Transforms a log packet into a {@link LogMessageInterface} and sends it to the reporter.\n *\n * @param log - The decoded log packet.\n * @param suitePath - Path of the suite that generated the log.\n *\n * @remarks\n * Resolves source position using source maps, attaches invocation context,\n * and passes the structured message to `reporter.log`.\n *\n * @example\n * ```ts\n * target.emit('log', logPacket, '/suite/path');\n * ```\n *\n * @see LogMessageInterface\n * @since 1.0.0\n */\n\n handleLog(log: DecodedPacketType<PacketKind.Log>, suitePath: string): void {\n const sourcemap = this.framework.getSourceMap(log.invocation.source);\n const source = sourcemap?.getPositionWithCode(log.invocation.line, log.invocation.column);\n\n const message: LogMessageInterface = {\n level: LogLevel[log.level] ?? 'UNKNOWN',\n suite: suitePath,\n runner: this.target.getRunnerName(log.runnerId),\n levelId: log.level,\n message: log.message,\n ancestry: log.ancestry.split(','),\n timestamp: new Date(log.timestamp)\n };\n\n if (source) {\n message.invocation = {\n code: source.code,\n line: source.line,\n column: source.column,\n source: source.source\n };\n }\n\n this.reporter.log?.(message);\n }\n\n /**\n * Transforms a suite error into an {@link EndMessageInterface} and sends it to the reporter.\n *\n * @param suiteError - The decoded error packet.\n * @param suitePath - Path of the suite where the error occurred.\n *\n * @remarks\n * Marks the suite as complete, decodes the error via {@link decodeError},\n * and forwards the message to `reporter.suiteEnd`.\n *\n * @see EndMessageInterface\n * @see SuiteErrorInterface\n * @since 1.0.0\n */\n\n handleSuiteError(suiteError: DecodedPacketType<PacketKind.Error>, suitePath: string): void {\n this.target.completeSuite(suiteError.runnerId + suiteError.suiteId, true);\n const message: EndMessageInterface = {\n suite: suitePath,\n error: <SuiteErrorInterface>this.decodeError(suiteError.error, { linesBefore: 2, linesAfter: 3 }),\n runner: this.target.getRunnerName(suiteError.runnerId),\n duration: 0,\n timestamp: new Date(suiteError.timestamp)\n };\n\n this.suiteError = true;\n this.reporter.suiteEnd?.(message);\n }\n\n /**\n * Handles suite lifecycle status updates.\n *\n * @param status - The decoded status packet.\n * @param suitePath - Path of the suite associated with the status.\n *\n * @remarks\n * Supported types:\n * - `StartSuite` \u2192 calls `reporter.suiteStart`\n * - `EndSuite` \u2192 marks suite complete and calls `reporter.suiteEnd`\n * - `Test` / `Describe` \u2192 builds a {@link StartAssertionMessageInterface} and calls `reporter.testStart` / `reporter.describeStart`\n *\n * @see MessageType\n * @see StartAssertionMessageInterface\n * @since 1.0.0\n */\n\n handleSuiteStatus(status: DecodedPacketType<PacketKind.Status>, suitePath: string): void {\n const baseMessage: StartMessageInterface = {\n suite: suitePath,\n runner: this.target.getRunnerName(status.runnerId),\n timestamp: new Date(status.timestamp)\n };\n\n switch (status.type) {\n case MessageType.StartSuite:\n this.reporter.suiteStart?.(baseMessage);\n break;\n case MessageType.EndSuite:\n this.target.completeSuite(status.runnerId + status.suiteId, false);\n (<EndMessageInterface> baseMessage).duration = status.duration;\n this.reporter.suiteEnd?.(<EndMessageInterface> baseMessage);\n break;\n case MessageType.Test:\n case MessageType.Describe: {\n const assertionMessage: StartAssertionMessageInterface = <StartAssertionMessageInterface> baseMessage;\n assertionMessage.ancestry = status.ancestry.split(',');\n assertionMessage.description = status.description;\n\n if (status.todo) assertionMessage.todo = true;\n if (status.skipped) assertionMessage.skipped = true;\n\n if (status.type === MessageType.Test) {\n this.reporter.testStart?.(assertionMessage);\n } else {\n this.reporter.describeStart?.(assertionMessage);\n }\n break;\n }\n }\n }\n\n /**\n * Handles completion of tests or describes.\n *\n * @param events - The decoded event's packet.\n * @param suitePath - Path of the suite associated with this event.\n *\n * @remarks\n * Builds an {@link EndAssertionMessageInterface}, attaches errors if present,\n * and forwards it to `reporter.testEnd` or `reporter.describeEnd`.\n *\n * Sets `hasError = true` if errors are present.\n *\n * @see EndAssertionMessageInterface\n * @since 1.0.0\n */\n\n handleSuiteEvent(events: DecodedPacketType<PacketKind.Events>, suitePath: string): void {\n const message: EndAssertionMessageInterface = {\n suite: suitePath,\n passed: true,\n runner: this.target.getRunnerName(events.runnerId),\n duration: events.duration,\n ancestry: events.ancestry.split(','),\n timestamp: new Date(events.timestamp),\n description: events.description\n };\n\n if (events.errors) {\n message.errors = <Array<SuiteErrorInterface>>this.decodeError(events.errors, { linesBefore: 2, linesAfter: 3 });\n message.passed = false;\n this.error = true;\n }\n\n if(events.type === MessageType.Test) {\n this.reporter.testEnd?.(message);\n } else {\n this.reporter.describeEnd?.(message);\n }\n }\n\n /**\n * Parses and structures an error or error array.\n *\n * @param error - JSON stringified error(s).\n * @param options - Optional stack trace metadata.\n * @returns Structured error(s).\n *\n * @remarks\n * - Parses into {@link ErrorType}.\n * - Enhances with {@link stackMetadata}.\n * - Falls back to caught error if parsing fails.\n *\n * @see SuiteErrorInterface\n * @since 1.0.0\n */\n\n private decodeError(error: string, options: StackTraceInterface = {}): SuiteErrorInterface | Array<SuiteErrorInterface> {\n try {\n const errorObject: ErrorType = JSON.parse(error);\n if (Array.isArray(errorObject)) {\n return errorObject.map(err => {\n return this.structuredError(\n err,\n stackMetadata(err, options)\n );\n });\n }\n\n return this.structuredError(\n errorObject,\n stackMetadata(errorObject, options)\n );\n } catch (e) {\n return this.structuredError(\n <ErrorType>e, stackMetadata(<ErrorType>e, options)\n );\n }\n }\n\n /**\n * Converts an {@link ErrorType} into a {@link SuiteErrorInterface}.\n *\n * @param error - Original error object.\n * @param metadata - Stack metadata for enriching error details.\n * @returns A structured error object.\n *\n * @remarks\n * Builds a standardized shape with name, message, matcher result,\n * and enriched stack/position info.\n *\n * @see ErrorType\n * @see StackMetadataInterface\n * @since 1.0.0\n */\n\n private structuredError(error: ErrorType, metadata: StackMetadataInterface): SuiteErrorInterface {\n return {\n name: error.name,\n line: metadata.line,\n code: metadata.code,\n formatCode: metadata.formatCode,\n stack: metadata.stacks,\n column: metadata.column,\n message: error.message,\n matcherResult: error.matcherResult\n };\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { RunnerInterface } from '@targets/interfaces/traget.interface';\nimport type { ModuleInterface, TranspileFileType } from '@services/interfaces/transpiler-service.interface';\n\n/**\n * Imports\n */\n\nimport * as process from 'process';\nimport { pathToFileURL } from 'url';\nimport { createRequire } from 'module';\nimport { dirname, relative, resolve } from 'path';\nimport { sandboxExecute } from '@services/vm.service';\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { AbstractTarget } from '@targets/abstract/target.abstract';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Local execution target for running tests within the local JavaScript environment.\n *\n * @remarks\n * The `LocalService` executes tests directly in a sandboxed environment\n * rather than using external runners. It handles:\n * - Test execution\n * - Error handling\n * - Source mapping and runtime context injection for accurate reporting\n *\n * @example\n * ```ts\n * const localService = new LocalService(config, frameworkService);\n * await localService.initTarget();\n * await localService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see PacketKind\n * @see AbstractTarget\n * @see TranspileFileType\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class LocalService extends AbstractTarget {\n /**\n * Unique identifier for the local runner instance.\n *\n * @remarks\n * This ID is generated when the `LocalService` instance is created and is used\n * to track test suites executed in the local environment. It ensures that each\n * suite execution can be associated with a specific runner for reporting and\n * error handling purposes.\n *\n * @since 1.0.0\n */\n\n private runnerId: string = this.generateId();\n\n /**\n * Returns the name of the local runner.\n *\n * @remarks\n * Since `LocalService` only has a single runner, this method always returns\n * the string `'local'`. It is used to identify the runner in reports,\n * events, and suite execution tracking.\n *\n * @returns The string `'local'`.\n *\n * @since 1.0.0\n */\n\n getRunnerName(): string {\n return 'local';\n }\n\n /**\n * Returns an array containing the local runner.\n *\n * @returns An array with a single object:\n * - `id`: The unique runner ID (`runnerId`).\n * - `name`: The runner name, always `'local'`.\n *\n * @remarks\n * `LocalService` only manages a single local runner. This method provides\n * a consistent interface with other targets by returning an array of\n * `RunnerInterface` objects, each with an `id` and `name`.\n *\n * @example\n * ```ts\n * const runners = localService.getRunners();\n * console.log(runners[0].id); // e.g., 'local-123'\n * console.log(runners[0].name); // 'local'\n * ```\n *\n * @since 1.0.0\n */\n\n getRunners(): Array<RunnerInterface> {\n return [\n {\n id: this.runnerId,\n name: this.getRunnerName()\n }\n ];\n }\n\n /**\n * Executes the provided transpiled test suites in a sandboxed local environment.\n *\n * @param transpileSuites - An array of transpiled test files to execute.\n * @param suites - A record mapping original suite names to their file paths.\n *\n * @remarks\n * This method registers the provided suites using `setSuites` and queues each\n * transpiled test file for execution using the internal queue. Each suite is\n * executed in the local sandbox via `executeTestWithErrorHandling`.\n *\n * Errors during execution are captured and emitted via the `eventEmitter`, but\n * do not halt the execution of other suites. The queue ensures controlled,\n * asynchronous execution of all tasks.\n *\n * @example\n * ```ts\n * await localService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see {@link setSuites} to register suites internally.\n * @see {@link executeTestWithErrorHandling} for individual suite execution logic.\n *\n * @since 1.0.0\n */\n\n async executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void> {\n this.setSuites(suites);\n const testExecutionTasks: Array<Promise<void>> = [];\n\n for (const transpile of transpileSuites) {\n const relativePath = relative(this.framework.rootPath, transpile.path)\n .replace(/\\.[^/.]+$/, '');\n\n testExecutionTasks.push(this.queue.enqueue(async () => {\n return this.executeTestWithErrorHandling(transpile.code, transpile.path, relativePath);\n }));\n }\n\n this.queue.start();\n await Promise.allSettled(testExecutionTasks);\n }\n\n /**\n * Executes test code in a local sandboxed environment.\n *\n * @param testCode - The transpiled test code to execute.\n * @param transpileFilePath - The original file path of the test file.\n * @param suiteId - The unique ID of the suite being executed.\n *\n * @remarks\n * This method creates a sandboxed execution context including\n * - Node.js globals (`Buffer`, `console`, timers)\n * - A `module` object for CommonJS exports\n * - A `require` function scoped to the test file\n * - A `__XJET` runtime context containing configuration and suite metadata\n * - A `dispatch` function for emitting test events\n *\n * The `sandboxExecute` function runs the test code within this isolated context.\n *\n * @example\n * ```ts\n * await localService.executeInSandbox(testCode, '/path/to/test.spec.ts', suiteId);\n * ```\n *\n * @since 1.0.0\n */\n\n private async executeInSandbox(testCode: string, transpileFilePath: string, suiteId: string): Promise<void> {\n const path = this.suites.get(suiteId)!;\n const module: ModuleInterface = { exports: {} };\n const require = createRequire(transpileFilePath);\n\n const safeProcess = Object.freeze({\n ...process,\n stdout: { write: (): void => {} },\n stderr: { write: (): void => {} }\n });\n\n const sandboxContext = {\n ...globalThis,\n Buffer,\n module,\n require,\n setTimeout,\n setInterval,\n clearTimeout,\n clearInterval,\n process: safeProcess,\n dispatch: this.dispatch.bind(this),\n __dirname: dirname(path),\n __filename: path,\n import_meta: {\n url: pathToFileURL(path),\n dirname: dirname(resolve(path)),\n filename: path\n },\n __XJET: {\n runtime: {\n bail: this.config.bail,\n path: path,\n filter: this.config.filter,\n timeout: this.config.timeout,\n suiteId: suiteId,\n runnerId: this.runnerId,\n randomize: this.config.randomize\n }\n }\n };\n\n await sandboxExecute(testCode, sandboxContext);\n }\n\n /**\n * Executes a single test suite in the local sandbox with error handling.\n *\n * @param testCode - The transpiled test code to execute.\n * @param filePath - The original file path of the test file.\n * @param relativePath - The relative path used to retrieve the suite ID.\n *\n * @returns A `Promise` that resolves when the suite has been executed or fails gracefully.\n *\n * @remarks\n * This method wraps the execution of a test suite in a `Promise` and tracks\n * it in the `runningSuites` map using the suite ID. If `executeInSandbox`\n * throws an error, the suite is marked as complete with failure, and an\n * 'error' event is emitted via the `eventEmitter`.\n *\n * The emitted error includes:\n * - `kind`: The packet type (`PacketKind.Error`)\n * - `error`: The serialized error object\n * - `suiteId`: The unique ID of the suite\n * - `runnerId`: The ID of the local runner\n *\n *\n * @example\n * ```ts\n * await localService.executeTestWithErrorHandling(testCode, '/path/to/test.spec.ts', 'tests/test.spec');\n * ```\n *\n * @since 1.0.0\n */\n\n private executeTestWithErrorHandling(testCode: string, filePath: string, relativePath: string): Promise<void> {\n const suiteId = this.suites.get(relativePath)!;\n\n return new Promise(async (resolve, reject) => {\n try {\n this.runningSuites.set(this.runnerId + suiteId, { resolve, reject });\n await this.executeInSandbox(testCode, filePath, suiteId);\n } catch (error) {\n this.completeSuite(this.runnerId + suiteId, true);\n this.eventEmitter.emit('error', {\n kind: PacketKind.Error,\n error: JSON.stringify(serializeError(error)),\n suiteId: suiteId,\n runnerId: this.runnerId,\n timestamp: new Date()\n }, this.suites.get(suiteId)!);\n }\n });\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { DecodedPacketType } from '@packets/packets.module';\nimport type { FunctionLikeType, FunctionType } from '@remotex-labs/xjet-expect';\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { ConfigurationInterface } from '@configuration/interfaces/configuration.interface';\nimport type { RunnerInterface, RunningSuitesInterface } from '@targets/interfaces/traget.interface';\n\n/**\n * Imports\n */\n\nimport EventEmitter from 'events';\nimport { xJetError } from '@errors/xjet.error';\nimport { decodePacket } from '@packets/packets.module';\nimport { QueueService } from '@services/queue.service';\nimport { inject } from '@symlinks/services/inject.service';\nimport { FrameworkService } from '@services/framework.service';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Abstract Target class for all xJet execution targets.\n *\n * @remarks\n * A `AbstractTarget` defines the core lifecycle and event-handling logic\n * used by concrete target implementations (e.g., local, remote, or distributed).\n * It manages suites, event dispatching, and lifecycle completion.\n *\n * @since 1.0.0\n */\n\nexport abstract class AbstractTarget {\n /**\n * Queue service responsible for scheduling and executing tasks.\n * @since 1.0.0\n */\n\n protected readonly queue: QueueService;\n\n /**\n * Tracks the currently running test suites and their associated promises.\n * @since 1.0.0\n */\n\n protected readonly runningSuites: Map<string, RunningSuitesInterface> = new Map();\n\n /**\n * Registry of loaded test suites keyed by suite identifier.\n * @since 1.0.0\n */\n\n protected readonly suites: Map<string, string> = new Map();\n\n /**\n * Event emitter used for handling log, error, status, and event packets.\n * @since 1.0.0\n */\n\n protected readonly eventEmitter = new EventEmitter();\n\n /**\n * Creates a new runner service instance.\n *\n * @param config - The runtime configuration for the runner.\n *\n * @remarks\n * The {@link FrameworkService} is injected automatically and does not need\n * to be passed manually. The constructor initializes the {@link QueueService}\n * with the parallelism level defined in the configuration.\n *\n * @since 1.0.0\n */\n\n protected readonly framework: FrameworkService = inject(FrameworkService);\n\n /**\n * Initializes a new {@link AbstractTarget} instance.\n *\n * @param config - The runtime configuration that controls execution behavior,\n * such as parallelism and bail mode.\n *\n * @remarks\n * The constructor sets up the internal {@link QueueService} based on the\n * configured parallelism level. Other dependencies (e.g., {@link FrameworkService})\n * are injected automatically and not passed here.\n *\n * @since 1.0.0\n */\n\n constructor(protected config: ConfigurationInterface) {\n this.queue = new QueueService(this.config.parallel);\n }\n\n /**\n * Returns the number of currently active tasks in the queue.\n * @since 1.0.0\n */\n\n get numberActiveTask(): number {\n return this.queue.size;\n }\n\n /**\n * Initializes the target environment with the given specification files.\n * @returns A `Promise` that resolves when the initialization is complete.\n *\n * @remarks\n * Implementations should ensure that the target is fully ready for later\n * operations after this method completes.\n *\n * @see {@link disconnect} for cleaning up the target environment.\n * @since 1.0.0\n */\n\n initTarget?(): Promise<void>;\n\n /**\n * Frees resources and cleans up the target.\n *\n * @returns A `Promise` that resolves when all resources have been freed.\n *\n * @remarks\n * This abstract method must be implemented by subclasses of `AbstractTarget`.\n * It should handle all necessary teardown and resource releases associated with the target,\n * ensuring a clean shutdown and preventing resource leaks.\n *\n * @see {@link disconnect} for terminating the target's active connections.\n * @since 1.0.0\n */\n\n freeTarget?(): Promise<void>;\n\n /**\n * Resolves a human-readable runner name for a given runner identifier.\n *\n * @param runnerId - Identifier of the runner\n *\n * @since 1.0.0\n */\n\n abstract getRunnerName(runnerId: string): string;\n\n /**\n * Retrieves all registered runners for the target.\n *\n * @returns An array of {@link RunnerInterface} instances representing all active runners.\n *\n * @remarks\n * Each runner represents a test execution context. Implementations of this method should\n * return all currently available runners, whether they are local or external.\n *\n * @see RunnerInterface\n * @since 1.0.0\n */\n\n abstract getRunners(): Array<RunnerInterface>;\n\n /**\n * Executes the provided test or transpiled suites on this target.\n *\n * @param transpileSuites - The transpiled suite files to execute.\n * @param suites - A record mapping original file names to their content.\n *\n * @returns A `Promise` that resolves once all suites have been executed.\n *\n * @remarks\n * This abstract method must be implemented by subclasses of `AbstractTarget`.\n * It should handle the execution of all provided suites, applying them to the\n * target environment and using the corresponding original files as needed.\n *\n * Implementations may include:\n * - Transpiling or preparing files for execution\n * - Running tests or suites in the target environment\n * - Collecting and reporting results or errors\n *\n * @see {@link initTarget}, {@link disconnect}, {@link freeTarget} for target lifecycle methods.\n *\n * @since 1.0.0\n */\n\n abstract executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void>;\n\n /**\n * Subscribe to log events emitted during test execution.\n *\n * @remarks\n * These logs correspond to runtime messages (`console.log`, `console.info`,\n * `console.warn`, `console.error`, etc.) generated inside tests, describe\n * blocks, or hooks. The listener receives the decoded log packet\n * ({@link DecodedPacketType} with {@link PacketKind.Log})\n * along with the test file path.\n *\n * @param key - Must be `'log'`.\n * @param listener - A handler invoked with the decoded log packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketLogInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'log', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Log>, string ]>): this;\n\n /**\n * Subscribe to fatal suite error events.\n *\n * @remarks\n * These errors occur at the suite level and are **not** tied to individual\n * tests, describe blocks, or hooks. The listener receives the decoded error\n * packet ({@link DecodedPacketType} with {@link PacketKind.Error})\n * along with the test file path.\n *\n * @param key - Must be `'error'`.\n * @param listener - A handler invoked with the decoded error packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketErrorInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'error', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Error>, string ]>): this;\n\n /**\n * Subscribe to test or describe completion events.\n *\n * @remarks\n * These events are emitted when a test or describe block **finishes execution**.\n * Skipped and TODO tests are excluded. The listener receives the decoded events\n * packet ({@link DecodedPacketType} with {@link PacketKind.Events})\n * along with the test file path.\n *\n * @param key - Must be `'events'`.\n * @param listener - A handler invoked with the decoded events packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketEventsInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'events', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Events>, string ]>): this;\n\n /**\n * Subscribe to test or describe status updates.\n *\n * @remarks\n * These events are emitted when a test or describe block **starts**, is\n * **skipped**, or marked as **TODO**. The listener receives the decoded\n * status packet ({@link DecodedPacketType} with {@link PacketKind.Status})\n * along with the originating test file path.\n *\n * @param key - Must be `'status'`.\n * @param listener - A handler invoked with the decoded status packet and file path.\n *\n * @see DecodedPacketType\n * @see PacketStatusInterface\n *\n * @since 1.0.0\n */\n\n on(key: 'status', listener: FunctionLikeType<void, [ DecodedPacketType<PacketKind.Status>, string ]>): this;\n\n /**\n * Generic listener registration.\n *\n * @param key - Event name\n * @param listener - The listener function\n *\n * @since 1.0.0\n */\n\n on(key: string | symbol, listener: FunctionType): this {\n this.eventEmitter.on(key, listener);\n\n return this;\n }\n\n /**\n * Marks a test suite as complete and resolves or rejects its associated promise.\n *\n * @remarks\n * This method is called when a suite finishes execution or encounters a fatal error.\n * - If `hasError` is `true` and the configuration has `bail` enabled, all remaining tasks in the queue are stopped\n * and the suite's promise is rejected.\n * - Otherwise, the suite's promise is resolved normally.\n *\n * After completion, the suite is removed from the `runningSuites` map.\n *\n * @param suiteId - The unique identifier of the test suite.\n * @param hasError - Whether the suite encountered a fatal error. Defaults to `false`.\n *\n * @since 1.0.0\n */\n\n completeSuite(suiteId: string, hasError = false): void {\n const suiteContext = this.runningSuites.get(suiteId);\n if (!suiteContext) {\n return;\n }\n\n this.runningSuites.delete(suiteId);\n if (hasError && this.config.bail) {\n this.queue.stop();\n this.queue.clear();\n suiteContext.reject();\n } else {\n suiteContext.resolve();\n }\n }\n\n /**\n * Processes a raw packet buffer received from a runner and emits the corresponding event.\n *\n * @param buffer - The raw buffer containing the encoded packet.\n *\n * @throws xJetError - If the packet belongs to an unregistered suite or has an invalid kind.\n *\n * @remarks\n * The method decodes the packet using the schema defined in {@link PacketSchemas} and routes it\n * to the appropriate event based on its kind:\n * - `PacketKind.Log` \u2192 emits a `'log'` event\n * - `PacketKind.Error` \u2192 marks the suite as complete with an error and emits an `'error'` event\n * - `PacketKind.Status` \u2192 emits a `'status'` event (for start, skip, or TODO)\n * - `PacketKind.Events` \u2192 emits an `'events'` event (for test/describe end that is not skipped or TODO)\n *\n * If the packet's `suiteId` is not registered in the `suites` map, an {@link xJetError} is thrown.\n * Any unknown `kind` also results in an {@link xJetError}.\n *\n * @since 1.0.0\n */\n\n protected dispatch(buffer: Buffer): void {\n const data = decodePacket(buffer);\n const suitePath = this.suites.get(data.suiteId);\n if (!suitePath) throw new xJetError(\n `Runner '${ data.runnerId }' in test suite '${ data.suiteId }' is not registered`\n );\n\n switch (data.kind) {\n case PacketKind.Log:\n this.eventEmitter.emit('log', data, suitePath);\n break;\n\n case PacketKind.Error:\n this.completeSuite(data.runnerId + data.suiteId, true);\n this.eventEmitter.emit('error', data, suitePath);\n break;\n\n case PacketKind.Status:\n this.eventEmitter.emit('status', data, suitePath);\n break;\n\n case PacketKind.Events:\n this.eventEmitter.emit('events', data, suitePath);\n break;\n\n default:\n const errorMessage = `Invalid schema type '${ data.kind }' detected for runner '${ data.runnerId }' in test suite '${ data.suiteId }'`;\n throw new xJetError(errorMessage);\n }\n }\n\n /**\n * Generates a pseudo-random alphanumeric identifier.\n *\n * @returns A pseudo-random alphanumeric string.\n *\n * @remarks\n * The ID is composed of two concatenated random strings, each derived from\n * `Math.random()` and converted to base-36, then truncated to 7 characters.\n * This method is typically used to create unique identifiers for suites,\n * runners, or tasks at runtime. Note that the IDs are not cryptographically secure.\n *\n * @since 1.0.0\n */\n\n protected generateId(): string {\n return Math.random().toString(36).substring(2, 9) + Math.random().toString(36).substring(2, 9);\n }\n\n /**\n * Registers multiple suites in the target's internal map.\n *\n * @param suites - A record mapping suite name to their file paths.\n *\n * @remarks\n * This method clears any previously registered suites and adds the provided ones.\n * Each suite is stored in the internal `suites` map in two ways:\n * 1. They generated unique ID maps to the suite's file path.\n * 2. The original suite name maps to the generated ID.\n *\n * This allows suites to be accessed either by their unique ID or by their original name.\n * The suite content itself is not duplicated in memory; only references and IDs are stored.\n *\n * @example\n * ```ts\n * this.setSuites({\n * \"loginTests\": \"/path/to/login.spec.ts\",\n * \"signupTests\": \"/path/to/signup.spec.ts\"\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n protected setSuites(suites: Record<string, string>): void {\n this.suites.clear();\n if(!suites) throw new xJetError(\n 'Suites must be provided to register them in the target'\n );\n\n for (const [ suiteName, path ] of Object.entries(suites)) {\n const id = this.generateId();\n this.suites.set(id, path);\n this.suites.set(suiteName, id);\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { PacketHeaderInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { DecodedPacketType, PacketPayloadMapType } from '@packets/interfaces/packets.interface';\n\n/**\n * Imports\n */\n\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\nimport { errorSchema, headerSchema } from '@packets/schema/packet.schema';\nimport { PacketSchemas } from '@packets/constants/packet-schema.constants';\n\n/**\n * Exports constants\n */\n\nexport * from '@packets/constants/packet-schema.constants';\n\n/**\n * Exports interfaces\n */\n\nexport * from '@packets/interfaces/packets.interface';\nexport * from '@packets/interfaces/packet-schema.interface';\n\n/**\n * Encodes a packet of a given kind into a `Buffer`.\n *\n * @template T - The packet kind (`PacketKind.Log`, `PacketKind.Error`, `PacketKind.Status`, or `PacketKind.Events`)\n *\n * @param kind - The type of packet to encode\n * @param data - Partial data matching the packet type; will be combined with header information\n *\n * @returns A `Buffer` containing the serialized packet\n *\n * @throws Error if the provided `kind` does not correspond to a known packet schema\n *\n * @remarks\n * This function combines a header and the payload according to the packet kind.\n * The header includes the suite ID, runner ID, and a timestamp.\n *\n * @since 1.0.0\n */\n\nexport function encodePacket<T extends PacketKind>(kind: T, data: Partial<PacketPayloadMapType[T]>): Buffer {\n const schema = PacketSchemas[kind];\n if (!schema) throw new Error(`Invalid schema kind: ${ kind }`);\n\n const header: PacketHeaderInterface = {\n kind: kind,\n suiteId: globalThis?.__XJET?.runtime?.suiteId ?? '',\n runnerId: globalThis?.__XJET?.runtime.runnerId ?? '',\n timestamp: (new Date()).toISOString()\n };\n\n return Buffer.concat([\n headerSchema.toBuffer(header),\n schema.toBuffer(data)\n ]);\n}\n\n/**\n * Decodes a packet from a `Buffer` into its corresponding object representation.\n *\n * @template T - The expected packet kind (`PacketKind.Log`, `PacketKind.Error`, `PacketKind.Status`, or `PacketKind.Events`)\n *\n * @param buffer - The buffer containing the encoded packet\n * @returns The decoded packet object, combining the header and payload fields\n *\n * @throws Error if the packet kind is unknown or invalid\n *\n * @remarks\n * Decodes both the header and payload based on the packet kind.\n *\n * @since 1.0.0\n */\n\nexport function decodePacket<T extends PacketKind>(buffer: Buffer): DecodedPacketType<T> {\n let offset = headerSchema.size;\n const header = headerSchema.toObject(buffer, (dynamicOffset: number): void => {\n offset += dynamicOffset;\n });\n\n const type = header.kind as PacketKind;\n const schema = PacketSchemas[type];\n if (!schema) {\n throw new Error(`Unknown packet kind: ${ type }`);\n }\n\n const dataBuffer = buffer.subarray(offset);\n const data = schema.toObject(dataBuffer) as PacketPayloadMapType[T];\n\n return { ...header, ...data };\n}\n\n/**\n * Encodes an {@link Error} instance into a binary buffer following the packet schema.\n *\n * @param error - The error object to be serialized and encoded.\n * @param suiteId - Identifier of the suite where the error occurred.\n * @param runnerId - Identifier of the runner reporting the error.\n *\n * @returns A {@link Buffer} containing the encoded error packet, ready for transmission.\n *\n * @remarks\n * The function creates two binary sections:\n * - A **header**, describing the packet kind (`Error`), suite ID, runner ID, and timestamp.\n * - A **data buffer**, holding the serialized error details in JSON format.\n *\n * These two sections are concatenated into a single buffer.\n *\n * @example\n * ```ts\n * try {\n * throw new Error(\"Test failed\");\n * } catch (err) {\n * const buffer = encodeErrorSchema(err, \"suite-123\", \"runner-456\");\n * socket.send(buffer); // transmit over a transport channel\n * }\n * ```\n *\n * @see serializeError\n * @see PacketKind.Error\n *\n * @since 1.0.0\n */\n\nexport function encodeErrorSchema(error: Error, suiteId: string, runnerId: string): Buffer {\n const header = headerSchema.toBuffer({\n kind: PacketKind.Error,\n suiteId: suiteId ?? '',\n runnerId: runnerId ?? '',\n timestamp: (new Date()).toISOString()\n });\n\n const dataBuffer = errorSchema.toBuffer({\n error: JSON.stringify(serializeError(error))\n });\n\n return Buffer.concat([ header, dataBuffer ]);\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { PacketLogInterface, PacketStatusInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { PacketErrorInterface, PacketEventsInterface } from '@packets/interfaces/packet-schema.interface';\nimport type { PacketHeaderInterface, PacketInvocationInterface } from '@packets/interfaces/packet-schema.interface';\n\n/**\n * Imports\n */\n\nimport { Struct } from '@remotex-labs/xstruct';\n\n/**\n * Schema for serializing and deserializing {@link PacketInvocationInterface} data.\n *\n * @remarks\n * Represents the location in source code where a test, describe, or log originates.\n *\n * @since 1.0.0\n */\n\nexport const invocationSchema = new Struct<PacketInvocationInterface>({\n line: 'UInt32LE',\n column: 'UInt32LE',\n source: 'string'\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketHeaderInterface} data.\n *\n * @remarks\n * Contains metadata for each packet, including kind, suite and runner identifiers, and timestamp.\n *\n * @since 1.0.0\n */\n\nexport const headerSchema = new Struct<PacketHeaderInterface>({\n kind: 'UInt8:4',\n suiteId: { type: 'string', size: 14 },\n runnerId: { type: 'string', size: 14 },\n timestamp: 'string'\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketLogInterface} data.\n *\n * @remarks\n * Used for console-like logs emitted by tests or describes, including message, level, ancestry, and invocation.\n *\n * @since 1.0.0\n */\n\nexport const logSchema = new Struct<PacketLogInterface>({\n level: 'UInt8',\n message: { type: 'string', lengthType: 'UInt32LE' },\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n invocation: invocationSchema\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketErrorInterface} data.\n *\n * @remarks\n * Represents suite-level fatal errors that are not tied to specific tests or describes.\n *\n * @since 1.0.0\n */\n\nexport const errorSchema = new Struct<PacketErrorInterface>({\n error: { type: 'string', lengthType: 'UInt32LE' }\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketStatusInterface} data.\n *\n * @remarks\n * Represents status updates for individual tests or describe blocks,\n * including whether it is TODO, skipped, and its ancestry and description.\n *\n * @since 1.0.0\n */\n\nexport const statusSchema = new Struct<PacketStatusInterface>({\n type: 'UInt8:5',\n todo: 'UInt8:1',\n skipped: 'UInt8:1',\n duration: 'UInt32LE',\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n description: { type: 'string', lengthType: 'UInt32LE' }\n});\n\n/**\n * Schema for serializing and deserializing {@link PacketEventsInterface} data.\n *\n * @remarks\n * Represents events emitted during the test or describe execution,\n * including pass/fail status, duration, error messages, ancestry, and invocation.\n *\n * @since 1.0.0\n */\n\nexport const eventsSchema = new Struct<PacketEventsInterface>({\n type: 'UInt8:5',\n passed: 'UInt8:1',\n duration: 'UInt32LE',\n ancestry: { type: 'string', lengthType: 'UInt32LE' },\n description: { type: 'string', lengthType: 'UInt32LE' },\n errors: { type: 'string', lengthType: 'UInt32LE' }\n});\n", "/**\n * Import will remove at compile time\n */\n\nimport type { Struct } from '@remotex-labs/xstruct';\n\n/**\n * Imports\n */\n\nimport { errorSchema, eventsSchema, logSchema, statusSchema } from '@packets/schema/packet.schema';\n\n/**\n * Defines the different kinds of packets that can be transmitted or received.\n *\n * @remarks\n * Each packet kind corresponds to a specific type of event or message in the test framework:\n * - `Log`: Console or logging messages\n * - `Error`: Suite-level fatal errors\n * - `Status`: Test or describe start events, including `skipped` and `todo` flags\n * - `Events`: Test or describe end events, only for completed tests/describes (no skipped or TODO)\n *\n * @since 1.0.0\n */\n\nexport const enum PacketKind {\n /**\n * Represents a log message packet, e.g., `console.log`, `console.error`.\n * @since 1.0.0\n */\n\n Log = 1,\n\n /**\n * Represents a fatal suite-level error.\n * Not associated with any test, describe, or hook.\n * @since 1.0.0\n */\n\n Error = 2,\n\n /**\n * Represents a status packet for test or describe start events.\n *\n * @remarks\n * Includes flags for:\n * - `skipped`: Whether the test or describe was skipped\n * - `todo`: Whether the test is marked as TODO\n *\n * @since 1.0.0\n */\n\n Status = 3,\n\n /**\n * Represents an event packet for test or describe end events.\n *\n * @remarks\n * Only includes completed tests/describes; skipped or TODO tests are not included.\n * Contains information such as `passed` and `duration`.\n *\n * @since 1.0.0\n */\n\n Events = 4\n}\n\n/**\n * Maps each {@link PacketKind} to its corresponding {@link Struct} schema for serialization/deserialization.\n *\n * @remarks\n * This object allows encoding and decoding packets of different kinds using\n * their respective `xStruct` schemas. Use `PacketSchemas[PacketKind.Log]` to\n * get the schema for log packets, etc.\n *\n * @see PacketKind\n * @see Struct\n *\n * @since 1.0.0\n */\n\nexport const PacketSchemas: Record<PacketKind, Struct> = {\n [PacketKind.Log]: logSchema,\n [PacketKind.Error]: errorSchema,\n [PacketKind.Status]: statusSchema,\n [PacketKind.Events]: eventsSchema\n} as const;\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TaskInterface } from '@services/interfaces/queue-service.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable } from '@symlinks/services/inject.service';\n\n/**\n * A service that manages asynchronous tasks with configurable concurrency.\n *\n * @remarks\n * This queue allows tasks to be enqueued and executed with a limit on the number of\n * concurrently running tasks. Tasks can be paused, resumed, cleared, or removed by runner ID.\n *\n * @example\n * ```ts\n * const queue = new QueueService(2);\n * queue.start();\n * queue.enqueue(async () => {\n * console.log(\"Task executed\");\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class QueueService {\n /**\n * Controls whether the queue processing is active or paused\n * @since 1.0.0\n */\n\n private paused = true;\n\n /**\n * Tracks the number of tasks currently being executed\n * @since 1.0.0\n */\n\n private activeCount = 0;\n\n /**\n * Maximum number of tasks that can execute concurrently\n * @since 1.0.0\n */\n\n private readonly concurrencyLimit: number;\n\n /**\n * Contains the pending tasks waiting to be processed\n * @since 1.0.0\n */\n\n private queue: Array<TaskInterface> = [];\n\n /**\n * Creates a new QueueService instance.\n *\n * @param concurrencyLimit - Maximum number of concurrent tasks (defaults to 1 if non-positive)\n * @default concurrencyLimit - 1\n *\n * @since 1.0.0\n */\n\n constructor(concurrencyLimit?: number) {\n this.concurrencyLimit = concurrencyLimit && concurrencyLimit > 0 ? concurrencyLimit : 1;\n }\n\n /**\n * Returns the number of tasks currently in the queue.\n *\n * @returns The number of pending tasks\n * @since 1.0.0\n */\n\n get size(): number {\n return this.queue.length;\n }\n\n /**\n * Returns the number of tasks currently running.\n *\n * @returns The number of active tasks\n * @since 1.0.0\n */\n\n get running(): number {\n return this.activeCount;\n }\n\n /**\n * Returns whether the queue is currently paused.\n *\n * @returns `true` if the queue is paused, otherwise `false`\n * @since 1.0.0\n */\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n /**\n * Pauses the processing of the queue.\n *\n * @since 1.0.0\n */\n\n stop(): void {\n this.paused = true;\n }\n\n /**\n * Resumes processing of the queue if it was paused.\n *\n * @since 1.0.0\n */\n\n start(): void {\n if (this.paused) {\n this.paused = false;\n // Start processing queue tasks again\n this.processQueue();\n }\n }\n\n /**\n * Clears all pending tasks from the queue and rejects their promises.\n *\n * @returns The number of tasks that were removed\n * @since 1.0.0\n */\n\n clear(): number {\n const count = this.queue.length;\n\n this.queue.forEach(taskItem => {\n if ('reject' in taskItem) {\n taskItem.reject();\n }\n });\n\n this.queue = [];\n\n return count;\n }\n\n /**\n * Adds a task to the queue and returns a promise for its result.\n *\n * @template T - The type of value that the task resolves to\n * @param task - A function returning a promise representing the asynchronous task\n * @param runnerId - Optional identifier for the runner executing this task\n *\n * @returns A promise that resolves or rejects with the task's result\n *\n * @see {@link TaskInterface}\n * @since 1.0.0\n */\n\n enqueue<T>(task: () => Promise<T>, runnerId?: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n // Wrap the task to handle its completion\n const wrappedTask = async (): Promise<void> => {\n try {\n const result = await task();\n resolve(result);\n } catch (error) {\n reject(error);\n } finally {\n this.activeCount--;\n this.processQueue();\n }\n };\n\n this.queue.push({ task: wrappedTask, runnerId, reject, resolve });\n if (!this.paused) {\n this.processQueue();\n }\n });\n }\n\n /**\n * Removes all tasks associated with a specific runner ID.\n *\n * @param runnerId - The ID of the runner whose tasks should be removed\n *\n * @returns The number of tasks removed\n * @since 1.0.0\n */\n\n removeTasksByRunner(runnerId: string): number {\n const initialCount = this.queue.length;\n this.queue = this.queue.filter(item => item.runnerId !== runnerId);\n\n return initialCount - this.queue.length;\n }\n\n /**\n * Processes tasks in the queue according to the concurrency limit.\n *\n * @since 1.0.0\n */\n\n private processQueue(): void {\n if (this.paused) {\n return;\n }\n\n while (this.activeCount < this.concurrencyLimit && this.queue.length > 0) {\n const item = this.queue.shift();\n if (item) {\n this.activeCount++;\n item.task();\n }\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { TranspileFileType } from '@services/interfaces/transpiler-service.interface';\nimport type { TestRunnerInterface } from '@configuration/interfaces/configuration.interface';\nimport type { RunnerInterface, RuntimeConfigInterface } from '@targets/interfaces/traget.interface';\n\n/**\n * Imports\n */\nimport yargs from 'yargs';\nimport { pathToFileURL } from 'url';\nimport { dirname, relative } from 'path';\nimport { xJetError } from '@errors/xjet.error';\nimport { serializeError } from '@remotex-labs/xjet-expect';\nimport { withTimeout } from '@components/timeout.component';\nimport { Injectable } from '@symlinks/services/inject.service';\nimport { AbstractTarget } from '@targets/abstract/target.abstract';\nimport { PacketKind } from '@packets/constants/packet-schema.constants';\n\n/**\n * Implementation of a test execution target that runs tests in external runners.\n *\n * @remarks\n * The `ExternalService` coordinates test execution across external processes or environments.\n * It connects to configured test runners, dispatches test code, and manages their lifecycle:\n * initialization (`initTarget`), execution (`executeSuites`), and cleanup (`freeTarget`).\n *\n * Unlike {@link LocalService}, which runs tests in a local sandbox, this class offloads execution\n * to one or more external runners (e.g., browser, VM, or remote environment).\n *\n * @example\n * ```ts\n * const config = {\n * testRunners: [\n * { name: 'chrome', connection: connectChromeRunner, connectionTimeout: 5000 }\n * ]\n * };\n *\n * const externalTarget = new ExternalService(config);\n * await externalTarget.initTarget();\n * await externalTarget.executeSuites(transpileFiles, originalFiles);\n * await externalTarget.freeTarget();\n * ```\n *\n * @see LocalService\n * @see AbstractTarget\n * @see TestRunnerInterface\n *\n * @since 1.0.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class ExternalService extends AbstractTarget {\n /**\n * A map of all registered test runners.\n *\n * @remarks\n * The key is the unique runner ID (generated internally), and the value is\n * the corresponding `TestRunnerInterface` instance. This map tracks all\n * runners connected to this target and is used to dispatch test suites\n * during execution.\n *\n * @example\n * ```ts\n * for (const [id, runner] of externalService.runners) {\n * console.log(`Runner ${runner.name} has ID: ${id}`);\n * }\n * ```\n *\n * @since 1.0.0\n */\n\n readonly runners: Map<string, TestRunnerInterface> = new Map();\n\n /**\n * Initializes all configured external test runners.\n *\n * @throws xJetError - If no test runners are configured.\n *\n * @remarks\n * This method sets up the target environment by connecting to each test runner\n * defined in the configuration (`this.config.testRunners`). It also parses\n * optional CLI arguments provided via `this.config.userArgv` using `yargs`.\n *\n * All runner connections are initiated concurrently using `Promise.allSettled`\n * to ensure the target attempts to connect to every runner, even if some fail.\n *\n * @example\n * ```ts\n * await externalService.initTarget();\n * // All configured runners are now connected and ready to execute suites\n * ```\n *\n * @since 1.0.0\n */\n\n async initTarget(): Promise<void> {\n if (!this.config.testRunners || this.config.testRunners.length === 0)\n throw new xJetError('No test runners configured');\n\n let argv: Record<string, unknown> = {};\n if (this.config.userArgv) {\n argv = yargs(process.argv.slice(2))\n .options(this.config.userArgv)\n .parseSync();\n }\n\n await Promise.all(\n this.config.testRunners.map(runner => this.connectRunner(runner, argv))\n );\n }\n\n /**\n * Frees all resources associated with the target.\n *\n * @remarks\n * This method disconnects all registered test runners by calling their\n * `disconnect` method (if available). It is intended to be called when the\n * target is no longer needed, ensuring a clean shutdown and preventing\n * resource leaks.\n *\n * Disconnections are performed concurrently using `Promise.allSettled` so\n * that all runners are attempted even if some fail to disconnect.\n *\n * @example\n * ```ts\n * await externalService.freeTarget();\n * // All connected runners are now disconnected\n * ```\n *\n * @see {@link initTarget} to initialize runners before execution.\n * @see {@link executeSuites} for running suites on the connected runners.\n *\n * @since 1.0.0\n */\n\n async freeTarget(): Promise<void> {\n const disconnectionPromises = [];\n const runners = Array.from(this.runners.values());\n\n for (let i = 0; i < runners.length; i++) {\n const runner = runners[i];\n if (runner?.disconnect) {\n disconnectionPromises.push(runner?.disconnect?.());\n }\n }\n\n await Promise.allSettled(disconnectionPromises);\n }\n\n /**\n * Returns the name of a registered runner given its ID.\n *\n * @param runnerId - The unique ID of the runner.\n * @returns The name of the runner associated with the given ID.\n *\n * @throws xJetError - If no runner with the specified ID exists.\n *\n * @remarks\n * The `runnerId` corresponds to the internally generated ID assigned\n * to each runner when it was connected via `initTarget`.\n *\n * @example\n * ```ts\n * const runnerName = externalService.getRunnerName('runner-123');\n * console.log(runnerName); // e.g., \"chrome\"\n * ```\n *\n * @since 1.0.0\n */\n\n getRunnerName(runnerId: string): string {\n const name = this.runners.get(runnerId)?.name;\n if (!name) {\n throw new xJetError(`Runner with ID \"${ runnerId }\" not found`);\n }\n\n return name;\n }\n\n /**\n * Returns a list of all registered runners with their IDs and names.\n *\n * @returns An array of objects each containing:\n * - `id`: The unique runner ID.\n * - `name`: The runner's name.\n *\n * @remarks\n * This method provides a simplified view of all connected runners without exposing\n * the full `TestRunnerInterface` details. It is useful for reporting or UI purposes.\n *\n * @example\n * ```ts\n * const runners = externalService.getRunners();\n * runners.forEach(runner => {\n * console.log(`Runner ID: ${runner.id}, Name: ${runner.name}`);\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n getRunners(): Array<RunnerInterface> {\n return Array.from(this.runners.values()).map(runner => ({\n id: runner.id!,\n name: runner.name\n }));\n }\n\n /**\n * Executes the provided transpiled test suites on all registered runners.\n *\n * @param transpileSuites - An array of transpiled test files to execute.\n * @param suites - A record mapping original suite names to their file paths.\n *\n * @remarks\n * This method registers the provided suites internally via `setSuites` and\n * queues each transpiled suite for execution on every connected runner.\n *\n * Each suite is executed asynchronously, and errors are handled internally\n * without halting the execution of other suites.\n *\n * The `queue` ensures that execution tasks are managed per runner, preventing\n * race conditions and allowing controlled concurrency.\n *\n * After all tasks are queued, the queue is started and the method waits\n * for all execution tasks to settle using `Promise.allSettled`.\n *\n * @example\n * ```ts\n * await externalService.executeSuites(transpileFiles, originalFiles);\n * ```\n *\n * @see {@link setSuites} to register suites for execution.\n * @see {@link executeTestWithErrorHandling} for individual test execution logic.\n *\n * @since 1.0.0\n */\n\n async executeSuites(transpileSuites: TranspileFileType, suites: Record<string, string>): Promise<void> {\n this.setSuites(suites);\n const testExecutionTasks: Array<Promise<void>> = [];\n\n for (const transpile of transpileSuites) {\n const relativePath = relative(this.framework.rootPath, transpile.path)\n .replace(/\\.[^/.]+$/, '');\n\n this.runners.forEach((runner: TestRunnerInterface, id: string) => {\n testExecutionTasks.push(this.queue.enqueue(async () => {\n return this.executeTestWithErrorHandling(transpile.code, relativePath, runner);\n }, id));\n });\n }\n\n this.queue.start();\n await Promise.allSettled(testExecutionTasks);\n }\n\n /**\n * Connects a single test runner and registers it in the internal map.\n *\n * @param runner - The test runner configuration to connect.\n * @param argv - Optional CLI arguments to pass to the runner during connection.\n *\n * @remarks\n * A unique ID is generated for the runner and assigned to `runner.id`.\n * The runner's `connection` method is called with a dispatch function, its ID,\n * and any provided arguments. The connection attempt is wrapped in a timeout\n * using `withTimeout` (defaulting to 5000 ms if `runner.connectionTimeout` is not set).\n *\n * If the connection succeeds, the runner is added to the `runners` map. If it fails,\n * the error is caught and logged as a `VMRuntimeError` without throwing,\n * allowing other runners to continue connecting.\n *\n * @example\n * ```ts\n * await this.connectRunner(runnerConfig, { verbose: true });\n * ```\n *\n * @since 1.0.0\n */\n\n private async connectRunner(runner: TestRunnerInterface, argv: Record<string, unknown>): Promise<void> {\n runner.id = this.generateId();\n await withTimeout(\n runner.connect(this.dispatch.bind(this), runner.id!, argv),\n runner?.connectionTimeout ?? 5000,\n `connection of runner \"${ runner.name }\"`\n );\n\n this.runners.set(runner.id, runner);\n }\n\n /**\n * Executes a single test suite on a runner with error handling.\n *\n * @param testCode - The transpiled test code to execute.\n * @param relativePath - The relative path of the test file, used to look up the suite ID.\n * @param runner - The test runner instance that will execute the suite.\n *\n * @returns A `Promise` that resolves when the suite has been executed or fails gracefully.\n *\n * @remarks\n * This method wraps the execution of a test suite in a `Promise` and tracks\n * it in the `runningSuites` map using the suite ID. If `executeInRunner`\n * throws an error, the suite is marked as complete with failure, and an\n * 'error' event is emitted via the `eventEmitter`.\n *\n * The emitted error includes:\n * - `kind`: The packet type (`PacketKind.Error`)\n * - `error`: The serialized error object\n * - `suiteId`: The unique ID of the suite\n * - `runnerId`: The ID of the runner that executed the suite\n *\n * @example\n * ```ts\n * await this.executeTestWithErrorHandling(testCode, \"tests/login.spec.ts\", runner);\n * ```\n *\n * @since 1.0.0\n */\n\n private executeTestWithErrorHandling(testCode: string, relativePath: string, runner: TestRunnerInterface): Promise<void> {\n const suiteId = this.suites.get(relativePath)!;\n\n return new Promise<void>(async (resolve, reject) => {\n try {\n this.runningSuites.set(runner.id + suiteId, { resolve, reject });\n await this.executeInRunner(testCode, suiteId, runner);\n } catch (error) {\n this.completeSuite(runner.id + suiteId, true);\n this.eventEmitter.emit('error', {\n kind: PacketKind.Error,\n error: JSON.stringify(serializeError(error)),\n suiteId: suiteId,\n runnerId: runner.id,\n timestamp: new Date()\n }, this.suites.get(suiteId)!);\n }\n });\n }\n\n /**\n * Dispatches a test suite to a runner with an injected runtime context.\n *\n * @param testCode - The transpiled test code to execute.\n * @param suiteId - The unique ID of the suite.\n * @param runner - The test runner instance that will execute the suite.\n *\n * @throws Throws a timeout error if the runner's dispatch does not complete in time.\n *\n * @remarks\n * This method prepares the test code by injecting runtime context (bail, path, filter,\n * timeout, suiteId, runnerId, randomization) using `prepareTestCodeWithContext`.\n * The prepared code is then dispatched to the runner via its `dispatch` method,\n * wrapped in a timeout using `withTimeout` (defaulting to 5000 ms if `runner.dispatchTimeout` is not set).\n *\n * The `suiteId` is used both for looking up the original file path in `suites` and for\n * identifying the suite during dispatch.\n *\n * @example\n * ```ts\n * await this.executeInRunner(testCode, suiteId, runner);\n * ```\n *\n * @since 1.0.0\n */\n\n private async executeInRunner(testCode: string, suiteId: string, runner: TestRunnerInterface): Promise<void> {\n const runtimeContext: Record<string, RuntimeConfigInterface> = {\n runtime: {\n bail: this.config.bail,\n path: this.suites.get(suiteId)!,\n filter: this.config.filter,\n timeout: this.config.timeout,\n suiteId: suiteId,\n runnerId: runner.id!,\n randomize: this.config.randomize\n }\n };\n\n const preparedTestCode = this.prepareTestCodeWithContext(testCode, runtimeContext);\n await withTimeout(\n runner?.dispatch?.(Buffer.from(preparedTestCode), suiteId, this.suites.get(suiteId)!),\n runner?.dispatchTimeout ?? 5000,\n `dispatch of runner \"${ runner.name }\"`\n );\n }\n\n /**\n * Injects a runtime context into the test code.\n *\n * @param testCode - The original transpiled test code.\n * @param context - The runtime context to inject, including configuration and suite/runner metadata.\n *\n * @returns A string containing the test code with the injected `__XJET` context variable.\n *\n * @remarks\n * This method prepends the test code with a `const __XJET` declaration containing\n * the provided context. The runner can access this context during execution to\n * determine runtime options like `bail`, `timeout`, `suiteId`, `runnerId`, etc.\n *\n * The resulting code is suitable for direct dispatch to a test runner environment.\n *\n * @example\n * ```ts\n * const preparedCode = this.prepareTestCodeWithContext(testCode, {\n * runtime: { suiteId, runnerId, bail: true }\n * });\n * ```\n *\n * @since 1.0.0\n */\n\n private prepareTestCodeWithContext(testCode: string, context: Record<string, RuntimeConfigInterface>): string {\n const __filename = context.runtime.path;\n const __dirname = dirname(__filename);\n\n return `globalThis.import_meta = { url: \"${ pathToFileURL(__filename) }\", dirname: \"${ __dirname }\", filename: \"${ __filename }\" };` +\n `globalThis.__dirname=${ JSON.stringify(__dirname) };` +\n `globalThis.__filename=${ JSON.stringify(__filename) };` +\n `globalThis.__XJET = ${ JSON.stringify(context) }; ${ testCode }`;\n }\n}\n", "export class TimeoutError extends Error {\n constructor(timeout: number, at: string, stack: string = '') {\n super(`Exceeded timeout of ${ timeout } ms at ${ at }`);\n\n // Ensure a correct prototype chain (important for `instanceof`)\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'xJetTimeoutError';\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n\n this.name = 'xJetFailingError';\n if(stack) {\n this.stack = `${ this.name }: ${ this.message }\\n${ stack }`;\n }\n }\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { FunctionLikeType } from '@remotex-labs/xjet-expect';\nimport type { TimerInterface } from '@shared/services/interfaces/timer-service.interface';\n\n/**\n * Imports\n */\n\nimport { Injectable, inject } from '@symlinks/services/inject.service';\n\n/**\n * Provides a virtual timer system that mimics native `setTimeout`/`setInterval`\n * while allowing controlled execution for deterministic tests.\n *\n * @remarks\n * This service replaces the global timing functions with fake timers so that\n * time can be manually advanced and callbacks triggered predictably.\n * It is intended for unit testing scenarios where you need full control over\n * asynchronous timing without waiting in real time.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 1000);\n * advanceTimersByTime(1000); // logs 'done' immediately\n * useRealTimers();\n * ```\n *\n * @since 1.1.0\n */\n\n@Injectable({\n scope: 'singleton'\n})\nexport class TimerService {\n /**\n * Active timers managed by the fake timer engine.\n * @since 1.1.0\n */\n\n readonly timers = new Map<number, TimerInterface>();\n\n /**\n * Stores original `Date.now` to restore when real timers are re-enabled.\n * @since 1.1.0\n */\n\n readonly originalDateNow = Date.now;\n\n /**\n * Stores original global `setTimeout`.\n * @since 1.1.0\n */\n\n readonly originalSetTimeout = globalThis.setTimeout;\n\n /**\n * Stores original global `setInterval`.\n * @since 1.1.0\n */\n\n readonly originalSetInterval = globalThis.setInterval;\n\n /**\n * Stores original global `clearTimeout`.\n * @since 1.1.0\n */\n\n readonly originalClearTimeout = globalThis.clearTimeout;\n\n /**\n * Stores original global `clearInterval`.\n * @since 1.1.0\n */\n\n readonly originalClearInterval = globalThis.clearInterval;\n\n /**\n * Simulated current timestamp for the fake timers.\n * @since 1.1.0\n */\n\n private now = 0;\n\n /**\n * Incremental id used to register timers uniquely.\n * @since 1.1.0\n */\n\n private nextId = 1;\n\n /**\n * Replaces the global timer functions with in-memory fakes.\n *\n * @remarks\n * After calling this method, any calls to `setTimeout`, `setInterval`,\n * `clearTimeout`, or `clearInterval` will be intercepted and stored in the\n * {@link timers} map instead of scheduling real OS timers.\n * This allows tests to control time progression manually using\n * {@link advanceTimersByTime}, {@link runAllTimers}, or\n * {@link runOnlyPendingTimers}.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * const id = setTimeout(() => console.log('done'), 1000);\n * timerService.advanceTimersByTime(1000); // logs \"done\" immediately\n * ```\n *\n * @since 1.1.0\n */\n\n useFakeTimers(): void {\n const setTimeout = (cb: FunctionLikeType<void>, delay: number = 0, ...args: Array<unknown>): number => {\n const id = this.nextId++;\n this.timers.set(id, { id, callback: cb, time: this.now + delay, interval: null, args: args ?? [] });\n\n return id;\n };\n\n const setInterval = (cb: FunctionLikeType<void>, interval: number = 0): number => {\n const id = this.nextId++;\n this.timers.set(id, { id, callback: cb, time: this.now + interval, interval, args: [] });\n\n return id;\n };\n\n const clearTimeout = (id: number): void => {\n this.timers.delete(id);\n };\n\n\n const clearInterval = (id: number): void => {\n this.timers.delete(id);\n };\n\n const global = <Record<string, unknown>> globalThis;\n global.setTimeout = setTimeout;\n global.setInterval = setInterval;\n global.clearTimeout = clearTimeout;\n global.clearInterval = clearInterval;\n }\n\n /**\n * Restores the original global timer APIs and `Date.now`.\n *\n * @remarks\n * This method undoes the effects of {@link useFakeTimers}, re-binding\n * the native implementations of `setTimeout`, `setInterval`,\n * `clearTimeout`, `clearInterval`, and `Date.now`.\n * After calling this, timers once again behave according to real system\n * time and manual advancement methods such as\n * {@link advanceTimersByTime} no longer apply.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * // ...run tests with controlled time...\n * timerService.useRealTimers(); // restore native timers\n * ```\n *\n * @since 1.1.0\n */\n\n useRealTimers(): void {\n this.timers.clear();\n globalThis.setTimeout = this.originalSetTimeout;\n globalThis.clearTimeout = this.originalClearTimeout;\n globalThis.setInterval = this.originalSetInterval;\n globalThis.clearInterval = this.originalClearInterval;\n Date.now = this.originalDateNow;\n }\n\n /**\n * Clears all active fake timers.\n *\n * @remarks\n * This method removes every timer currently stored in {@link timers},\n * effectively resetting the fake timer state without advancing time.\n * It is useful for cleaning up between tests to ensure no lingering\n * scheduled callbacks remain.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * clearAllTimers(); // removes all scheduled timers\n * advanceTimersByTime(100); // nothing happens\n * ```\n *\n * @since 1.3.0\n */\n\n clearAllTimers(): void {\n this.timers.clear();\n }\n\n /**\n * Advances the simulated clock by a specific number of milliseconds and\n * executes all timers whose scheduled time has elapsed.\n *\n * @remarks\n * Use this method after calling {@link useFakeTimers} to fast-forward the\n * internal clock without waiting in real time.\n * Any `setTimeout` or `setInterval` callbacks scheduled within the\n * advanced period will run immediately in order of their scheduled time.\n *\n * @param ms - The number of milliseconds to move the simulated time forward.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => console.log('done'), 500);\n * timerService.advanceTimersByTime(500); // logs \"done\"\n * ```\n *\n * @since 1.1.0\n */\n\n advanceTimersByTime(ms: number) : void {\n this.now += ms;\n this.runDueTimers();\n }\n\n /**\n * Executes every scheduled timer until none remain.\n *\n * @remarks\n * This method repeatedly advances the simulated clock to the next\n * scheduled timer and runs its callback until the {@link timers} map\n * is empty.\n * It is useful when you want to immediately flush **all** pending\n * `setTimeout` or `setInterval` callbacks regardless of their delay,\n * without specifying a time increment.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n * timerService.runAllTimers(); // logs \"A\" then \"B\"\n * ```\n *\n * @since 1.1.0\n */\n\n runAllTimers(): void {\n while (this.timers.size > 0) {\n this.now = Math.min(...Array.from(this.timers.values()).map(t => t.time));\n this.runDueTimers();\n }\n }\n\n /**\n * Executes only the timers that are currently pending at the time of call,\n * without running any new timers that may be scheduled by those callbacks.\n *\n * @remarks\n * Unlike {@link runAllTimers}, this method captures the set of timers\n * that exist when the method is invoked and restricts execution to that\n * initial set.\n * If any of those timers schedule additional timers while running,\n * the newly scheduled ones will **not** be executed during this call.\n *\n * @example\n * ```ts\n * timerService.useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n *\n * timerService.runOnlyPendingTimers();\n * // Logs only \"first\" because \"second\" was created afterward.\n * ```\n *\n * @since 1.1.0\n */\n\n runOnlyPendingTimers(): void {\n const pendingTimers = new Set(this.timers.keys());\n\n while (pendingTimers.size > 0) {\n const nextTimerTimes = Array.from(this.timers.values())\n .filter(t => pendingTimers.has(t.id))\n .map(t => t.time);\n\n if (nextTimerTimes.length === 0) break;\n\n this.now = Math.min(...nextTimerTimes);\n this.runDueTimers(pendingTimers);\n\n for (const id of pendingTimers) {\n if (!this.timers.has(id)) pendingTimers.delete(id);\n }\n }\n }\n\n /**\n * Asynchronous equivalent of {@link runAllTimers}.\n *\n * @remarks\n * This method first yields to the event loop to allow any pending promises\n * to resolve before executing all remaining fake timers.\n * It ensures a deterministic sequence when timers and microtasks coexist.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * Promise.resolve().then(() => console.log('microtask'));\n * setTimeout(() => console.log('timer'), 0);\n * await timerService.runAllTimersAsync();\n * // Logs:\n * // microtask\n * // timer\n * ```\n *\n * @since 1.3.0\n */\n\n async runAllTimersAsync(): Promise<void> {\n await Promise.resolve();\n this.runAllTimers();\n }\n\n /**\n * Asynchronous equivalent of {@link runOnlyPendingTimers}.\n *\n * @remarks\n * This method first yields to the event loop to allow any pending promises\n * to resolve before executing only currently pending fake timers.\n * Timers scheduled during execution will not run until explicitly advanced later.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n * await timerService.runOnlyPendingTimersAsync();\n * // Logs:\n * // first\n * ```\n *\n * @since 1.3.0\n */\n\n async runOnlyPendingTimersAsync(): Promise<void> {\n await Promise.resolve();\n this.runOnlyPendingTimers();\n }\n\n /**\n * Executes all timers whose scheduled time is less than or equal to the\n * current simulated time (`this.now`).\n *\n * @remarks\n * This internal method is called by {@link advanceTimersByTime},\n * {@link runAllTimers}, and {@link runOnlyPendingTimers} to trigger\n * due timers.\n * If `limitTimers` are provided, only timers included in that set are executed.\n * Repeating timers (`setInterval`) are rescheduled automatically until\n * their next execution time exceeds the current simulated time.\n *\n * @param limitTimers - Optional set of timer IDs to restrict execution.\n *\n * @internal\n * @since 1.1.0\n */\n\n private runDueTimers(limitTimers?: Set<number>): void {\n let executed = true;\n while (executed) {\n executed = false;\n\n const timers = Array.from(this.timers.values()).sort((a, b) => a.time - b.time);\n\n for (const timer of timers) {\n if (!this.timers.has(timer.id)) continue;\n if (limitTimers && !limitTimers.has(timer.id)) continue;\n\n if (timer.time <= this.now) {\n if (timer.interval !== null) {\n while (timer.time <= this.now) {\n timer.callback();\n timer.time += timer.interval;\n }\n } else {\n timer.callback();\n this.timers.delete(timer.id);\n }\n executed = true;\n }\n }\n }\n }\n}\n\n/**\n * Globally enables fake timers using the shared {@link TimerService}.\n *\n * @remarks\n * After calling this function, all calls to `setTimeout`, `setInterval`,\n * `clearTimeout`, and `clearInterval` will be intercepted by the\n * {@link TimerService} and stored in-memory instead of executing in real time.\n * This allows deterministic testing by manually advancing time with\n * {@link advanceTimersByTime}, {@link runAllTimers}, or\n * {@link runOnlyPendingTimers}.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 1000);\n * advanceTimersByTime(1000); // logs \"done\" immediately\n * ```\n *\n * @since 1.1.0\n */\n\nexport function useFakeTimers(): void {\n inject(TimerService).useFakeTimers();\n}\n\n/**\n * Restores real timers globally using the shared {@link TimerService}.\n *\n * @remarks\n * This function undoes the effects of {@link useFakeTimers}, restoring the\n * native implementations of `setTimeout`, `setInterval`, `clearTimeout`,\n * `clearInterval`, and `Date.now`.\n * After calling this, timers once again behave according to real system time,\n * and manual advancement methods like {@link advanceTimersByTime} no longer apply.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * // ...run tests with controlled time...\n * useRealTimers(); // restore native timers\n * ```\n *\n * @since 1.1.0\n */\n\nexport function useRealTimers(): void {\n inject(TimerService).useRealTimers();\n}\n\n/**\n * Executes all timers currently registered in the {@link TimerService}.\n *\n * @remarks\n * This function repeatedly runs all pending `setTimeout` and `setInterval`\n * callbacks until no timers remain.\n * It is equivalent to calling {@link TimerService.runAllTimers} on the\n * injected service instance and is useful for immediately flushing\n * all scheduled timers in tests.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n * runAllTimers(); // logs \"A\" then \"B\"\n * ```\n *\n * @since 1.1.0\n */\n\nexport function runAllTimers(): void {\n inject(TimerService).runAllTimers();\n}\n\n/**\n * Removes all scheduled fake timers from the {@link TimerService}.\n *\n * @remarks\n * This function clears all active timers registered in the shared timer service,\n * effectively canceling any pending callbacks that would have run during\n * timer advancement.\n *\n * It's useful for resetting the fake timer state between test cases to ensure\n * no lingering timers affect further tests or for scenarios where you\n * need to abort all pending operations.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('A'), 100);\n * setTimeout(() => console.log('B'), 200);\n *\n * clearAllTimers(); // removes all scheduled timers\n * advanceTimersByTime(1000); // nothing happens, not show any logs\n * ```\n *\n * @since 1.3.0\n */\n\nexport function clearAllTimers(): void {\n inject(TimerService).clearAllTimers();\n}\n\n/**\n * Executes only the timers that are pending at the time of invocation.\n *\n * @remarks\n * This function runs the callbacks of timers that exist when the function\n * is called, without executing any new timers that may be scheduled\n * during their execution.\n * It delegates to {@link TimerService.runOnlyPendingTimers} on the injected\n * service instance.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n *\n * runOnlyPendingTimers();\n * // Logs only \"first\"; \"second\" is not executed yet\n * ```\n *\n * @since 1.1.0\n */\n\nexport function runOnlyPendingTimers(): void {\n inject(TimerService).runOnlyPendingTimers();\n}\n\n/**\n * Advances the simulated time by a specified number of milliseconds and\n * executes all timers that are due.\n *\n * @remarks\n * This function delegates to {@link TimerService.advanceTimersByTime}\n * on the injected service instance.\n * It is intended to be used after {@link useFakeTimers} to fast-forward\n * time in tests without waiting for real timers.\n *\n * @param ms - The number of milliseconds to advance (default is `0`).\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => console.log('done'), 500);\n * advanceTimersByTime(500); // logs \"done\"\n * ```\n *\n * @since 1.1.0\n */\n\nexport function advanceTimersByTime(ms: number = 0): void {\n inject(TimerService).advanceTimersByTime(ms);\n}\n\n/**\n * Asynchronous equivalent of {@link runAllTimers}.\n *\n * @remarks\n * Yields to the event loop before running all pending fake timers.\n * Useful when working with both Promises and fake timers.\n *\n * @example\n * ```ts\n * xJet.useFakeTimers();\n * Promise.resolve().then(() => console.log('promise done'));\n * setTimeout(() => console.log('timeout done'), 0);\n * await xJet.runAllTimersAsync();\n * // Logs:\n * // promise done\n * // timeout done\n * ```\n *\n * @since 1.3.0\n */\n\nexport async function runAllTimersAsync(): Promise<void> {\n await inject(TimerService).runAllTimersAsync();\n}\n\n/**\n * Asynchronous equivalent of {@link runOnlyPendingTimers}.\n *\n * @remarks\n * Yields to the event loop before running only timers that are currently pending.\n * Any timers scheduled by those callbacks will not be executed until a later call.\n *\n * @example\n * ```ts\n * useFakeTimers();\n * setTimeout(() => {\n * console.log('first');\n * setTimeout(() => console.log('second'), 100);\n * }, 100);\n * await runOnlyPendingTimersAsync();\n * // Logs only \"first\"\n * ```\n *\n * @since 1.3.0\n */\n\nexport async function runOnlyPendingTimersAsync(): Promise<void> {\n await inject(TimerService).runOnlyPendingTimersAsync();\n}\n", "/**\n * Import will remove at compile time\n */\n\nimport type { FunctionLikeType } from '@remotex-labs/xjet-expect';\n\n/**\n * Imports\n */\n\nimport { TimeoutError } from '@errors/timeout.error';\nimport { inject } from '@symlinks/services/inject.service';\nimport { TimerService } from '@shared/services/timer.service';\n\n\n/**\n * Executes a given asynchronous or synchronous task with an optional timeout constraint.\n *\n * @typeParam T - The resolved value type.\n *\n * @param task - Either a function that returns a value or promise, or a promise itself.\n * @param delay - Timeout in milliseconds, or `-1` to disable the timeout.\n * @param at - A contextual label (e.g., method name or operation name) to aid debugging.\n * @param stack - Optional stack trace to provide more detailed error context.\n *\n * @throws {@link TimeoutError} If the task does not complete within the specified `delay`\n * (only when `delay` is not `-1`).\n *\n * @remarks\n * The function accepts either:\n * - a function returning a value or a promise, or\n * - a promise directly.\n *\n * If `delay` is `-1`, no timeout is applied. Otherwise the task is raced against\n * a timer and a {@link TimeoutError} is thrown on expiry.\n *\n * @example\n * ```ts\n * // Passing a function\n * await withTimeout(\n * () => fetchData(),\n * 5000,\n * 'fetchData'\n * );\n *\n * // Passing a promise directly\n * await withTimeout(\n * fetchData(),\n * 5000,\n * 'fetchDataDirect'\n * );\n *\n * // No timeout\n * await withTimeout(fetchData(), -1, 'fetchDataNoTimeout');\n * ```\n *\n * @since 1.1.0\n */\n\nexport async function withTimeout<T>(\n task: FunctionLikeType<T | Promise<T>> | Promise<T> | T, delay: number, at: string, stack?: string\n): Promise<T> {\n const timers = inject(TimerService);\n\n const taskPromise =\n typeof task === 'function'\n ? Promise.resolve((task as FunctionLikeType<T | Promise<T>>)())\n : Promise.resolve(task);\n\n if (delay === -1 || !timers.originalSetTimeout) {\n return taskPromise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = timers.originalSetTimeout?.(\n () => reject(new TimeoutError(delay, at, stack)),\n delay\n );\n });\n\n try {\n return await Promise.race([ taskPromise, timeoutPromise ]);\n } finally {\n timers.originalClearTimeout?.(timeoutId!);\n }\n}\n\n", "#!/usr/bin/env node\n\n/**\n * Imports\n */\n\nimport '@errors/uncaught.error';\nimport { parseArguments } from '@providers/cli.provider';\nimport { SuitesService } from '@services/suites.service';\nimport { bannerComponent } from '@components/banner.component';\nimport { configuration } from '@providers/configuration.provider';\n\n/**\n * Main entry point for the xJet library.\n *\n * @since 1.0.0\n */\n\nasync function main(argv: Array<string>): Promise<void> {\n const cli = await parseArguments(argv);\n if (cli.verbose) globalThis.VERBOSE = true;\n\n const config = await configuration(cli.config, cli);\n if (config.verbose) globalThis.VERBOSE = true;\n\n if (![ 'json', 'junit' ].includes(config.reporter)) {\n console.log(bannerComponent());\n } else {\n globalThis.NO_COLOR = true;\n }\n\n const suites = new SuitesService(config);\n await suites.executeSuites();\n}\n\n/**\n * Run entrypoint of xJet cli\n */\n\nmain(process.argv);\n"],
6
+ "mappings": "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",
7
7
  "names": ["dirname", "join", "relative", "SINGLETONS", "INJECTABLES", "Injectable", "options", "target", "__name", "inject", "token", "args", "metadata", "instance", "xterm", "dirname", "normalize", "readFileSync", "SourceService", "_FrameworkService_decorators", "_init", "Injectable", "FrameworkService", "__name", "position", "source", "sourceRoot", "lowerCaseSource", "path", "normalize", "key", "error", "map", "sourceMapData", "readFileSync", "dirname", "sourceMap", "SourceService", "__decoratorStart", "__decorateElement", "__runInitializers", "Bias", "highlightCode", "parseErrorStack", "formatErrorCode", "MULTIPLE_SPACES", "URL_PATTERN", "FILE_PROTOCOL", "formatStackFrame", "frame", "relative", "position", "xterm", "__name", "getSourceLocation", "source", "sourceRoot", "line", "lastIndex", "lastHttpsIndex", "path", "dirname", "join", "highlightPositionCode", "formatErrorCode", "highlightCode", "formatFrameWithPosition", "stackEntry", "options", "Bias", "parseStackTrace", "error", "context", "inject", "FrameworkService", "parseErrorStack", "formatStack", "metadata", "parts", "stackMetadata", "xJetBaseError", "__name", "message", "name", "json", "key", "value", "error", "options", "formatStack", "formatErrors", "reason", "err", "xJetBaseError", "formatStack", "__name", "yargs", "resolve", "hideBin", "xterm", "asciiLogo", "bannerComponent", "xterm", "__name", "existsSync", "version", "defaultConfiguration", "dirname", "createRequire", "Script", "createContext", "sandboxExecute", "code", "sandbox", "options", "script", "Script", "context", "createContext", "__name", "VMRuntimeError", "_VMRuntimeError", "xJetBaseError", "originalError", "options", "error", "__name", "errorList", "cwd", "build", "xJetError", "xJetBaseError", "__name", "message", "options", "xterm", "formatCode", "highlightCode", "esBuildError", "xJetBaseError", "__name", "error", "errors", "xterm", "formatCode", "highlightCode", "defaultBuildOptions", "cwd", "buildFiles", "filePaths", "buildOptions", "build", "esbuildErrors", "esBuildError", "__name", "transpileFiles", "result", "transpiled", "outputFiles", "framework", "inject", "FrameworkService", "file", "basePath", "isSourceMap", "isJsFile", "transpileFile", "filePath", "xJetError", "parseConfigurationFile", "file", "transpileOptions", "dirname", "module", "code", "path", "transpileFile", "require", "createRequire", "sandboxExecute", "error", "VMRuntimeError", "__name", "configuration", "configFile", "cli", "config", "defaultConfiguration", "existsSync", "userConfig", "parseConfigurationFile", "__name", "DEFAULT_CONFIG_PATH", "DEFAULT_CLI_OPTIONS", "__name", "value", "resolve", "USAGE_EXAMPLES", "getUserArgv", "argv", "yargs", "configuration", "parseArguments", "userOptions", "parser", "hideBin", "originalShowHelp", "consoleFunction", "bannerComponent", "cli", "command", "description", "join", "exit", "accessSync", "readFile", "watch", "dirname", "join", "normalize", "join", "relative", "existsSync", "readdirSync", "getRelativePath", "path", "relative", "inject", "FrameworkService", "__name", "collectFilesFromDir", "dir", "patterns", "excludes", "suites", "specFiles", "existsSync", "entries", "readdirSync", "entry", "fullPath", "join", "relativePath", "matchesAny", "relativeFilePath", "key", "getSpecFiles", "config", "suitesRegex", "compilePatterns", "patternsRegex", "excludesRegex", "QUESTION_MARK", "BRACE_PATTERN", "DOUBLE_ASTERISK", "SINGLE_ASTERISK", "CHARACTER_CLASS", "REGEX_SPECIAL_CHARS", "compileGlobPattern", "globPattern", "escapeRegexChars", "__name", "pattern", "convertGlobToRegex", "_", "chars", "choices", "isGlob", "str", "globCharacters", "hasBraces", "hasExtglob", "matchesAny", "path", "patterns", "regex", "compilePatterns", "escapedPattern", "getRelativePath", "relative", "readFileSync", "pathToFileURL", "createRequire", "typescriptAlias", "updateAliases", "tsconfigPath", "raw", "readFileSync", "paths", "key", "value", "__name", "resolveImport", "importPath", "framework", "inject", "FrameworkService", "pattern", "target", "resolved", "relative", "path", "createRequire", "pathToFileURL", "WatchService", "_WatchService", "config", "testsFile", "exec", "updateAliases", "compilePatterns", "__name", "inject", "FrameworkService", "testFile", "changedFilesSet", "watcher", "watch", "filename", "fullPath", "normalize", "matchesAny", "fn", "delay", "file", "accessSync", "dependents", "changedFiles", "suites", "key", "suite", "target", "force", "content", "readFile", "dependencies", "match", "importPath", "path", "resolveImport", "join", "dirname", "testFiles", "dep", "depSet", "originalSize", "test", "nestedDeps", "changedFile", "deps", "xterm", "existsSync", "createRequire", "LogLevel", "dirname", "mkdirSync", "writeFileSync", "AbstractReporter", "logLevel", "outFilePath", "__name", "JsonReporter", "AbstractReporter", "__name", "suites", "runners", "suiteName", "runner", "event", "key", "name", "suite", "describeJson", "parent", "describe", "testJson", "result", "folderPath", "dirname", "mkdirSync", "writeFileSync", "ancestry", "currentDescribes", "d", "dirname", "mkdirSync", "writeFileSync", "JunitReporter", "JsonReporter", "__name", "runnerName", "suitesByName", "suite", "xmlContent", "folderPath", "dirname", "mkdirSync", "writeFileSync", "rootDescribe", "tests", "failures", "skipped", "duration", "suiteAttrs", "describe", "test", "nested", "name", "baseAttributes", "reason", "errors", "e", "sum", "t", "str", "ANSI", "writeRaw", "xterm", "ShadowRenderer", "xterm", "STATIC_HEIGHT", "formatStatus", "statePrefix", "ConsoleReporter", "AbstractReporter", "__name", "logLevel", "outFilePath", "height", "width", "ShadowRenderer", "STATIC_HEIGHT", "suites", "runners", "writeRaw", "ANSI", "suiteName", "runner", "key", "title", "log", "suite", "lines", "xterm", "line", "event", "suiteStats", "prefix", "err", "testLine", "formatStatus", "error", "data", "counter", "suitesParts", "testsParts", "elapsedSeconds", "row", "detail", "status", "runnerPrefix", "statePrefix", "statusPrefix", "transpile", "reporterPath", "transpileFile", "__name", "parseExternalReporter", "code", "path", "module", "require", "createRequire", "context", "sandboxExecute", "error", "VMRuntimeError", "getReporter", "config", "reporter", "outputFile", "builtInReporters", "JsonReporter", "JunitReporter", "ConsoleReporter", "existsSync", "Reporter", "LogLevel", "CustomReporter", "xJetError", "MessageService", "target", "reporter", "__name", "inject", "FrameworkService", "log", "suitePath", "source", "message", "LogLevel", "suiteError", "status", "baseMessage", "assertionMessage", "events", "error", "options", "errorObject", "err", "stackMetadata", "e", "metadata", "process", "pathToFileURL", "createRequire", "dirname", "relative", "resolve", "serializeError", "EventEmitter", "serializeError", "Struct", "invocationSchema", "headerSchema", "logSchema", "errorSchema", "statusSchema", "eventsSchema", "PacketSchemas", "logSchema", "errorSchema", "statusSchema", "eventsSchema", "decodePacket", "buffer", "offset", "headerSchema", "header", "dynamicOffset", "type", "schema", "PacketSchemas", "dataBuffer", "data", "__name", "_QueueService_decorators", "_init", "Injectable", "QueueService", "__name", "concurrencyLimit", "count", "taskItem", "task", "runnerId", "resolve", "reject", "wrappedTask", "result", "error", "initialCount", "item", "__decoratorStart", "__decorateElement", "__runInitializers", "AbstractTarget", "config", "QueueService", "__name", "EventEmitter", "inject", "FrameworkService", "key", "listener", "suiteId", "hasError", "suiteContext", "buffer", "data", "decodePacket", "suitePath", "xJetError", "errorMessage", "suites", "suiteName", "path", "id", "_LocalService_decorators", "_init", "_a", "Injectable", "LocalService", "AbstractTarget", "__name", "transpileSuites", "suites", "testExecutionTasks", "transpile", "relativePath", "relative", "testCode", "transpileFilePath", "suiteId", "path", "module", "require", "createRequire", "safeProcess", "process", "sandboxContext", "dirname", "pathToFileURL", "resolve", "sandboxExecute", "filePath", "reject", "error", "serializeError", "__decoratorStart", "__decorateElement", "__runInitializers", "yargs", "pathToFileURL", "dirname", "relative", "serializeError", "TimeoutError", "__name", "timeout", "at", "stack", "_TimerService_decorators", "_init", "Injectable", "TimerService", "__name", "setTimeout", "cb", "delay", "args", "id", "setInterval", "interval", "clearTimeout", "clearInterval", "global", "ms", "t", "pendingTimers", "nextTimerTimes", "limitTimers", "executed", "timers", "a", "b", "timer", "__decoratorStart", "__decorateElement", "__runInitializers", "withTimeout", "task", "delay", "at", "stack", "timers", "inject", "TimerService", "taskPromise", "timeoutId", "timeoutPromise", "_", "reject", "TimeoutError", "__name", "_ExternalService_decorators", "_init", "_a", "Injectable", "ExternalService", "AbstractTarget", "__name", "xJetError", "argv", "yargs", "runner", "disconnectionPromises", "runners", "i", "runnerId", "name", "transpileSuites", "suites", "testExecutionTasks", "transpile", "relativePath", "relative", "id", "withTimeout", "testCode", "suiteId", "resolve", "reject", "error", "serializeError", "runtimeContext", "preparedTestCode", "context", "__filename", "__dirname", "dirname", "pathToFileURL", "__decoratorStart", "__decorateElement", "__runInitializers", "banner", "footer", "SuitesService", "config", "__name", "inject", "FrameworkService", "specsFiles", "getSpecFiles", "xterm", "message", "MessageService", "getReporter", "exit", "transpiled", "ExternalService", "LocalService", "WatchService", "filePaths", "transpileFiles", "join", "main", "argv", "cli", "parseArguments", "config", "configuration", "bannerComponent", "SuitesService", "__name"]
8
8
  }