diff --git a/.changeset/tiny-dodos-juggle.md b/.changeset/tiny-dodos-juggle.md new file mode 100644 index 00000000000..c721b667058 --- /dev/null +++ b/.changeset/tiny-dodos-juggle.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +Honor custom split and strip regular expressions passed to `String.noCase`. diff --git a/packages/effect/src/String.ts b/packages/effect/src/String.ts index 5bee588be46..ecf3d86e740 100644 --- a/packages/effect/src/String.ts +++ b/packages/effect/src/String.ts @@ -1234,15 +1234,20 @@ export const noCase: { readonly delimiter?: string | undefined readonly transform?: (part: string, index: number, parts: ReadonlyArray) => string }): string => { + const splitRegExp = toRegExpArray(options?.splitRegExp ?? SPLIT_REGEXP) + const stripRegExp = toRegExpArray(options?.stripRegExp ?? STRIP_REGEXP) const delimiter = options?.delimiter ?? " " const transform = options?.transform ?? toLowerCase - return normalizeCase(input, SPLIT_REGEXP, STRIP_REGEXP, delimiter, transform) + return normalizeCase(input, splitRegExp, stripRegExp, delimiter, transform) }) +const toRegExpArray = (regexp: RegExp | ReadonlyArray): ReadonlyArray => + predicate.isRegExp(regexp) ? [regexp] : regexp + const normalizeCase = ( input: string, splitRegExp: ReadonlyArray, - stripRegExp: RegExp, + stripRegExp: ReadonlyArray, delimiter: string, transform: (part: string, index: number, parts: ReadonlyArray) => string ): string => { @@ -1250,7 +1255,9 @@ const normalizeCase = ( for (const regexp of splitRegExp) { result = result.replace(regexp, "$1\0$2") } - result = result.replace(stripRegExp, "\0") + for (const regexp of stripRegExp) { + result = result.replace(regexp, "\0") + } let start = 0 let end = result.length // Trim the delimiter from around the output string. @@ -1370,7 +1377,7 @@ export const constantCase: (self: string) => string = noCase({ * @since 4.0.0 */ export const configCase: (self: string) => string = (self) => - normalizeCase(self, CONFIG_SPLIT_REGEXP, STRIP_REGEXP, "_", toUpperCase) + normalizeCase(self, CONFIG_SPLIT_REGEXP, [STRIP_REGEXP], "_", toUpperCase) /** * Converts a string to kebab-case (lowercase with hyphens). diff --git a/packages/effect/test/String.test.ts b/packages/effect/test/String.test.ts index b0612ba9d86..26d43e5c852 100644 --- a/packages/effect/test/String.test.ts +++ b/packages/effect/test/String.test.ts @@ -634,6 +634,22 @@ describe("String", () => { strictEqual(pipe("helloWorld", S.noCase({ delimiter: "-" })), "hello-world") }) + it("uses a custom split regular expression", () => { + strictEqual(S.noCase("ab", { splitRegExp: /([a])([b])/g }), "a b") + }) + + it("uses custom split regular expressions", () => { + strictEqual(S.noCase("abc", { splitRegExp: [/([a])([b])/g, /([b])([c])/g] }), "a b c") + }) + + it("uses a custom strip regular expression", () => { + strictEqual(S.noCase("a_b-c", { stripRegExp: /_/g }), "a b-c") + }) + + it("uses custom strip regular expressions", () => { + strictEqual(S.noCase("a_b-c", { stripRegExp: [/_/g, /-/g] }), "a b c") + }) + it("handles underscores and hyphens", () => { strictEqual(S.noCase("hello_world"), "hello world") strictEqual(S.noCase("hello-world"), "hello world")