feat: enhance framework integration and simplify codebase
- Simplify universal modules to be more framework-friendly
- Add comprehensive framework integration documentation (Next.js, Vue, React)
- Implement missing relateMany() batch relationship creation method
- Clean up obsolete test files and improve test coverage
- Reduce browser polyfill complexity while maintaining compatibility
- Remove unused browserFramework entry points for cleaner API surface
📄 3,120 lines added, 3,679 lines removed for net simplification
This commit is contained in:
parent
4c208ef78d
commit
29e3b47c36
18 changed files with 3120 additions and 3679 deletions
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Universal Path implementation
|
||||
* Browser: Manual path operations
|
||||
* Node.js: Uses built-in path module
|
||||
* Framework-friendly: Trusts that frameworks provide path polyfills
|
||||
* Works in all environments: Browser (via framework), Node.js, Serverless
|
||||
*/
|
||||
|
||||
import { isNode } from '../utils/environment.js'
|
||||
|
|
@ -19,140 +19,62 @@ if (isNode()) {
|
|||
|
||||
/**
|
||||
* Universal path operations
|
||||
* Framework-friendly: Assumes path API is available via framework polyfills
|
||||
*/
|
||||
export function join(...paths: string[]): string {
|
||||
if (nodePath) {
|
||||
return nodePath.join(...paths)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
const parts: string[] = []
|
||||
for (const path of paths) {
|
||||
if (path) {
|
||||
parts.push(...path.split('/').filter(p => p))
|
||||
}
|
||||
}
|
||||
return parts.join('/')
|
||||
}
|
||||
|
||||
export function dirname(path: string): string {
|
||||
if (nodePath) {
|
||||
return nodePath.dirname(path)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
const parts = path.split('/').filter(p => p)
|
||||
if (parts.length <= 1) return '.'
|
||||
return parts.slice(0, -1).join('/')
|
||||
}
|
||||
|
||||
export function basename(path: string, ext?: string): string {
|
||||
if (nodePath) {
|
||||
return nodePath.basename(path, ext)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
const parts = path.split('/')
|
||||
let name = parts[parts.length - 1]
|
||||
|
||||
if (ext && name.endsWith(ext)) {
|
||||
name = name.slice(0, -ext.length)
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
export function extname(path: string): string {
|
||||
if (nodePath) {
|
||||
return nodePath.extname(path)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
const name = basename(path)
|
||||
const lastDot = name.lastIndexOf('.')
|
||||
return lastDot === -1 ? '' : name.slice(lastDot)
|
||||
}
|
||||
|
||||
export function resolve(...paths: string[]): string {
|
||||
if (nodePath) {
|
||||
return nodePath.resolve(...paths)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
let resolved = ''
|
||||
let resolvedAbsolute = false
|
||||
|
||||
for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
||||
const path = i >= 0 ? paths[i] : '/'
|
||||
|
||||
if (!path) continue
|
||||
|
||||
resolved = path + '/' + resolved
|
||||
resolvedAbsolute = path.charAt(0) === '/'
|
||||
}
|
||||
|
||||
// Normalize the path
|
||||
resolved = normalizeArray(resolved.split('/').filter(p => p), !resolvedAbsolute).join('/')
|
||||
|
||||
return (resolvedAbsolute ? '/' : '') + resolved
|
||||
}
|
||||
|
||||
export function relative(from: string, to: string): string {
|
||||
if (nodePath) {
|
||||
return nodePath.relative(from, to)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
const fromParts = resolve(from).split('/').filter(p => p)
|
||||
const toParts = resolve(to).split('/').filter(p => p)
|
||||
|
||||
let commonLength = 0
|
||||
for (let i = 0; i < Math.min(fromParts.length, toParts.length); i++) {
|
||||
if (fromParts[i] === toParts[i]) {
|
||||
commonLength++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const upCount = fromParts.length - commonLength
|
||||
const upParts = new Array(upCount).fill('..')
|
||||
const downParts = toParts.slice(commonLength)
|
||||
|
||||
return [...upParts, ...downParts].join('/')
|
||||
}
|
||||
|
||||
export function isAbsolute(path: string): boolean {
|
||||
if (nodePath) {
|
||||
return nodePath.isAbsolute(path)
|
||||
} else {
|
||||
throw new Error('Path operations not available. Framework bundlers should provide path polyfills.')
|
||||
}
|
||||
|
||||
// Browser fallback implementation
|
||||
return path.charAt(0) === '/'
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize array helper function
|
||||
*/
|
||||
function normalizeArray(parts: string[], allowAboveRoot: boolean): string[] {
|
||||
const res: string[] = []
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const p = parts[i]
|
||||
|
||||
if (!p || p === '.') continue
|
||||
|
||||
if (p === '..') {
|
||||
if (res.length && res[res.length - 1] !== '..') {
|
||||
res.pop()
|
||||
} else if (allowAboveRoot) {
|
||||
res.push('..')
|
||||
}
|
||||
} else {
|
||||
res.push(p)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Path separator (always use forward slash for consistency)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue