Path Case
Transform text to path/case format - lowercase words separated by forward slashes.
๐ Features
- Lightweight - Only ~450B minified + gzipped
- Type-safe - Full TypeScript support with comprehensive type definitions
- Zero dependencies - No external dependencies
- Tree-shakeable - ES modules support
- Universal - Works in browsers, Node.js, and serverless environments
- Well-tested - Comprehensive test suite with edge cases
- Customizable - Support for custom transform functions and options
๐ฆ Installation
# npm
npm install text-path-case
# yarn
yarn add text-path-case
# pnpm
pnpm add text-path-case
# bun
bun add text-path-case
๐ฏ Quick Start
import { pathCase } from "text-path-case";
console.log(pathCase("hello world")); // "hello/world"
console.log(pathCase("camelCase")); // "camel/case"
console.log(pathCase("kebab-case")); // "kebab/case"
๐ Usage
ES Modules (Recommended)
import { pathCase } from "text-path-case";
console.log(pathCase("hello world")); // "hello/world"
CommonJS
const { pathCase } = require("text-path-case");
console.log(pathCase("hello world")); // "hello/world"
TypeScript
import { pathCase } from "text-path-case";
const result: string = pathCase("hello world");
console.log(result); // "hello/world"
๐ Transformation Examples
Basic Transformations
import { pathCase } from "text-path-case";
// Simple cases
pathCase("hello world"); // "hello/world"
pathCase("Hello World"); // "hello/world"
pathCase("HELLO WORLD"); // "hello/world"
// From other cases
pathCase("camelCase"); // "camel/case"
pathCase("PascalCase"); // "pascal/case"
pathCase("snake_case"); // "snake/case"
pathCase("kebab-case"); // "kebab/case"
pathCase("dot.case"); // "dot/case"
// Complex examples
pathCase("XMLHttpRequest"); // "xml/http/request"
pathCase("iPhone"); // "i/phone"
pathCase("version 1.2.3"); // "version/1/2/3"
Advanced Usage with Options
import { pathCase } from "text-path-case";
// Custom transform function
pathCase("hello world", {
transform: (word, index, words) => {
// Custom transformation logic
return word.toLowerCase();
},
}); // "hello/world"
// Custom split regex
pathCase("hello-world_test", {
splitRegexp: /[-_\s]+/,
}); // "hello/world/test"
// Strip specific characters
pathCase("hello@world#test", {
stripRegexp: /[@#]/g,
}); // "hello/world/test"
๐ Real-World Examples
URL Path Generation
import { pathCase } from "text-path-case";
// Generate URL paths from titles
pathCase("User Profile Settings"); // "user/profile/settings"
pathCase("API Documentation"); // "api/documentation"
pathCase("Getting Started Guide"); // "getting/started/guide"
pathCase("FAQ Section"); // "faq/section"
File Path Construction
import { pathCase } from "text-path-case";
function createFilePath(category, subcategory, filename) {
const categoryPath = pathCase(category);
const subcategoryPath = pathCase(subcategory);
const filePath = pathCase(filename);
return `${categoryPath}/${subcategoryPath}/${filePath}`;
}
console.log(createFilePath("User Data", "Profile Images", "Avatar Photo"));
// "user/data/profile/images/avatar/photo"
console.log(createFilePath("API Docs", "Authentication", "OAuth Setup"));
// "api/docs/authentication/o/auth/setup"
Navigation Menu Structure
import { pathCase } from "text-path-case";
function createMenuStructure(menuItems) {
return menuItems.map((item) => ({
...item,
path: pathCase(item.title),
children: item.children ? createMenuStructure(item.children) : undefined,
}));
}
const menuItems = [
{
title: "User Management",
children: [
{ title: "User Profiles" },
{ title: "Account Settings" },
{ title: "Security Options" },
],
},
{
title: "Content Management",
children: [
{ title: "Blog Posts" },
{ title: "Media Library" },
{ title: "SEO Settings" },
],
},
];
console.log(createMenuStructure(menuItems));
// [
// {
// title: "User Management",
// path: "user/management",
// children: [
// { title: "User Profiles", path: "user/profiles" },
// { title: "Account Settings", path: "account/settings" },
// { title: "Security Options", path: "security/options" }
// ]
// },
// {
// title: "Content Management",
// path: "content/management",
// children: [
// { title: "Blog Posts", path: "blog/posts" },
// { title: "Media Library", path: "media/library" },
// { title: "SEO Settings", path: "seo/settings" }
// ]
// }
// ]
API Endpoint Generation
import { pathCase } from "text-path-case";
class ApiEndpointBuilder {
constructor(baseUrl = "/api") {
this.baseUrl = baseUrl;
}
buildEndpoint(resource, action = null, id = null) {
const resourcePath = pathCase(resource);
let endpoint = `${this.baseUrl}/${resourcePath}`;
if (id) {
endpoint += `/${id}`;
}
if (action) {
const actionPath = pathCase(action);
endpoint += `/${actionPath}`;
}
return endpoint;
}
buildNestedEndpoint(parentResource, parentId, childResource, childId = null) {
const parentPath = pathCase(parentResource);
const childPath = pathCase(childResource);
let endpoint = `${this.baseUrl}/${parentPath}/${parentId}/${childPath}`;
if (childId) {
endpoint += `/${childId}`;
}
return endpoint;
}
}
const api = new ApiEndpointBuilder();
console.log(api.buildEndpoint("User Profiles"));
// "/api/user/profiles"
console.log(api.buildEndpoint("Blog Posts", "Published Articles"));
// "/api/blog/posts/published/articles"
console.log(api.buildNestedEndpoint("User Accounts", 123, "Profile Settings"));
// "/api/user/accounts/123/profile/settings"
Breadcrumb Generation
import { pathCase } from "text-path-case";
function generateBreadcrumbs(pathSegments) {
const breadcrumbs = [];
let currentPath = "";
pathSegments.forEach((segment, index) => {
const pathSegment = pathCase(segment);
currentPath += (index === 0 ? "" : "/") + pathSegment;
breadcrumbs.push({
label: segment,
path: currentPath,
isLast: index === pathSegments.length - 1,
});
});
return breadcrumbs;
}
const pathSegments = [
"Home",
"User Management",
"Profile Settings",
"Security Options",
];
console.log(generateBreadcrumbs(pathSegments));
// [
// { label: "Home", path: "home", isLast: false },
// { label: "User Management", path: "home/user/management", isLast: false },
// { label: "Profile Settings", path: "home/user/management/profile/settings", isLast: false },
// { label: "Security Options", path: "home/user/management/profile/settings/security/options", isLast: true }
// ]
Static Site Generator
import { pathCase } from "text-path-case";
class StaticSiteGenerator {
constructor() {
this.pages = [];
}
addPage(title, content, category = null) {
const slug = pathCase(title);
const categoryPath = category ? pathCase(category) : null;
const fullPath = categoryPath ? `${categoryPath}/${slug}` : slug;
this.pages.push({
title,
slug,
category,
categoryPath,
fullPath,
content,
url: `/${fullPath}`,
});
}
generateSitemap() {
return this.pages.map((page) => ({
url: page.url,
title: page.title,
category: page.category,
}));
}
}
const ssg = new StaticSiteGenerator();
ssg.addPage("Getting Started Guide", "Content here", "Documentation");
ssg.addPage("API Reference", "API content", "Documentation");
ssg.addPage("User Authentication", "Auth content", "Tutorials");
ssg.addPage("About Us", "About content");
console.log(ssg.generateSitemap());
// [
// { url: "/documentation/getting/started/guide", title: "Getting Started Guide", category: "Documentation" },
// { url: "/documentation/api/reference", title: "API Reference", category: "Documentation" },
// { url: "/tutorials/user/authentication", title: "User Authentication", category: "Tutorials" },
// { url: "/about/us", title: "About Us", category: null }
// ]
Content Management System
import { pathCase } from "text-path-case";
class ContentManager {
constructor() {
this.content = new Map();
}
createContent(title, type, parentPath = null) {
const slug = pathCase(title);
const fullPath = parentPath ? `${parentPath}/${slug}` : slug;
const content = {
id: Date.now(),
title,
slug,
type,
path: fullPath,
createdAt: new Date(),
children: [],
};
this.content.set(fullPath, content);
return content;
}
createHierarchy(structure, parentPath = null) {
const result = [];
structure.forEach((item) => {
const content = this.createContent(item.title, item.type, parentPath);
if (item.children) {
content.children = this.createHierarchy(item.children, content.path);
}
result.push(content);
});
return result;
}
}
const cms = new ContentManager();
const siteStructure = [
{
title: "Blog Section",
type: "category",
children: [
{ title: "Technology Posts", type: "category" },
{ title: "Design Articles", type: "category" },
{ title: "Tutorial Content", type: "category" },
],
},
{
title: "Documentation",
type: "category",
children: [
{ title: "Getting Started", type: "page" },
{ title: "API Reference", type: "page" },
{ title: "Best Practices", type: "page" },
],
},
];
console.log(cms.createHierarchy(siteStructure));
// Creates a hierarchical structure with paths like:
// - "blog/section"
// - "blog/section/technology/posts"
// - "blog/section/design/articles"
// - "documentation"
// - "documentation/getting/started"
// etc.
๐ API Reference
pathCase(input, options?)
Transforms text to path/case format.
Parameters
input
(string
): The string to transformoptions
(object
, optional): Configuration optionstransform
(function
): Custom transform function for each wordsplitRegexp
(RegExp
): Custom regex for splitting wordsstripRegexp
(RegExp
): Custom regex for stripping characters
Returns
string
: The path/case formatted string
Options Interface
interface Options {
transform?: (word: string, index: number, words: string[]) => string;
splitRegexp?: RegExp;
stripRegexp?: RegExp;
}
๐ Bundle Size
This package is optimized for minimal bundle size:
- Minified: ~450B
- Gzipped: ~300B
- Tree-shakeable: Yes
- Side effects: None
๐ Browser Support
- Modern browsers: ES2015+ (Chrome 51+, Firefox 54+, Safari 10+)
- Node.js: 12+
- TypeScript: 4.0+
- Bundle formats: UMD, ESM, CommonJS
๐งช Testing
# Run tests
pnpm test
# Run tests in watch mode
pnpm test --watch
# Run tests with coverage
pnpm test --coverage
# Type checking
pnpm typecheck
# Linting
pnpm lint
๐ Related Packages
text-kebab-case
- Convert to kebab-casetext-dot-case
- Convert to dot.casetext-snake-case
- Convert to snake_casetext-case
- All case transformations in one package
๐ License
๐ค Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
๐ Support
- ๐ง Email: selikhov.dmitrey@gmail.com
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ Documentation: Full Documentation
Made with โค๏ธ by Dmitry Selikhov