Skip to content

Commit

Permalink
style: lint and format with prettier v3
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Nov 15, 2023
1 parent 3a5f1a6 commit ba39ce6
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 94 deletions.
17 changes: 9 additions & 8 deletions README.md
Expand Up @@ -19,10 +19,10 @@ Import:

```js
// CommonJS
const { pascalCase } = require('scule')
const { pascalCase } = require("scule");

// ESM
import { pascalCase } from 'scule'
import { pascalCase } from "scule";
```

**Notice:** You may need to transpile package for legacy environments.
Expand All @@ -34,7 +34,7 @@ import { pascalCase } from 'scule'
Splits string and joins by PascalCase convention:

```ts
pascalCase('foo-bar_baz')
pascalCase("foo-bar_baz");
// FooBarBaz
```

Expand All @@ -45,7 +45,7 @@ pascalCase('foo-bar_baz')
Splits string and joins by camelCase convention:

```ts
camelCase('foo-bar_baz')
camelCase("foo-bar_baz");
// fooBarBaz
```

Expand All @@ -54,7 +54,7 @@ camelCase('foo-bar_baz')
Splits string and joins by kebab-case convention:

```ts
kebabCase('fooBar_Baz')
kebabCase("fooBar_Baz");
// foo-bar-baz
```

Expand All @@ -65,7 +65,7 @@ kebabCase('fooBar_Baz')
Splits string and joins by snake_case convention:

```ts
snakeCase('foo-barBaz')
snakeCase("foo-barBaz");
// foo_bar_baz
```

Expand All @@ -74,7 +74,7 @@ snakeCase('foo-barBaz')
Converts first character to upper case:

```ts
upperFirst('hello world!')
upperFirst("hello world!");
// Hello world!
```

Expand All @@ -83,7 +83,7 @@ upperFirst('hello world!')
Converts first character to lower case:

```ts
lowerFirst('Hello world!')
lowerFirst("Hello world!");
// hello world!
```

Expand All @@ -108,6 +108,7 @@ lowerFirst('Hello world!')
[MIT](./LICENSE)

<!-- Badges -->

[npm-version-src]: https://img.shields.io/npm/v/scule?style=flat&colorA=18181B&colorB=F0DB4F
[npm-version-href]: https://npmjs.com/package/scule
[npm-downloads-src]: https://img.shields.io/npm/dm/scule?style=flat&colorA=18181B&colorB=F0DB4F
Expand Down
38 changes: 19 additions & 19 deletions src/index.ts
Expand Up @@ -13,11 +13,11 @@ export function isUppercase(char = ""): boolean | undefined {
export function splitByCase<T extends string>(string_: T): SplitByCase<T>;
export function splitByCase<
T extends string,
Separator extends readonly string[]
Separator extends readonly string[],
>(string_: T, separators: Separator): SplitByCase<T, Separator[number]>;
export function splitByCase<
T extends string,
Separator extends readonly string[]
Separator extends readonly string[],
>(string_: T, separators?: Separator) {
const splitters = separators ?? STR_SPLITTERS;
const parts: string[] = [];
Expand Down Expand Up @@ -52,7 +52,7 @@ export function splitByCase<
}
// Case falling edge
if (previousUpper === true && isUpper === false && buff.length > 1) {
const lastChar = buff[buff.length - 1];
const lastChar = buff.at(-1);
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
buff = lastChar + char;
previousUpper = isUpper;
Expand All @@ -73,58 +73,58 @@ export function splitByCase<

export function upperFirst<S extends string>(string_: S): Capitalize<S> {
return (
!string_ ? "" : string_[0].toUpperCase() + string_.slice(1)
string_ ? string_[0].toUpperCase() + string_.slice(1) : ""
) as Capitalize<S>;
}

export function lowerFirst<S extends string>(string_: S): Uncapitalize<S> {
return (
!string_ ? "" : string_[0].toLowerCase() + string_.slice(1)
string_ ? string_[0].toLowerCase() + string_.slice(1) : ""
) as Uncapitalize<S>;
}

export function pascalCase(): "";
export function pascalCase<T extends string | readonly string[]>(
string_: T
string_: T,
): PascalCase<T>;
export function pascalCase<T extends string | readonly string[]>(string_?: T) {
return !string_
? ""
: ((Array.isArray(string_) ? string_ : splitByCase(string_ as string))
return string_
? ((Array.isArray(string_) ? string_ : splitByCase(string_ as string))
.map((p) => upperFirst(p))
.join("") as PascalCase<T>);
.join("") as PascalCase<T>)
: "";
}

export function camelCase(): "";
export function camelCase<T extends string | readonly string[]>(
string_: T
string_: T,
): CamelCase<T>;
export function camelCase<T extends string | readonly string[]>(string_?: T) {
return lowerFirst(pascalCase(string_ || "")) as CamelCase<T>;
}

export function kebabCase(): "";
export function kebabCase<T extends string | readonly string[]>(
string_: T
string_: T,
): JoinByCase<T, "-">;
export function kebabCase<
T extends string | readonly string[],
Joiner extends string
Joiner extends string,
>(string_: T, joiner: Joiner): JoinByCase<T, Joiner>;
export function kebabCase<
T extends string | readonly string[],
Joiner extends string
Joiner extends string,
>(string_?: T, joiner?: Joiner) {
return !string_
? ""
: ((Array.isArray(string_) ? string_ : splitByCase(string_ as string))
return string_
? ((Array.isArray(string_) ? string_ : splitByCase(string_ as string))
.map((p) => p.toLowerCase())
.join(joiner ?? "-") as JoinByCase<T, Joiner>);
.join(joiner ?? "-") as JoinByCase<T, Joiner>)
: "";
}

export function snakeCase(): "";
export function snakeCase<T extends string | readonly string[]>(
string_: T
string_: T,
): JoinByCase<T, "_">;
export function snakeCase<T extends string | readonly string[]>(string_?: T) {
return kebabCase(string_ || "", "_") as JoinByCase<T, "_">;
Expand Down
137 changes: 70 additions & 67 deletions src/types.ts
Expand Up @@ -16,22 +16,22 @@ type IsUpper<S extends string> = S extends Uppercase<S> ? true : false;
type IsLower<S extends string> = S extends Lowercase<S> ? true : false;
type SameLetterCase<
X extends string,
Y extends string
Y extends string,
> = IsUpper<X> extends IsUpper<Y>
? true
: IsLower<X> extends IsLower<Y>
? true
: false;
? true
: false;
type CapitalizedWords<
T extends readonly string[],
Accumulator extends string = ""
Accumulator extends string = "",
> = T extends readonly [infer F extends string, ...infer R extends string[]]
? CapitalizedWords<R, `${Accumulator}${Capitalize<F>}`>
: Accumulator;
type JoinLowercaseWords<
T extends readonly string[],
Joiner extends string,
Accumulator extends string = ""
Accumulator extends string = "",
> = T extends readonly [infer F extends string, ...infer R extends string[]]
? Accumulator extends ""
? JoinLowercaseWords<R, Joiner, `${Accumulator}${Lowercase<F>}`>
Expand All @@ -46,85 +46,88 @@ type RemoveLastOfArray<T extends any[]> = T extends [...infer F, any]
export type SplitByCase<
T,
Separator extends string = Splitter,
Accumulator extends unknown[] = []
Accumulator extends unknown[] = [],
> = string extends Separator
? string[]
: T extends `${infer F}${infer R}`
? [LastOfArray<Accumulator>] extends [never]
? SplitByCase<R, Separator, [F]>
: LastOfArray<Accumulator> extends string
? R extends ""
? SplitByCase<
R,
Separator,
[...RemoveLastOfArray<Accumulator>, `${LastOfArray<Accumulator>}${F}`]
>
: SameLetterCase<F, FirstOfString<R>> extends true
? F extends Separator
? FirstOfString<R> extends Separator
? SplitByCase<R, Separator, [...Accumulator, ""]>
: IsUpper<FirstOfString<R>> extends true
? [LastOfArray<Accumulator>] extends [never]
? SplitByCase<R, Separator, [F]>
: LastOfArray<Accumulator> extends string
? R extends ""
? SplitByCase<
RemoveFirstOfString<R>,
R,
Separator,
[...Accumulator, FirstOfString<R>]
[
...RemoveLastOfArray<Accumulator>,
`${LastOfArray<Accumulator>}${F}`,
]
>
: SplitByCase<R, Separator, [...Accumulator, ""]>
: SplitByCase<
R,
Separator,
[
...RemoveLastOfArray<Accumulator>,
`${LastOfArray<Accumulator>}${F}`
]
>
: IsLower<F> extends true
? SplitByCase<
RemoveFirstOfString<R>,
Separator,
[
...RemoveLastOfArray<Accumulator>,
`${LastOfArray<Accumulator>}${F}`,
FirstOfString<R>
]
>
: SplitByCase<R, Separator, [...Accumulator, F]>
: never
: Accumulator extends []
? T extends ""
? []
: string[]
: Accumulator;
: SameLetterCase<F, FirstOfString<R>> extends true
? F extends Separator
? FirstOfString<R> extends Separator
? SplitByCase<R, Separator, [...Accumulator, ""]>
: IsUpper<FirstOfString<R>> extends true
? SplitByCase<
RemoveFirstOfString<R>,
Separator,
[...Accumulator, FirstOfString<R>]
>
: SplitByCase<R, Separator, [...Accumulator, ""]>
: SplitByCase<
R,
Separator,
[
...RemoveLastOfArray<Accumulator>,
`${LastOfArray<Accumulator>}${F}`,
]
>
: IsLower<F> extends true
? SplitByCase<
RemoveFirstOfString<R>,
Separator,
[
...RemoveLastOfArray<Accumulator>,
`${LastOfArray<Accumulator>}${F}`,
FirstOfString<R>,
]
>
: SplitByCase<R, Separator, [...Accumulator, F]>
: never
: Accumulator extends []
? T extends ""
? []
: string[]
: Accumulator;

export type PascalCase<T> = string extends T
? string
: string[] extends T
? string
: T extends string
? SplitByCase<T> extends readonly string[]
? CapitalizedWords<SplitByCase<T>>
: never
: T extends readonly string[]
? CapitalizedWords<T>
: never;
? string
: T extends string
? SplitByCase<T> extends readonly string[]
? CapitalizedWords<SplitByCase<T>>
: never
: T extends readonly string[]
? CapitalizedWords<T>
: never;

export type CamelCase<T> = string extends T
? string
: string[] extends T
? string
: Uncapitalize<PascalCase<T>>;
? string
: Uncapitalize<PascalCase<T>>;

export type JoinByCase<T, Joiner extends string> = string extends T
? string
: string[] extends T
? string
: T extends string
? SplitByCase<T> extends readonly string[]
? JoinLowercaseWords<SplitByCase<T>, Joiner>
: never
: T extends readonly string[]
? JoinLowercaseWords<T, Joiner>
: never;
? string
: T extends string
? SplitByCase<T> extends readonly string[]
? JoinLowercaseWords<SplitByCase<T>, Joiner>
: never
: T extends readonly string[]
? JoinLowercaseWords<T, Joiner>
: never;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
type __tests = [
Expand Down Expand Up @@ -184,6 +187,6 @@ type __tests = [
Assert<Equal<JoinByCase<"FooBARb", "-">, "foo-ba-rb">>,
Assert<Equal<JoinByCase<"foo_bar-baz/qux", "-">, "foo-bar-baz-qux">>,
// array
Assert<Equal<JoinByCase<["Foo", "Bar"], "-">, "foo-bar">>
Assert<Equal<JoinByCase<["Foo", "Bar"], "-">, "foo-bar">>,
];
/* eslint-enable @typescript-eslint/no-unused-vars */

0 comments on commit ba39ce6

Please sign in to comment.