@hyperfrontend/project-scope/core

Core Module

The core module provides foundational utilities for file system operations, path manipulation, logging, caching, error handling, and pattern matching. These utilities are used throughout the library and are also available for consumers.

Capabilities

File System (fs/)

Safe, typed file system operations with comprehensive error handling.

import {
  readFileContent,
  readJsonFile,
  writeFileContent,
  writeJsonFile,
  readDirectory,
  readDirectoryRecursive,
  exists,
  isFile,
  isDirectory,
  ensureDir,
} from '@hyperfrontend/project-scope'

// Read files
const content = readFileContent('./package.json')
const config = readJsonFile<Config>('./config.json', { default: {} })

// Write files (creates directories automatically)
writeFileContent('./output/data.txt', 'Hello, World!')
writeJsonFile('./output/config.json', { port: 3000 })

// Directory operations
const entries = readDirectory('./src')
const allFiles = readDirectoryRecursive('./src', { maxDepth: 5 })

// Stat operations
if (exists('./config.json') && isFile('./config.json')) {
  // Process file
}

Key Functions

FunctionDescription
readFileContentRead file as string with encoding support
readFileBufferRead file as Buffer
readFileIfExistsRead file or return null
readJsonFileParse JSON file with type inference
readJsonFileIfExistsParse JSON file or return null
writeFileContentWrite string to file
writeFileBufferWrite Buffer to file
writeJsonFileSerialize and write JSON
ensureDirCreate directory recursively
readDirectoryList directory contents
readDirectoryRecursiveList contents recursively
existsCheck if path exists
isFileCheck if path is a file
isDirectoryCheck if path is a directory
isSymlinkCheck if path is a symlink
getFileStatGet detailed file statistics

Path Utilities (path/)

Cross-platform path manipulation utilities.

import {
  normalizePath,
  joinPath,
  resolvePath,
  relativePath,
  isAbsolute,
  getDirname,
  getBasename,
  getExtension,
} from '@hyperfrontend/project-scope'

const normalized = normalizePath('./src/../lib/index.ts') // 'lib/index.ts'
const joined = joinPath('src', 'utils', 'helper.ts') // 'src/utils/helper.ts'

Encoding (encoding/)

Utilities for detecting and converting file encodings.

import { detectEncoding, convertEncoding } from '@hyperfrontend/project-scope'

const encoding = detectEncoding(buffer)
const utf8Content = convertEncoding(buffer, 'utf-8')

Platform Detection (platform/)

Detect operating system and normalize platform-specific behaviors.

import { detectPlatform, isWindows, isMacOS, isLinux, normalizeLineEndings } from '@hyperfrontend/project-scope'

const platform = detectPlatform() // 'windows' | 'macos' | 'linux'
const normalizedContent = normalizeLineEndings(content, 'lf')

Logger (logger.ts)

Scoped logging with automatic secret sanitization.

import { createScopedLogger, setGlobalLogLevel } from '@hyperfrontend/project-scope'

// Create a scoped logger
const logger = createScopedLogger('my-module')

// Log messages with optional metadata
logger.info('Starting process', { path: './project' })
logger.debug('Config loaded', { apiKey: 'secret123' }) // apiKey is auto-redacted

// Set global log level
setGlobalLogLevel('debug') // 'error' | 'warn' | 'log' | 'info' | 'debug'

Cache (cache.ts)

In-memory cache with TTL and size limits.

import { createCache, clearAllCaches } from '@hyperfrontend/project-scope'

// Create cache with TTL
const cache = createCache<string, Object>({ ttl: 60000 }) // 60 second TTL

// Create cache with size limit
const lruCache = createCache<string, Object>({ maxSize: 100 })

// Combined options
const configCache = createCache<string, Config>({ ttl: 30000, maxSize: 50 })

cache.set('key', { data: 'value' })
const value = cache.get('key')

// Clear all registered caches
clearAllCaches()

Structured Errors (errors/)

Create errors with machine-readable codes and context.

import {
  createStructuredError,
  createConfigError,
  createFsError,
  createParseError,
  createValidationError,
} from '@hyperfrontend/project-scope'

throw createStructuredError('Config not found', 'CONFIG_NOT_FOUND', {
  path: './config.json',
  searched: ['./config.json', './settings.json'],
})

// Specialized error factories
throw createFsError('File not found', 'ENOENT', { path: './missing.txt' })
throw createParseError('Invalid JSON', 'PARSE_ERROR', { line: 10, column: 5 })

Glob Pattern Matching (patterns/)

Safe glob matching without regex (ReDoS-protected).

import { matchGlobPattern } from '@hyperfrontend/project-scope'

matchGlobPattern('src/utils/helper.ts', '**/*.ts') // true
matchGlobPattern('test.spec.ts', '*.spec.ts') // true
matchGlobPattern('config.json', '*.{json,yaml}') // true
matchGlobPattern('src/index.ts', 'src/*.ts') // true

Supported Patterns

PatternDescription
*Match any characters except /
**Match any characters including /
?Match exactly one character
{a,b,c}Match any alternative

Design Principles

  1. Safe by default: All operations handle errors gracefully with typed error objects
  2. No side effects: Functions are pure where possible
  3. ReDoS protection: Glob matching uses character iteration instead of regex
  4. Secret sanitization: Logging automatically redacts sensitive values
  5. Cross-platform: Path operations normalize across Windows/Unix

API Reference§

ƒ Functions

§function

addBom(content: string): string

Add UTF-8 BOM to string if not present.
Parameters
NameTypeDescription
§content
stringString to add BOM to
Returns
string
String with BOM
Example

Adding UTF-8 BOM to content

const content = 'Hello World'
const withBom = addBom(content)
// => '\ufeffHello World'
§function

bufferToString(content: Buffer, encoding?: BufferEncoding): string

Convert buffer to string with encoding detection.
Parameters
NameTypeDescription
§content
BufferBuffer to convert
§encoding?
BufferEncodingOptional encoding override (auto-detected if not provided)
Returns
string
Converted string
Example

Converting file buffer to string with auto-detection

const fileBuffer = readFileSync('./config.json')
const content = bufferToString(fileBuffer)
// => '{"key": "value"}'
§function

clearAllCaches(): void

Clear all registered caches.
Useful for testing or when a global state reset is needed. This clears all caches created via createCache().
Example

Clearing caches in tests

// In tests
afterEach(() => {
  clearAllCaches()
})
§function

createCache<K, V>(options?: CacheOptions): Cache<K, V>

Create a cache with optional TTL and size limits.
The cache provides a simple key-value store with:
  • Optional TTL (time-to-live) for automatic expiration
  • Optional maxSize for limiting cache size with FIFO eviction
  • Lazy expiration (entries are checked on access)
Parameters
NameTypeDescription
§options?
CacheOptionsCache configuration options
Returns
Cache<K, V>
Cache instance
Example

Creating caches with different options

// Basic cache
const cache = createCache<string, number>()
cache.set('answer', 42)
cache.get('answer') // 42

// Cache with TTL (expires after 60 seconds)
const ttlCache = createCache<string, object>({ ttl: 60000 })

// Cache with max size (evicts oldest when full)
const lruCache = createCache<string, object>({ maxSize: 100 })

// Combined options
const configCache = createCache<string, object>({
  ttl: 30000,
  maxSize: 50
})
§function

createConfigError(message: string, code: string, context?: Record<string, unknown>): StructuredError

Create a configuration-related error.
Parameters
NameTypeDescription
§message
stringThe human-readable error message
§code
stringThe machine-readable error code for programmatic handling
§context?
Record<string, unknown>Additional contextual information (e.g., file path, config key)
Returns
StructuredError
Structured error instance tagged with type 'config'
Example

Creating a configuration error

throw createConfigError(
  'Invalid port number',
  'CONFIG_INVALID_PORT',
  { configFile: './app.config.json', value: -1 }
)
§function

createDirectory(dirPath: string, options?: CreateDirectoryOptions): void

Create a directory, optionally creating parent directories.
Parameters
NameTypeDescription
§dirPath
stringPath where the directory should be created
§options?
CreateDirectoryOptionsCreation options
Example

Creating directories

// Create nested directories
createDirectory('./output/reports/2024')

// Create single directory without parents
createDirectory('./logs', { recursive: false })
§function

createFileSystemError(message: string, code: FileSystemErrorCode, context: FileSystemErrorContext): Error

Create a file system error with code and context.
Parameters
NameTypeDescription
§message
stringThe error message describing what went wrong
§code
FileSystemErrorCodeThe category code for this type of filesystem failure
§context
FileSystemErrorContextAdditional context including path, operation, and cause
Returns
Error
A configured Error object with code and context properties
Example

Creating a file system error

throw createFileSystemError(
  'Cannot read file',
  'FS_READ_ERROR',
  { path: './missing.txt', operation: 'read' }
)
§function

createFsError(message: string, code: string, context?: Record<string, unknown>): StructuredError

Create a filesystem-related error.
Parameters
NameTypeDescription
§message
stringThe human-readable error message
§code
stringThe filesystem error code (e.g., ENOENT for not found, EACCES for access denied)
§context?
Record<string, unknown>Additional contextual information (e.g., file path, operation attempted)
Returns
StructuredError
Structured error instance tagged with type 'fs'
Example

Creating a filesystem error

throw createFsError(
  'Configuration file not found',
  'ENOENT',
  { path: './missing.json', operation: 'read' }
)
§function

createParseError(message: string, code: string, context?: Record<string, unknown>): StructuredError

Create a parsing-related error.
Parameters
NameTypeDescription
§message
stringThe human-readable error message
§code
stringThe machine-readable error code for programmatic handling
§context?
Record<string, unknown>Additional contextual information (e.g., file path, line/column numbers, expected format)
Returns
StructuredError
Structured error instance tagged with type 'parse'
Example

Creating a parse error

throw createParseError(
  'Invalid JSON syntax',
  'JSON_PARSE_ERROR',
  { file: './config.json', line: 42, column: 15 }
)
§function

createScopedLogger(namespace: string, options: ScopedLoggerOptions): ScopedLogger

Creates a scoped logger with namespace prefix and optional secret sanitization. All log messages will be prefixed with [namespace] and sensitive metadata values will be automatically redacted.
Parameters
NameTypeDescription
§namespace
stringLogger namespace (e.g., 'project-scope', 'analyze')
§options
ScopedLoggerOptionsLogger configuration options(default: {})
Returns
ScopedLogger
A configured scoped logger instance
Example

Creating a scoped logger

const logger = createScopedLogger('project-scope')
logger.setLogLevel('debug')

// Basic logging
logger.info('Starting analysis', { path: './project' })

// Sensitive data is automatically redacted
logger.debug('Config loaded', { apiKey: 'secret123' })
// Output: [project-scope] Config loaded {"apiKey":"[REDACTED]"}
§function

createStructuredError(message: string, code: string, context?: Record<string, unknown>): StructuredError

Create a structured error with code and optional context.
Parameters
NameTypeDescription
§message
stringThe human-readable error message
§code
stringThe machine-readable error code for programmatic handling
§context?
Record<string, unknown>Additional contextual information about the error
Returns
StructuredError
Structured error instance with code and context properties
Example

Creating a structured error with context

import { createStructuredError } from '@hyperfrontend/project-scope'

throw createStructuredError(
  'Configuration file not found',
  'CONFIG_NOT_FOUND',
  { path: './config.json', searched: ['./config.json', './settings.json'] }
)
§function

createValidationError(message: string, code: string, context?: Record<string, unknown>): StructuredError

Create a validation-related error.
Parameters
NameTypeDescription
§message
stringThe human-readable error message
§code
stringThe machine-readable error code for programmatic handling
§context?
Record<string, unknown>Additional contextual information (e.g., field name, actual vs expected values)
Returns
StructuredError
Structured error instance tagged with type 'validation'
Example

Creating a validation error

throw createValidationError(
  'Email format is invalid',
  'INVALID_EMAIL',
  { field: 'email', value: 'not-an-email' }
)
§function

detectCaseSensitivity(): boolean

Detect if file system is case sensitive.
Returns
boolean
True if file system is case-sensitive
Example

Detecting case sensitivity

if (detectCaseSensitivity()) {
  // Linux: 'File.ts' and 'file.ts' are different files
} else {
  // Windows/macOS: treat as same file
}
§function

detectEncoding(buffer: Buffer): BufferEncoding

Detect file encoding from BOM or content analysis.
Parameters
NameTypeDescription
§buffer
BufferBuffer to analyze
Returns
BufferEncoding
Detected encoding, defaults to 'utf-8'
Example

Detecting encoding from buffer

const buffer = readFileSync('./data.txt')
const encoding = detectEncoding(buffer)
const content = buffer.toString(encoding)
§function

detectEncodingInfo(buffer: Buffer): EncodingInfo

Detect if content is likely text or binary with encoding information.
Parameters
NameTypeDescription
§buffer
BufferBuffer to analyze
Returns
EncodingInfo
Encoding information
Example

Detecting encoding and BOM info

const buffer = readFileSync('./document.txt')
const info = detectEncodingInfo(buffer)
if (info.type === 'text') {
  console.log(`Encoding: ${info.encoding}, BOM: ${info.hasBom}`)
}
§function

detectLineEnding(content: string): DetectedLineEnding

Detect line ending style used in content.
Parameters
NameTypeDescription
§content
stringContent to analyze
Returns
DetectedLineEnding
Detected line ending style
Example

Detecting line ending style

const ending = detectLineEnding('line1\nline2\n')
// => 'lf'

const mixed = detectLineEnding('line1\r\nline2\nline3')
// => 'mixed'
§function

detectPlatform(): PlatformInfo

Detect current platform.
Returns
PlatformInfo
Platform information object
Example

Detecting current platform

const platform = detectPlatform()
if (platform.isWindows) {
  // Windows-specific handling
}
§function

ensureDir(dirPath: string): void

Ensure directory exists, create recursively if not.
Parameters
NameTypeDescription
§dirPath
stringDirectory path to ensure exists
Example

Ensuring directory exists

ensureDir('./output/reports')
// Directory now exists (created if missing)
§function

ensureTrailingSlash(filePath: string): string

Append a forward slash to the path if not already present.
Parameters
NameTypeDescription
§filePath
stringPath to process
Returns
string
Path with trailing forward slash
Example

Ensuring trailing slash

ensureTrailingSlash('src/components')
// => 'src/components/'

ensureTrailingSlash('already/has/')
// => 'already/has/'
§function

exists(filePath: string): boolean

Check if path exists.
Parameters
NameTypeDescription
§filePath
stringPath to check
Returns
boolean
True if path exists
Example

Checking if path exists

if (exists('./config.json')) {
  const config = readJsonFile('./config.json')
}
§function

findUpwardWhere(startPath: string, test: (dirPath: string) => boolean): string

Find directory where predicate returns true, starting from given path.
Parameters
NameTypeDescription
§startPath
stringStarting directory
§test
(dirPath: string) => booleanFunction to test if directory matches criteria
Returns
string
Matching directory path or null
Example

Finding directory with specific config

// Find directory with a specific config
const configDir = findUpwardWhere('./deep/nested/path', (dir) =>
  existsSync(join(dir, '.eslintrc.js'))
)
§function

getBasename(filePath: string, ext?: string): string

Get basename of path.
Parameters
NameTypeDescription
§filePath
stringPath to extract basename from
§ext?
stringOptional extension to strip
Returns
string
Basename of path
Example

Getting basename

getBasename('src/components/Button.tsx')
// => 'Button.tsx'

getBasename('src/components/Button.tsx', '.tsx')
// => 'Button'
§function

getCacheCount(): number

Get the number of registered caches.
Primarily used for testing.
Returns
number
Number of registered caches
Example

Getting the number of active caches

const count = getCacheCount()
// => 3 (number of active caches)
§function

getDirname(filePath: string): string

Get directory name of path.
Parameters
NameTypeDescription
§filePath
stringPath to extract directory from
Returns
string
Directory name
Example

Getting directory name

getDirname('src/components/Button.tsx')
// => 'src/components'
§function

getExtension(filePath: string): string

Get file extension (including dot).
Parameters
NameTypeDescription
§filePath
stringPath to extract extension from
Returns
string
Extension including dot (e.g., '.ts')
Example

Getting file extension

getExtension('src/utils/helpers.ts')
// => '.ts'

getExtension('package.json')
// => '.json'
§function

getFileNameWithoutExtension(filePath: string): string

Get filename without extension.
Parameters
NameTypeDescription
§filePath
stringPath to extract name from
Returns
string
Filename without extension
Example

Getting filename without extension

getFileNameWithoutExtension('src/utils/helpers.ts')
// => 'helpers'
§function

getFileStat(filePath: string, followSymlinks: boolean): FileStats

Get file stats with error handling.
Parameters
NameTypeDescription
§filePath
stringPath to file
Returns
FileStats
File stats or null if path doesn't exist
Example

Getting file statistics

const stats = getFileStat('./package.json')
if (stats) {
  console.log(`Size: ${stats.size} bytes`)
  console.log(`Modified: ${stats.modified}`)
}
§function

getGlobalLogLevel(): LogLevel

Get the current global log level.
Returns
LogLevel
The global log level, or null if not set
Example

Getting current log level

setGlobalLogLevel('debug')
const level = getGlobalLogLevel()
// => 'debug'
§function

getLineEnding(): " " | " "

Get platform-appropriate line ending.
Returns
" " | " "
Line ending for current platform
Example

Getting platform line ending

const eol = getLineEnding()
const lines = ['line1', 'line2', 'line3']
const content = lines.join(eol)
§function

getPathSeparator(): "\" | "/"

Get platform-appropriate path separator.
Returns
"\" | "/"
Path separator for current platform
Example

Getting platform path separator

const sep = getPathSeparator()
const fullPath = ['src', 'utils', 'helpers.ts'].join(sep)
§function

getPlatformInfo(): PlatformInfo

Get comprehensive platform information.
Returns
PlatformInfo
Platform information object (cached after first call)
Example

Getting platform information

const info = getPlatformInfo()
console.log(info.os)           // => 'linux'
console.log(info.pathSeparator) // => '/'
console.log(info.lineEnding)    // => '\n'
§function

hasBom(buffer: Buffer): boolean

Check if buffer starts with a BOM.
Parameters
NameTypeDescription
§buffer
BufferBuffer to check
Returns
boolean
True if buffer has a BOM
Example

Checking if buffer has BOM

const buffer = readFileSync('./file.txt')
if (hasBom(buffer)) {
  // Strip BOM before processing
}
§function

isAbsolute(filePath: string): boolean

Check if path is absolute.
Parameters
NameTypeDescription
§filePath
stringPath to check
Returns
boolean
True if path is absolute
Example

Checking absolute path

isAbsolute('/workspace/src/index.ts')
// => true

isAbsolute('./src/index.ts')
// => false
§function

isCaseSensitiveFs(): boolean

Check if file system is case-sensitive.
Returns
boolean
True if file system is case-sensitive
Example

Checking case sensitivity

const caseSensitive = isCaseSensitiveFs()
// => true on Linux, false on Windows/macOS
§function

isDirectory(dirPath: string): boolean

Check if path is a directory.
Parameters
NameTypeDescription
§dirPath
stringPath to check
Returns
boolean
True if path is a directory
Example

Checking if path is a directory

if (isDirectory('./src')) {
  // Path exists and is a directory
}
§function

isFile(filePath: string): boolean

Check if path is a file.
Parameters
NameTypeDescription
§filePath
stringPath to check
Returns
boolean
True if path is a file
Example

Checking if path is a file

if (isFile('./package.json')) {
  // Path exists and is a regular file
}
§function

isTextFile(buffer: Buffer): boolean

Check if buffer represents text content.
Parameters
NameTypeDescription
§buffer
BufferBuffer to check
Returns
boolean
True if the buffer appears to be text
Example

Checking if content is text

const buffer = readFileSync('./unknown-file')
if (isTextFile(buffer)) {
  const content = buffer.toString('utf-8')
}
§function

isWindows(): boolean

Check if running on Windows.
Returns
boolean
True if running on Windows
Example

Checking for Windows

if (isWindows()) {
  // Use Windows-specific paths or commands
}
§function

join(...paths: string[]): string

Join path segments. Uses platform-specific separators (e.g., / or \).
Parameters
NameTypeDescription
§...paths
string[]Path segments to join
Returns
string
Joined path
Example

Joining path segments

const fullPath = join('src', 'components', 'Button.tsx')
// => 'src/components/Button.tsx' (or 'src\\components\\Button.tsx' on Windows)
§function

joinPath(...segments: string[]): string

Join path segments.
Parameters
NameTypeDescription
§...segments
string[]Path segments to join
Returns
string
Joined path with normalized separators
Example

Joining path segments

joinPath('src', 'components', 'Button.tsx')
// => 'src/components/Button.tsx'
§function

joinPosix(...paths: string[]): string

Join path segments using POSIX separators (/). Always uses forward slashes regardless of platform.
Parameters
NameTypeDescription
§...paths
string[]Path segments to join
Returns
string
Joined path with forward slashes
Example

Joining paths with forward slashes

const configPath = joinPosix('config', 'settings', 'app.json')
// => 'config/settings/app.json'
§function

locateByMarkers(startPath: string, markers: unknown): string

Find directory containing any of the specified marker files.
Parameters
NameTypeDescription
§startPath
stringStarting directory
§markers
unknownArray of marker file names to search for
Returns
string
First directory containing any marker, or null
Example

Finding project root by marker files

// Find project root by looking for common marker files
const projectRoot = locateByMarkers('./src/components', [
  'package.json',
  'nx.json',
  'tsconfig.base.json'
])
// => '/workspace/my-project'
§function

matchesAnyPattern(path: string, patterns: unknown): boolean

Test if path matches any of the patterns.
Parameters
NameTypeDescription
§path
stringPath to test
§patterns
unknownArray of glob patterns
Returns
boolean
True if path matches any pattern
Example

Checking path against multiple patterns

const ignorePatterns = ['*.log', 'node_modules/**', '*.tmp']
const shouldIgnore = matchesAnyPattern('debug.log', ignorePatterns)
// => true
§function

matchesExact(path: string, pattern: string): boolean

Test if path exactly matches the pattern (no glob).
Parameters
NameTypeDescription
§path
stringPath to test
§pattern
stringExact pattern to match
Returns
boolean
True if path equals pattern
Example

Exact path matching

matchesExact('package.json', 'package.json')
// => true

matchesExact('src/package.json', 'package.json')
// => false
§function

matchGlobPattern(path: string, pattern: string): boolean

Match path against glob pattern using safe character iteration. Avoids regex to prevent ReDoS attacks.
Supported patterns:
  • matches any characters except /
  • * matches any characters including /
  • ? matches exactly one character except /
  • {a,b,c} matches any of the alternatives
Parameters
NameTypeDescription
§path
stringThe filesystem path to test against the pattern
§pattern
stringThe glob pattern to match against
Returns
boolean
True if path matches pattern
Example

Matching paths against glob patterns

import { matchGlobPattern } from '@hyperfrontend/project-scope'

matchGlobPattern('src/utils/helper.ts', '\*\*/*.ts')     // true
matchGlobPattern('test.spec.ts', '\*.spec.ts')          // true
matchGlobPattern('config.json', '\*.{json,yaml}')       // true
matchGlobPattern('src/index.ts', 'src/\*.ts')           // true
§function

memoize<K, V>(fn: (key: K) => V, options?: CacheOptions): MemoizedFunction<K, V>

Create a memoized version of a function with caching.
The memoized function caches results based on the first argument (key). If additional arguments are needed, use the options.keyFn parameter.
Parameters
NameTypeDescription
§fn
(key: K) => VFunction to memoize
§options?
CacheOptionsCache options for the underlying cache
Returns
MemoizedFunction<K, V>
Memoized function with cache control methods
Example

Memoizing an expensive function

// Memoize a detection function
const detectTechStackMemo = memoize(
  (path: string) => expensiveDetection(path),
  { ttl: 60000 }
)

const result1 = detectTechStackMemo('/path/to/project')
const result2 = detectTechStackMemo('/path/to/project') // Returns cached

// Clear the cache
detectTechStackMemo.cache.clear()
§function

normalizeLineEndings(content: string, style: LineEndingStyle): string

Normalize line endings in content.
Parameters
NameTypeDescription
§content
stringContent to normalize
§style
LineEndingStyleTarget line ending style ('lf', 'crlf', or 'auto' for platform default)(default: 'lf')
Returns
string
Content with normalized line endings
Example

Normalizing line endings

// Normalize to Unix line endings
const normalized = normalizeLineEndings('line1\r\nline2\r\n', 'lf')
// => 'line1\nline2\n'

// Use platform default
const platformNormalized = normalizeLineEndings(content, 'auto')
§function

normalizePath(filePath: string): string

Normalize path separators to forward slashes.
Parameters
NameTypeDescription
§filePath
stringPath to normalize
Returns
string
Normalized path with forward slashes
Example

Normalizing path separators

const path = normalizePath('src\\components\\Button.tsx')
// => 'src/components/Button.tsx'
§function

normalizeToForwardSlashes(filePath: string): string

Convert path separators to forward slashes using POSIX style. Resolves . and .. segments for cross-platform configuration.
Parameters
NameTypeDescription
§filePath
stringThe input path to convert
Returns
string
Path with forward slashes and resolved segments
Example

Converting to forward slashes

const path = normalizeToForwardSlashes('./src/../lib/utils')
// => 'lib/utils'
§function

normalizeToNative(filePath: string): string

Convert path to use the operating system's native separator.
Parameters
NameTypeDescription
§filePath
stringThe input path to convert
Returns
string
Path with native separators (backslash on Windows, forward slash elsewhere)
Example

Converting to native separators

const path = normalizeToNative('src/components/Button.tsx')
// => 'src\\components\\Button.tsx' on Windows
// => 'src/components/Button.tsx' on Unix
§function

offsetFromRoot(filePath: string): string

Calculate offset from root (e.g., "../../../").
Parameters
NameTypeDescription
§filePath
stringPath to calculate offset for
Returns
string
Relative offset path (e.g., "../../")
Example

Calculating offset from root

offsetFromRoot('libs/utils/src')
// => '../../../'

offsetFromRoot('apps')
// => '../'
§function

parsePath(filePath: string): ParsedPath

Parse path into components.
Parameters
NameTypeDescription
§filePath
stringPath to parse
Returns
ParsedPath
Parsed path components
Example

Parsing path components

const parsed = parsePath('/workspace/src/index.ts')
// => { root: '/', dir: '/workspace/src', base: 'index.ts', ext: '.ts', name: 'index' }
§function

pathSegments(filePath: string): string[]

Split path into segments.
Parameters
NameTypeDescription
§filePath
stringPath to split
Returns
string[]
Array of path segments
Example

Splitting path into segments

pathSegments('src/components/Button.tsx')
// => ['src', 'components', 'Button.tsx']
§function

pathsEqual(path1: string, path2: string): boolean

Compare paths with case sensitivity awareness.
Parameters
NameTypeDescription
§path1
stringFirst path
§path2
stringSecond path
Returns
boolean
True if paths are equal (respecting case sensitivity)
Example

Comparing paths

// On case-insensitive filesystem (Windows/macOS)
pathsEqual('src/App.tsx', 'src/app.tsx')
// => true

// On case-sensitive filesystem (Linux)
pathsEqual('src/App.tsx', 'src/app.tsx')
// => false
§function

readDirectory(dirPath: string): DirectoryEntry[]

List immediate contents of a directory.
Parameters
NameTypeDescription
§dirPath
stringAbsolute or relative path to the directory
Returns
DirectoryEntry[]
Array of entries with metadata for each file/directory
Example

Listing directory contents

import { readDirectory } from '@hyperfrontend/project-scope'

const entries = readDirectory('./src')
for (const entry of entries) {
  console.log(entry.name, entry.isFile ? 'file' : 'directory')
}
§function

readDirectoryRecursive(dirPath: string, options?: RecursiveOptions): DirectoryEntry[]

List directory contents recursively with depth tracking.
Parameters
NameTypeDescription
§dirPath
stringRoot directory path to start traversal
§options?
RecursiveOptionsConfiguration for depth limit, hidden files, and symlinks
Returns
DirectoryEntry[]
Flat array of all entries found during traversal
Example

Recursive directory listing with options

import { readDirectoryRecursive } from '@hyperfrontend/project-scope'

// List all files up to 3 levels deep
const entries = readDirectoryRecursive('./src', { maxDepth: 3 })

// Include hidden files
const allEntries = readDirectoryRecursive('./project', { includeHidden: true })
§function

readFileBuffer(filePath: string): Buffer

Read file contents as Buffer.
Parameters
NameTypeDescription
§filePath
stringPath to file
Returns
Buffer
File contents as Buffer
Example

Reading file as buffer

const buffer = readFileBuffer('./image.png')
console.log(buffer.length) // File size in bytes
§function

readFileContent(filePath: string, encoding: BufferEncoding): string

Read file contents as string.
Parameters
NameTypeDescription
§filePath
stringPath to file
§encoding
BufferEncodingFile encoding (default: utf-8)(default: 'utf-8')
Returns
string
File contents as string
Example

Reading file contents

import { readFileContent } from '@hyperfrontend/project-scope'

const content = readFileContent('./package.json')
console.log(content) // JSON string
§function

readFileIfExists(filePath: string, encoding: BufferEncoding): string

Read file if exists, return null otherwise.
Parameters
NameTypeDescription
§filePath
stringPath to file
§encoding
BufferEncodingFile encoding (default: utf-8)(default: 'utf-8')
Returns
string
File contents or null if file doesn't exist
Example

Reading file if it exists

const content = readFileIfExists('./optional-config.json')
if (content) {
  // File existed, use content
}
§function

readJsonFile<T>(filePath: string, options?: ReadJsonFileOptions<T>): T

Read and parse JSON file.
Parameters
NameTypeDescription
§filePath
stringPath to JSON file
§options?
ReadJsonFileOptions<T>Parse options
Returns
T
Parsed JSON object
Example

Reading JSON file

import { readJsonFile } from '@hyperfrontend/project-scope'

// Read with type inference
interface Config { port: number }
const config = readJsonFile<Config>('./config.json')

// Read with default fallback
const settings = readJsonFile('./settings.json', { default: {} })
§function

readJsonFileIfExists<T>(filePath: string): T

Read and parse JSON file if exists, return null otherwise.
Parameters
NameTypeDescription
§filePath
stringPath to JSON file
Returns
T
Parsed JSON object or null if file doesn't exist or is invalid
Example

Reading JSON file if it exists

interface UserSettings { theme: string }
const settings = readJsonFileIfExists<UserSettings>('./user-settings.json')
const theme = settings?.theme ?? 'default'
§function

relativePath(from: string, to: string): string

Compute the normalized path from source directory to target.
Parameters
NameTypeDescription
§from
stringSource path (base directory)
§to
stringTarget path to reach
Returns
string
Relative path from source to target with forward slashes
Example

Computing relative path

relativePath('/workspace/src/utils', '/workspace/lib/helpers')
// => '../../lib/helpers'
§function

removeDirectory(dirPath: string, options?: RemoveDirectoryOptions): void

Delete a directory from the filesystem.
Parameters
NameTypeDescription
§dirPath
stringPath to the directory to remove
§options?
RemoveDirectoryOptionsRemoval configuration
Example

Removing directories

// Remove directory and all contents
removeDirectory('./temp', { recursive: true })

// Safe removal (no error if missing)
removeDirectory('./cache', { recursive: true, force: true })
§function

removeTrailingSlash(filePath: string): string

Strip any trailing forward or back slashes from a path.
Parameters
NameTypeDescription
§filePath
stringPath that may have trailing slashes
Returns
string
Path with trailing slashes removed
Example

Removing trailing slashes

removeTrailingSlash('src/components/')
// => 'src/components'

removeTrailingSlash('path\\to\\dir\\')
// => 'path\\to\\dir'
§function

resetGlobalLogLevel(): void

Reset the global log level override. Each logger will retain its current level but new loggers will use their default.
Example

Resetting the global log level

setGlobalLogLevel('debug')
// ... perform debugging ...
resetGlobalLogLevel()
// Global override removed, loggers use individual levels
§function

resolveFromWorkspace(workspaceRoot: string, ...segments: string[]): string

Resolve path relative to workspace root.
Parameters
NameTypeDescription
§workspaceRoot
stringWorkspace root directory
§...segments
string[]Path segments relative to workspace
Returns
string
Resolved absolute path with normalized separators
Example

Resolving from workspace root

const configPath = resolveFromWorkspace('/workspace', 'config', 'app.json')
// => '/workspace/config/app.json'
§function

resolvePath(...segments: string[]): string

Resolve path segments to an absolute path.
Parameters
NameTypeDescription
§...segments
string[]Path segments to resolve
Returns
string
Resolved absolute path with normalized separators
Example

Resolving to absolute path

const absPath = resolvePath('src', 'components', 'Button.tsx')
// => '/workspace/project/src/components/Button.tsx'
§function

resolveRealPath(filePath: string): string

Resolve symlinks to real path.
Parameters
NameTypeDescription
§filePath
stringPath to resolve
Returns
string
Real path or null if path doesn't exist
Example

Resolving symlinks

const realPath = resolveRealPath('./node_modules/.bin/tsc')
// => '/workspace/node_modules/typescript/bin/tsc'
§function

sanitize(obj: unknown): unknown

Sanitizes an object by replacing sensitive values with REDACTED. This function recursively processes nested objects and arrays.
Parameters
NameTypeDescription
§obj
unknownObject to sanitize
Returns
unknown
New object with sensitive values redacted
Example

Sanitizing sensitive data

const config = { apiKey: 'secret123', endpoint: 'https://api.example.com' }
const safe = sanitize(config)
// => { apiKey: '[REDACTED]', endpoint: 'https://api.example.com' }
§function

setGlobalLogLevel(level: LogLevel): void

Set the log level for all registered scoped loggers. This is useful for enabling verbose logging across the entire library.
Parameters
NameTypeDescription
§level
LogLevelThe log level to set globally
Example

Enabling debug logging globally

import { setGlobalLogLevel } from '@hyperfrontend/project-scope/core'

// Enable debug logging for all project-scope modules
setGlobalLogLevel('debug')
§function

stripBom(content: string): string

Strip BOM from start of string if present.
Parameters
NameTypeDescription
§content
stringString that may have BOM
Returns
string
String without BOM
Example

Stripping BOM from a string

const withBom = '\ufeffHello World'
const clean = stripBom(withBom)
// => 'Hello World'
§function

toUtf8(content: string | Buffer<ArrayBufferLike>, sourceEncoding: BufferEncoding): string

Convert content to UTF-8 string.
Parameters
NameTypeDescription
§content
string | Buffer<ArrayBufferLike>Buffer or string content
§sourceEncoding
BufferEncodingSource encoding (auto-detected if not provided)(default: 'utf-8')
Returns
string
UTF-8 string
Example

Converting a buffer to UTF-8 string

const buffer = Buffer.from('Hello', 'utf-8')
const text = toUtf8(buffer)
// => 'Hello'
§function

traverseUpward(startPath: string, predicate: (dirPath: string) => boolean): string

Generic upward directory traversal. Name avoids similarity to fs.readdir/fs.readdirSync.
Parameters
NameTypeDescription
§startPath
stringStarting directory
§predicate
(dirPath: string) => booleanFunction to test each directory
Returns
string
First matching directory or null
Example

Finding directory containing README

// Find first directory containing a README
const readmeDir = traverseUpward('./src/utils', (dir) =>
  existsSync(join(dir, 'README.md'))
)
// => '/project' or null
§function

unregisterCache<K, V>(cache: Cache<K, V>): boolean

Unregister a cache from the global registry.
Useful for cleanup in tests or when a cache is no longer needed.
Parameters
NameTypeDescription
§cache
Cache<K, V>Cache to unregister
Returns
boolean
True if cache was unregistered
Example

Unregistering a cache from the registry

const myCache = createCache<string, number>({ name: 'temp-cache' })
const wasRemoved = unregisterCache(myCache)
// => true
§function

writeFileBuffer(filePath: string, content: Buffer, options?: WriteFileOptions): void

Write Buffer to file. Creates parent directories if needed.
Parameters
NameTypeDescription
§filePath
stringAbsolute or relative path to the target file
§content
BufferBuffer containing binary data to write
§options?
WriteFileOptionsOptional write configuration (mode)
Example

Writing binary buffer to file

const imageBuffer = Buffer.from([0x89, 0x50, 0x4e, 0x47])
writeFileBuffer('./output/image.png', imageBuffer)
§function

writeFileContent(filePath: string, content: string, options?: WriteFileOptions): void

Write string content to file. Creates parent directories if needed.
Parameters
NameTypeDescription
§filePath
stringAbsolute or relative path to the target file
§content
stringString content to write to the file
§options?
WriteFileOptionsOptional write configuration (encoding, mode)
Example

Writing text content to file

import { writeFileContent } from '@hyperfrontend/project-scope'

// Write a simple text file
writeFileContent('./output/data.txt', 'Hello, World!')

// Write with custom encoding
writeFileContent('./output/data.txt', 'Content', { encoding: 'utf-8' })
§function

writeJsonFile<T>(filePath: string, data: T, options?: WriteJsonOptions): void

Write JSON data to file with formatting. Creates parent directories if needed.
Parameters
NameTypeDescription
§filePath
stringAbsolute or relative path to the target JSON file
§data
TObject or value to serialize as JSON
§options?
WriteJsonOptionsOptional write configuration (indent, encoding, mode)
Example

Writing JSON data to file

import { writeJsonFile } from '@hyperfrontend/project-scope'

// Write object to JSON file
writeJsonFile('./config.json', { port: 3000, debug: true })

// Write with custom indentation
writeJsonFile('./config.json', data, { indent: 4 })

◈ Interfaces

§interface

Cache

Cache interface for storing key-value pairs with optional TTL and size limits.
Properties
§interface

CacheOptions

Options for cache creation.
Properties
§maxSize?:numberMaximum number of entries in cache. When exceeded, oldest entries are evicted (FIFO).
§ttl?:numberTime to live in milliseconds. Entries older than this will be considered expired.
§interface

DirectoryEntry

Entry metadata for a directory listing.
Properties
§depth?:numberDirectory depth (for recursive listings)
§isDirectory:booleanIs a directory
§isFile:booleanIs a file
§name:stringEntry basename
§path:stringFull path
§interface

FileStats

File statistics.
Properties
§accessed:DateLast access time
§created:DateCreation time
§isDirectory:booleanIs a directory
§isFile:booleanIs a file
§mode:numberFile mode/permissions
§modified:DateModification time
§size:numberFile size in bytes
§interface

FileSystemErrorContext

File system error with code and context.
Properties
§cause?:unknownOriginal error that caused the failure
§operation:"read" | "write" | "stat" | "readdir"The filesystem operation that failed
§path:stringAbsolute or relative path where the error occurred
§interface

ParsedPath

Parsed path components.
Properties
§base:stringBase name with extension
§dir:stringDirectory name
§ext:stringFile extension including dot
§name:stringFile name without extension
§root:stringRoot of the path (e.g., "/" or "C:\\")
§interface

PlatformInfo

Platform information.
Properties
§arch:stringCPU architecture
§caseSensitive:booleanFile system case sensitivity
§isLinux:booleanIs Linux
§isMac:booleanIs macOS
§isWindows:booleanIs Windows
§lineEnding:" " | " "Line ending for platform
§nodeVersion:stringNode.js version
§os:"darwin" | "linux" | "win32" | "freebsd" | "sunos" | "aix" | "other"Operating system
§pathSeparator:"\" | "/"Path separator for platform
§interface

ReadJsonFileOptions

Options for reading a JSON file.
Properties
§default?:TDefault value to return if the file is not found
§interface

RecursiveOptions

Options for recursive directory listing.
Properties
§includeHidden?:booleanInclude hidden files (dotfiles)
§maxDepth?:numberMaximum depth (-1 or Infinity for unlimited)
§interface

ScopedLogger

A scoped logger instance with namespace prefix and secret sanitization.
Properties
§debug:(message: string, meta?: object) => voidLog at debug level
§error:(message: string, meta?: object) => voidLog at error level
§getLogLevel:() => LogLevelGet the current log level
§info:(message: string, meta?: object) => voidLog at info level
§log:(message: string, meta?: object) => voidLog at log level
§setLogLevel:(level: LogLevel) => voidSet the current log level
§warn:(message: string, meta?: object) => voidLog at warn level
§interface

ScopedLoggerOptions

Options for creating a scoped logger.
Properties
§level?:LogLevelInitial log level. Messages below this level will not be logged.
§sanitizeSecrets?:booleanWhether to sanitize sensitive data in metadata.
§interface

StructuredError

Structured error with code and context.
Properties
§cause?:unknown
§code:stringMachine-readable error code for programmatic handling
§context?:Record<string, unknown>Additional contextual information about the error
§message:string
§name:string
§stack?:string
§interface

WriteFileOptions

Options for write operations.
Properties
§encoding?:BufferEncodingFile encoding
§mode?:numberFile mode/permissions
§interface

WriteJsonOptions

Options for JSON write operations.
Properties
§encoding?:BufferEncodingFile encoding
§indent?:numberIndentation spaces (default: 2)
§mode?:numberFile mode/permissions

◆ Types

§type

DetectedLineEnding

Result of analyzing line endings in content.
type DetectedLineEnding = "lf" | "crlf" | "mixed" | "none"
§type

EncodingInfo

Encoding detection result.
type EncodingInfo = TextEncodingInfo | BinaryEncodingInfo
§type

FileSystemErrorCode

Error codes for file system operations.
type FileSystemErrorCode = "FS_NOT_FOUND" | "FS_READ_ERROR" | "FS_WRITE_ERROR" | "FS_PARSE_ERROR" | "FS_NOT_A_DIRECTORY"
§type

LineEndingStyle

Target specification for normalizing line endings.
type LineEndingStyle = "lf" | "crlf" | "auto"
§type

LogLevel

Valid log level values in order of verbosity
type LogLevel = "none" | "error" | "warn" | "log" | "info" | "debug"

● Variables

§type

BINARY_SIGNATURES

Common binary file signatures.
§type

CRLF

Windows line ending
§type

LF

Unix line ending
§type

logger

Default logger instance for the project-scope library. Use this for general logging within the library.
§type

UTF16_BE_BOM_BYTES

UTF-16 BE BOM bytes
§type

UTF16_LE_BOM_BYTES

UTF-16 LE BOM bytes
§type

UTF8_BOM

UTF-8 BOM string
§type

UTF8_BOM_BYTES

UTF-8 BOM bytes