diff --git a/.changeset/major-nights-fix.md b/.changeset/major-nights-fix.md new file mode 100644 index 0000000..a1cb321 --- /dev/null +++ b/.changeset/major-nights-fix.md @@ -0,0 +1,6 @@ +--- +"std": minor +--- + +feat: Add `equalsOneOf` utility + \ No newline at end of file diff --git a/.changeset/salty-kiwis-give.md b/.changeset/salty-kiwis-give.md new file mode 100644 index 0000000..06bd7b4 --- /dev/null +++ b/.changeset/salty-kiwis-give.md @@ -0,0 +1,6 @@ +--- +"std": minor +--- + +feat: Update `strings` API to return the matched string for `startsWithOneOf` and `endsWithOneOf` + \ No newline at end of file diff --git a/package.json b/package.json index dea40e8..ba876ec 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,6 @@ "typedoc-material-theme": "^1.4.0" }, "pnpm": { - "onlyBuiltDependencies": [ - "@biomejs/biome", - "esbuild" - ] + "onlyBuiltDependencies": ["@biomejs/biome", "esbuild"] } } diff --git a/src/ts/strings.test.ts b/src/ts/strings.test.ts index fc59197..a655aef 100644 --- a/src/ts/strings.test.ts +++ b/src/ts/strings.test.ts @@ -1,17 +1,24 @@ import { describe, expect, it } from 'vitest'; import * as strings from './strings'; +describe('equalsOneOf', () => { + it('correctly identifies a string that equals one of the provided strings', () => { + expect(strings.equalsOneOf('aa', ['aa', 'ba'])).toBe('aa'); + expect(strings.equalsOneOf('aa', ['ba', 'ca'])).toBe(undefined); + }); +}); + describe('startsWithOneOf', () => { it('correctly identifies a string that starts with one of the provided strings', () => { - expect(strings.startsWithOneOf('aab', ['aa', 'ba'])).toBe(true); - expect(strings.startsWithOneOf('aab', ['ba', 'ca'])).toBe(false); + expect(strings.startsWithOneOf('aab', ['aa', 'ba'])).toBe('aa'); + expect(strings.startsWithOneOf('aab', ['ba', 'ca'])).toBe(undefined); }); }); describe('endsWithOneOf', () => { it('correctly identifies a string that ends with one of the provided strings', () => { - expect(strings.endsWithOneOf('baa', ['aa', 'ca'])).toBe(true); - expect(strings.endsWithOneOf('baa', ['ab', 'ac'])).toBe(false); + expect(strings.endsWithOneOf('baa', ['aa', 'ca'])).toBe('aa'); + expect(strings.endsWithOneOf('baa', ['ab', 'ac'])).toBe(undefined); }); }); diff --git a/src/ts/strings.ts b/src/ts/strings.ts index 1a00e51..63fc3ee 100644 --- a/src/ts/strings.ts +++ b/src/ts/strings.ts @@ -1,4 +1,4 @@ -/** Returns true if `str` starts with one of the provided `strings`. +/** Returns the string that matches the string (if it exits). Great for matching string union types. * * @param str * @param strings @@ -6,19 +6,50 @@ * * ## Usage * ```ts - * startsWithOneOf('ab', 'a', 'c'); // true - * startsWithOneOf('cc', 'a', 'b'); // false + * const methods = ['GET', 'PUT', 'POST', 'PATCH', 'DELETE'] as const; + * + * const methodStr: string = 'GET'; + * + * const method = equalsOneOf(methodStr, methods); + * + * if (method) { + * // if method was just a string this would be a type error + * methods.includes(method) + * } + * ``` + */ +export function equalsOneOf(str: string, strings: readonly T[]): T | undefined { + for (const s of strings) { + if (s === str) return s; + } + + return undefined; +} + +/** Returns the matched prefix for the string (if it exists). Great for matching string union types. + * + * @param str + * @param strings + * @returns + * + * ## Usage + * ```ts + * startsWithOneOf('ab', 'a', 'c'); // 'a' + * startsWithOneOf('cc', 'a', 'b'); // undefined * ``` */ -export function startsWithOneOf(str: string, strings: string[]): boolean { +export function startsWithOneOf( + str: string, + strings: readonly T[] +): T | undefined { for (const s of strings) { - if (str.startsWith(s)) return true; + if (str.startsWith(s)) return s; } - return false; + return undefined; } -/** Returns true if `str` starts with one of the provided `strings`. +/** Returns the matched suffix for the string (if it exists). Great for matching string union types. * * @param str * @param strings @@ -26,16 +57,16 @@ export function startsWithOneOf(str: string, strings: string[]): boolean { * * ## Usage * ```ts - * endsWithOneOf('cb', 'a', 'b'); // true - * endsWithOneOf('cc', 'a', 'b'); // false + * endsWithOneOf('cb', 'a', 'b'); // 'b' + * endsWithOneOf('cc', 'a', 'b'); // undefined * ``` */ -export function endsWithOneOf(str: string, strings: string[]): boolean { +export function endsWithOneOf(str: string, strings: readonly T[]): T | undefined { for (const s of strings) { - if (str.endsWith(s)) return true; + if (str.endsWith(s)) return s; } - return false; + return undefined; } /** Case insensitive equality. Returns true if `left.toLowerCase()` and `right.toLowerCase()` are equal.