UNPKG

wttp-core

Version:

Core contracts, interfaces, and TypeScript types for the Web3 Transfer Protocol (WTTP).

112 lines 4.13 kB
"use strict"; /** * Path normalization utilities for WTTP protocol * * These utilities handle the soft enforcement of web semantics by normalizing * paths for consistent storage while preserving semantic meaning through headers. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.normalizePath = normalizePath; exports.pathIndicatesDirectory = pathIndicatesDirectory; exports.pathIndicatesRelative = pathIndicatesRelative; exports.displayPath = displayPath; exports.validatePathEdgeCases = validatePathEdgeCases; /** * Normalizes a path by ensuring leading slash and handling trailing slashes based on directory status * * This implements "soft semantic enforcement" where: * - Storage layer: Consistent, normalized paths with trailing slashes for directories * - Presentation layer: Semantic trailing slashes preserved for directories * - Behavior layer: Headers determine actual functionality (directory vs file) * * @param path - The path to normalize * @param isDirectory - Optional flag indicating if the path represents a directory * @returns Normalized path with trailing slash for directories (including root "/") * @throws Error if path is malformed (multiple consecutive slashes, etc.) */ function normalizePath(path, isDirectory) { // Trim whitespace path = path.trim(); // Handle empty paths or root paths if (path === '' || path === '/') { return '/'; } if (pathIndicatesRelative(path)) { throw new Error(`Path should be absolute: ${path}`); } // Validate no double slashes in the middle if (path.includes('//')) { throw new Error(`Malformed path with double slashes: ${path}`); } // All paths except relative paths must start with a slash if (!path.startsWith('/')) { path = '/' + path; } if (isDirectory === undefined) { isDirectory = pathIndicatesDirectory(path); } // Add trailing slash for directories, remove trailing slash for files if (isDirectory) { path = !path.endsWith('/') ? path + '/' : path; } else { path = path.endsWith('/') && path !== '/' ? path.slice(0, -1) : path; } return path; } /** * Checks if a path represents a directory based on trailing slash * This is used for presentation/UX purposes only * * @param originalPath - The original path before normalization * @returns True if the path had a trailing slash (indicating directory intent) */ function pathIndicatesDirectory(originalPath) { if (!originalPath || originalPath.trim() === '') { return false; } const trimmed = originalPath.trim(); return trimmed.endsWith('/'); } function pathIndicatesRelative(originalPath) { if (!originalPath || originalPath.trim() === '') { return false; } return originalPath.startsWith('.') && originalPath.includes('./') || originalPath === '.'; } /** * Adds trailing slash for display purposes when path represents a directory * Used by client tools for UX consistency * * @param normalizedPath - The normalized path * @param isDirectory - Whether this path should be displayed as a directory * @returns Path with trailing slash added if it's a directory */ function displayPath(normalizedPath, isDirectory = false) { // Since normalizePath now handles directories correctly, we can just use it return normalizePath(normalizedPath, isDirectory); } /** * Edge case testing function - validates various path scenarios * Used primarily for testing to ensure normalization handles edge cases * * @param testPath - Path to validate * @returns Object with validation results */ function validatePathEdgeCases(testPath, isDirectory = false) { try { const normalized = normalizePath(testPath, isDirectory); return { isValid: true, normalized }; } catch (error) { return { isValid: false, indicatesDirectory: pathIndicatesDirectory(testPath), error: error instanceof Error ? error.message : 'Unknown error' }; } } //# sourceMappingURL=path.js.map