-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #223 from kitsuyui/string
Add @kitsuyui/string package
- Loading branch information
Showing
12 changed files
with
497 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# @kitsuyui/string | ||
|
||
A simple string manipulation library | ||
|
||
## Installation | ||
|
||
### NPM | ||
|
||
```bash | ||
npm install @kitsuyui/string | ||
``` | ||
|
||
### Yarn | ||
|
||
```bash | ||
yarn add @kitsuyui/string | ||
``` | ||
|
||
### PNPM | ||
|
||
```bash | ||
pnpm add @kitsuyui/string | ||
``` | ||
|
||
## Usage | ||
|
||
### convertCase | ||
|
||
```typescript | ||
import { convertCase } from '@kitsuyui/string'; | ||
|
||
convertCase('helloWorld', 'kebab-case') // => `hello-world` | ||
convertCase('hello-world', 'camelCase') // => `helloWorld` | ||
convertCase('helloWorld', 'kebab-case') // => `hello-world` | ||
convertCase('hello-world', 'camelCase') // => `helloWorld` | ||
convertCase('hello-world', 'snake_case') // => `hello_world` | ||
convertCase('hello-world', 'space separated') // => `hello world` | ||
convertCase('hello-world', 'UpperCamelCase') // => `HelloWorld` | ||
convertCase('hello-world', 'PascalCase') // => `HelloWorld` | ||
convertCase('hello-world', 'lowerCamelCase') // => `helloWorld` | ||
convertCase('hello-world', 'lowerPascalCase') // => `helloWorld` | ||
convertCase('hello-world', 'SCREAMING_SNAKE_CASE') // => `HELLO_WORLD` | ||
convertCase('hello-world', 'MACRO_CASE') // => `HELLO_WORLD` | ||
convertCase('hello-world', 'Train-Case') // => `Hello-World` | ||
convertCase('hello-world', 'dot.separated') // => `hello.world` | ||
convertCase('hello-world', 'flatcase') // => `helloworld` | ||
convertCase('hello-world', 'ALL CAPS') // => `HELLO WORLD` | ||
``` | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "@kitsuyui/string", | ||
"version": "0.0.0", | ||
"license": "MIT", | ||
"author": "Yui Kitsu <[email protected]>", | ||
"description": "A simple additional library for String", | ||
"scripts": { | ||
"build": "tsup src/index.ts --clean", | ||
"dev": "pnpm build --watch" | ||
}, | ||
"bin": { | ||
"ts-playground-main": "./dist/main.js" | ||
}, | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.js", | ||
"types": "./dist/index.d.ts" | ||
} | ||
}, | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"package.json" | ||
], | ||
"devDependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { describe, it, expect, jest } from '@jest/globals' | ||
|
||
import { isValidCaseName } from '.' | ||
|
||
describe('isValidCaseName', () => { | ||
it('should return true for valid case names', () => { | ||
expect(isValidCaseName('kebab-case')).toBe(true) | ||
expect(isValidCaseName('snake_case')).toBe(true) | ||
expect(isValidCaseName('space separated')).toBe(true) | ||
expect(isValidCaseName('camelCase')).toBe(true) | ||
expect(isValidCaseName('UpperCamelCase')).toBe(true) | ||
expect(isValidCaseName('lowerCamelCase')).toBe(true) | ||
expect(isValidCaseName('PascalCase')).toBe(true) | ||
expect(isValidCaseName('lowerPascalCase')).toBe(true) | ||
expect(isValidCaseName('SCREAMING_SNAKE_CASE')).toBe(true) | ||
expect(isValidCaseName('MACRO_CASE')).toBe(true) | ||
expect(isValidCaseName('Train-Case')).toBe(true) | ||
expect(isValidCaseName('dot.separated')).toBe(true) | ||
expect(isValidCaseName('flatcase')).toBe(true) | ||
expect(isValidCaseName('ALL CAPS')).toBe(true) | ||
}) | ||
|
||
it('should return false for invalid case names', () => { | ||
expect(isValidCaseName('invalid')).toBe(false) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
export const ALL_CASES = [ | ||
'kebab-case', | ||
'snake_case', | ||
'space separated', | ||
'camelCase', | ||
'UpperCamelCase', | ||
'lowerCamelCase', | ||
'PascalCase', // equivalent to UpperCamelCase | ||
'lowerPascalCase', // equivalent to lowerCamelCase | ||
'SCREAMING_SNAKE_CASE', | ||
'MACRO_CASE', // equivalent to SCREAMING_SNAKE_CASE | ||
'Train-Case', | ||
'dot.separated', | ||
'flatcase', | ||
'ALL CAPS', | ||
] as const | ||
|
||
export type Case = typeof ALL_CASES[number] | ||
|
||
/** | ||
* Check if a string is a valid Case Name | ||
* @param caseText | ||
* @returns | ||
*/ | ||
export const isValidCaseName = (caseText: string): caseText is Case => { | ||
return ALL_CASES.includes(caseText as Case) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { describe, it, expect, jest } from '@jest/globals' | ||
|
||
import { convertCase } from '.' | ||
import { ALL_CASES, type Case } from '../cases' | ||
|
||
describe('convertCase', () => { | ||
it('should work some simple examples', () => { | ||
expect(convertCase('helloWorld', 'kebab-case')).toBe('hello-world') | ||
expect(convertCase('hello-world', 'camelCase')).toBe('helloWorld') | ||
expect(convertCase('hello-world', 'snake_case')).toBe('hello_world') | ||
expect(convertCase('hello-world', 'space separated')).toBe('hello world') | ||
expect(convertCase('hello-world', 'UpperCamelCase')).toBe('HelloWorld') | ||
expect(convertCase('hello-world', 'PascalCase')).toBe('HelloWorld') | ||
expect(convertCase('hello-world', 'lowerCamelCase')).toBe('helloWorld') | ||
expect(convertCase('hello-world', 'lowerPascalCase')).toBe('helloWorld') | ||
expect(convertCase('hello-world', 'SCREAMING_SNAKE_CASE')).toBe('HELLO_WORLD') | ||
expect(convertCase('hello-world', 'MACRO_CASE')).toBe('HELLO_WORLD') | ||
expect(convertCase('hello-world', 'Train-Case')).toBe('Hello-World') | ||
expect(convertCase('hello-world', 'dot.separated')).toBe('hello.world') | ||
expect(convertCase('hello-world', 'flatcase')).toBe('helloworld') | ||
expect(convertCase('hello-world', 'ALL CAPS')).toBe('HELLO WORLD') | ||
}) | ||
|
||
it('should convert text to all cases', () => { | ||
const text = 'convert this text to all cases' | ||
for (const toCase of ALL_CASES) { | ||
const converted = convertCase(text, toCase) | ||
expect(converted).toBeTruthy() | ||
} | ||
}) | ||
|
||
it('should throw an error for invalid case', () => { | ||
const text = 'convert this text to all cases' | ||
const toCase = 'invalid' | ||
expect(() => convertCase(text, 'invalid' as Case)).toThrowError('Invalid Case: invalid') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { splitToWords } from "../split" | ||
import { joinWords } from "../join" | ||
import { ALL_CASES, type Case } from "../cases" | ||
|
||
const isValidCase = (caseText: string): caseText is Case => { | ||
return ALL_CASES.includes(caseText as Case) | ||
} | ||
|
||
|
||
export const convertCase = (text: string, toCase: Case): string => { | ||
if (!isValidCase(toCase)) { | ||
throw new Error(`Invalid Case: ${toCase}`) | ||
} | ||
const words = splitToWords(text) | ||
const converted = joinWords(words, toCase) | ||
return converted | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { convertCase } from './convert' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { describe, it, expect, jest } from '@jest/globals' | ||
|
||
import { | ||
joinWords, | ||
intoAllCaps, | ||
intoFlatCase, | ||
intoKebabCase, | ||
intoScreamingSnakeCase, | ||
intoSnakeCase, | ||
intoSpaceSeparated, | ||
intoTrainCase, | ||
intoLowerCamelCase, | ||
intoDotSeparated, | ||
} from './index' | ||
import type { Case } from '../cases' | ||
|
||
describe('joinWords', () => { | ||
it('should join words into the specified case', () => { | ||
const words = ['join', 'words'] | ||
const kebab = joinWords(words, 'kebab-case') | ||
expect(kebab).toBe('join-words') | ||
}) | ||
|
||
it('should throw an error for invalid case', () => { | ||
const words = ['join', 'words'] | ||
expect(() => joinWords(words, 'invalid' as Case)).toThrowError('Invalid Case: invalid') | ||
expect(() => joinWords(words, undefined as unknown as Case)).toThrowError('Case is required') | ||
}) | ||
}) | ||
|
||
describe('intoKebabCase', () => { | ||
it('should join words into kebab case', () => { | ||
const words = ['kebab', 'case'] | ||
const kebab = intoKebabCase(words) | ||
expect(kebab).toBe('kebab-case') | ||
}) | ||
}) | ||
|
||
describe('intoSnakeCase', () => { | ||
it('should join words into snake case', () => { | ||
const words = ['snake', 'case'] | ||
const snake = intoSnakeCase(words) | ||
expect(snake).toBe('snake_case') | ||
}) | ||
}) | ||
|
||
describe('intoSpaceSeparated', () => { | ||
it('should join words into space separated', () => { | ||
const words = ['space', 'separated'] | ||
const space = intoSpaceSeparated(words) | ||
expect(space).toBe('space separated') | ||
}) | ||
}) | ||
|
||
describe('intoAllCaps', () => { | ||
it('should join words into all caps', () => { | ||
const words = ['all', 'caps'] | ||
const caps = intoAllCaps(words) | ||
expect(caps).toBe('ALL CAPS') | ||
}) | ||
}) | ||
|
||
describe('intoScreamingSnakeCase', () => { | ||
it('should join words into screaming snake case', () => { | ||
const words = ['screaming', 'snake', 'case'] | ||
const snake = intoScreamingSnakeCase(words) | ||
expect(snake).toBe('SCREAMING_SNAKE_CASE') | ||
}) | ||
}) | ||
|
||
describe('intoTrainCase', () => { | ||
it('should join words into train case', () => { | ||
const words = ['train', 'case'] | ||
const train = intoTrainCase(words) | ||
expect(train).toBe('Train-Case') | ||
}) | ||
}) | ||
|
||
describe('intoFlatCase', () => { | ||
it('should join words into flat case', () => { | ||
const words = ['flat', 'case'] | ||
const flat = intoFlatCase(words) | ||
expect(flat).toBe('flatcase') | ||
}) | ||
}) | ||
|
||
describe('intoDotSeparated', () => { | ||
it('should join words into dot separated', () => { | ||
const words = ['dot', 'separated'] | ||
const dot = intoDotSeparated(words) | ||
expect(dot).toBe('dot.separated') | ||
}) | ||
}) | ||
|
||
describe('intoLowerCamelCase', () => { | ||
it('should join words into lower camel case', () => { | ||
const words = ['lower', 'camel', 'case'] | ||
const camel = intoLowerCamelCase(words) | ||
expect(camel).toBe('lowerCamelCase') | ||
}) | ||
}) |
Oops, something went wrong.