@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

Function Description
readFileContent Read file as string with encoding support
readFileBuffer Read file as Buffer
readFileIfExists Read file or return null
readJsonFile Parse JSON file with type inference
readJsonFileIfExists Parse JSON file or return null
writeFileContent Write string to file
writeFileBuffer Write Buffer to file
writeJsonFile Serialize and write JSON
ensureDir Create directory recursively
readDirectory List directory contents
readDirectoryRecursive List contents recursively
exists Check if path exists
isFile Check if path is a file
isDirectory Check if path is a directory
isSymlink Check if path is a symlink
getFileStat Get 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

Pattern Description
* 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
string
String 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
Buffer
Buffer to convert
§encoding?
BufferEncoding
Optional 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?
CacheOptions
Cache 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
string
The human-readable error message
§code
string
The 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
string
Path where the directory should be created
§options?
CreateDirectoryOptions
Creation 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
string
The error message describing what went wrong
§code
FileSystemErrorCode
The category code for this type of filesystem failure
§context
FileSystemErrorContext
Additional 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
string
The human-readable error message
§code
string
The 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
string
The human-readable error message
§code
string
The 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
string
Logger namespace (e.g., 'project-scope', 'analyze')
§options
ScopedLoggerOptions
Logger 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
string
The human-readable error message
§code
string
The 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
string
The human-readable error message
§code
string
The 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
Buffer
Buffer 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
Buffer
Buffer 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
string
Content 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
string
Directory 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
string
Path 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
string
Path 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
string
Starting directory
§test
(dirPath: string) => boolean
Function 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
string
Path to extract basename from
§ext?
string
Optional 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
string
Path 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
string
Path 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
string
Path 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
string
Path 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
Buffer
Buffer 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
string
Path 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
string
Path 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
string
Path 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
Buffer
Buffer 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
string
Starting directory
§markers
unknown
Array 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
string
Path to test
§patterns
unknown
Array 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
string
Path to test
§pattern
string
Exact 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
string
The filesystem path to test against the pattern
§pattern
string
The 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) => V
Function to memoize
§options?
CacheOptions
Cache 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
string
Content to normalize
§style
LineEndingStyle
Target 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
string
Path 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
string
The 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
string
The 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
string
Path 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
string
Path 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
string
Path 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
string
First path
§path2
string
Second 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
string
Absolute 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
string
Root directory path to start traversal
§options?
RecursiveOptions
Configuration 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
string
Path 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
string
Path to file
§encoding
BufferEncoding
File 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
string
Path to file
§encoding
BufferEncoding
File 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
string
Path 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
string
Path 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
string
Source path (base directory)
§to
string
Target 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
string
Path to the directory to remove
§options?
RemoveDirectoryOptions
Removal 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
string
Path 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
string
Workspace 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
string
Path 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
unknown
Object 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
LogLevel
The 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
string
String 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
BufferEncoding
Source 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
string
Starting directory
§predicate
(dirPath: string) => boolean
Function 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
string
Absolute or relative path to the target file
§content
Buffer
Buffer containing binary data to write
§options?
WriteFileOptions
Optional 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
string
Absolute or relative path to the target file
§content
string
String content to write to the file
§options?
WriteFileOptions
Optional 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
string
Absolute or relative path to the target JSON file
§data
T
Object or value to serialize as JSON
§options?
WriteJsonOptions
Optional 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?:number
Maximum number of entries in cache. When exceeded, oldest entries are evicted (FIFO).
§ttl?:number
Time to live in milliseconds. Entries older than this will be considered expired.
§interface

DirectoryEntry

Entry metadata for a directory listing.

Properties

§depth?:number
Directory depth (for recursive listings)
§isDirectory:boolean
Is a directory
§isFile:boolean
Is a file
§name:string
Entry basename
§path:string
Full path
§interface

FileStats

File statistics.

Properties

§accessed:Date
Last access time
§created:Date
Creation time
§isDirectory:boolean
Is a directory
§isFile:boolean
Is a file
§mode:number
File mode/permissions
§modified:Date
Modification time
§size:number
File size in bytes
§interface

FileSystemErrorContext

File system error with code and context.

Properties

§cause?:unknown
Original error that caused the failure
§operation:"read" | "write" | "stat" | "readdir"
The filesystem operation that failed
§path:string
Absolute or relative path where the error occurred
§interface

ParsedPath

Parsed path components.

Properties

§base:string
Base name with extension
§dir:string
Directory name
§ext:string
File extension including dot
§name:string
File name without extension
§root:string
Root of the path (e.g., "/" or "C:\\")
§interface

PlatformInfo

Platform information.

Properties

§arch:string
CPU architecture
§caseSensitive:boolean
File system case sensitivity
§isLinux:boolean
Is Linux
§isMac:boolean
Is macOS
§isWindows:boolean
Is Windows
§lineEnding:" " | " "
Line ending for platform
§nodeVersion:string
Node.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?:T
Default value to return if the file is not found
§interface

RecursiveOptions

Options for recursive directory listing.

Properties

§includeHidden?:boolean
Include hidden files (dotfiles)
§maxDepth?:number
Maximum depth (-1 or Infinity for unlimited)
§interface

ScopedLogger

A scoped logger instance with namespace prefix and secret sanitization.

Properties

§debug:(message: string, meta?: object) => void
Log at debug level
§error:(message: string, meta?: object) => void
Log at error level
§getLogLevel:() => LogLevel
Get the current log level
§info:(message: string, meta?: object) => void
Log at info level
§log:(message: string, meta?: object) => void
Log at log level
§setLogLevel:(level: LogLevel) => void
Set the current log level
§warn:(message: string, meta?: object) => void
Log at warn level
§interface

ScopedLoggerOptions

Options for creating a scoped logger.

Properties

§level?:LogLevel
Initial log level. Messages below this level will not be logged.
§sanitizeSecrets?:boolean
Whether to sanitize sensitive data in metadata.
§interface

StructuredError

Structured error with code and context.

Properties

§cause?:unknown
§code:string
Machine-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?:BufferEncoding
File encoding
§mode?:number
File mode/permissions
§interface

WriteJsonOptions

Options for JSON write operations.

Properties

§encoding?:BufferEncoding
File encoding
§indent?:number
Indentation spaces (default: 2)
§mode?:number
File 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