2025-08-26 12:32:21 -07:00
|
|
|
/**
|
|
|
|
|
* Universal Path implementation
|
2025-09-15 14:53:59 -07:00
|
|
|
* Framework-friendly: Trusts that frameworks provide path polyfills
|
|
|
|
|
* Works in all environments: Browser (via framework), Node.js, Serverless
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { isNode } from '../utils/environment.js'
|
|
|
|
|
|
|
|
|
|
let nodePath: any = null
|
|
|
|
|
|
|
|
|
|
// Dynamic import for Node.js path (only in Node.js environment)
|
|
|
|
|
if (isNode()) {
|
|
|
|
|
try {
|
feat: add node: protocol to all Node.js built-in imports for bundler compatibility
- Updated all fs, path, crypto, os, url, util, events, http, https, net, child_process, stream, and zlib imports
- Changed both static imports and dynamic imports to use node: protocol
- This makes Brainy more bundler-friendly by explicitly marking Node.js built-ins
- Prevents bundlers from attempting to polyfill or bundle these modules
- Reduces bundle size for web applications using Brainy
- Improves tree-shaking and dead code elimination
Benefits for external bundlers:
- Clear distinction between Node.js built-ins and external dependencies
- No ambiguity about what needs polyfilling
- Smaller bundles for browser builds
- Better compatibility with modern bundlers (Webpack 5, Vite, Rollup, esbuild)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 14:20:21 -07:00
|
|
|
// Use node: protocol to prevent bundler polyfilling (requires Node 22+)
|
|
|
|
|
nodePath = await import('node:path')
|
2025-08-26 12:32:21 -07:00
|
|
|
} catch {
|
|
|
|
|
// Ignore import errors in non-Node environments
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Universal path operations
|
2025-09-15 14:53:59 -07:00
|
|
|
* Framework-friendly: Assumes path API is available via framework polyfills
|
2025-08-26 12:32:21 -07:00
|
|
|
*/
|
|
|
|
|
export function join(...paths: string[]): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.join(...paths)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function dirname(path: string): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.dirname(path)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function basename(path: string, ext?: string): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.basename(path, ext)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function extname(path: string): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.extname(path)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function resolve(...paths: string[]): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.resolve(...paths)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function relative(from: string, to: string): string {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.relative(from, to)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isAbsolute(path: string): boolean {
|
|
|
|
|
if (nodePath) {
|
|
|
|
|
return nodePath.isAbsolute(path)
|
2025-09-15 14:53:59 -07:00
|
|
|
} else {
|
|
|
|
|
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
2025-08-26 12:32:21 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Path separator (always use forward slash for consistency)
|
|
|
|
|
export const sep = '/'
|
|
|
|
|
export const delimiter = ':'
|
|
|
|
|
|
|
|
|
|
// POSIX path object for compatibility
|
|
|
|
|
export const posix = {
|
|
|
|
|
join,
|
|
|
|
|
dirname,
|
|
|
|
|
basename,
|
|
|
|
|
extname,
|
|
|
|
|
resolve,
|
|
|
|
|
relative,
|
|
|
|
|
isAbsolute,
|
|
|
|
|
sep: '/',
|
|
|
|
|
delimiter: ':'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Default export
|
|
|
|
|
export default {
|
|
|
|
|
join,
|
|
|
|
|
dirname,
|
|
|
|
|
basename,
|
|
|
|
|
extname,
|
|
|
|
|
resolve,
|
|
|
|
|
relative,
|
|
|
|
|
isAbsolute,
|
|
|
|
|
sep,
|
|
|
|
|
delimiter,
|
|
|
|
|
posix
|
|
|
|
|
}
|