diff --git a/CHANGELOG.md b/CHANGELOG.md index 4481b74..effaeaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # deverything +## 0.47.2 + +### Patch Changes + +- added position to truncate + ## 0.47.1 ### Patch Changes diff --git a/package.json b/package.json index 94fa6e6..0e63bda 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deverything", - "version": "0.47.1", + "version": "0.47.2", "description": "Everything you need for Dev", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/src/helpers/truncate.test.ts b/src/helpers/truncate.test.ts index 5f607d0..3e586d8 100644 --- a/src/helpers/truncate.test.ts +++ b/src/helpers/truncate.test.ts @@ -2,14 +2,65 @@ import { describe, expect, test } from "@jest/globals"; import { truncate } from "./truncate"; describe("truncate", () => { - test("works", async () => { + test("basic functionality", async () => { expect(truncate("asd", -Infinity)).toBe("asd"); expect(truncate("asd", Infinity)).toBe("asd"); expect(truncate("asd", -1)).toBe("asd"); expect(truncate("", 0)).toBe(""); expect(truncate("", 1)).toBe(""); expect(truncate("1", 1)).toBe("1"); - expect(truncate("1 ", 1)).toBe("1..."); - expect(truncate("😴😄😃⛔🎠🚓🚇", 4)).toBe("😴😄😃⛔..."); + expect(truncate("12345", 4)).toBe("1..."); + expect(truncate("😴😄😃⛔🎠🚓🚇", 4)).toBe("😴..."); + }); + test("truncation at the start", () => { + expect( + truncate("Hello, world!", 8, { + position: "start", + }) + ).toBe("...orld!"); + expect( + truncate("😴😄😃⛔🎠🚓🚇", 6, { + position: "start", + }) + ).toBe("...🎠🚓🚇"); + }); + + test("truncation in the middle", () => { + expect( + truncate("Hello, world!", 11, { + position: "middle", + }) + ).toBe("Hell...rld!"); + expect( + truncate("😴😄😃⛔🎠🚓🚇", 5, { + position: "middle", + }) + ).toBe("😴...🚇"); + }); + + test("truncation at the end", () => { + expect( + truncate("Hello, world!", 10, { + position: "end", + }) + ).toBe("Hello, ..."); + expect( + truncate("😴😄😃⛔🎠🚓🚇", 5, { + position: "end", + }) + ).toBe("😴😄..."); + }); + + test("custom ellipsis", () => { + const originalUrl = + "https://very-long-url.com/path?query=string&anotherParam=value"; + const expectedUrl = + "https://very-long-url.com[...]string&anotherParam=value"; + expect( + truncate(originalUrl, 55, { + ellipsis: "[...]", + position: "middle", + }) + ).toBe(expectedUrl); }); }); diff --git a/src/helpers/truncate.ts b/src/helpers/truncate.ts index 3088968..34b560c 100644 --- a/src/helpers/truncate.ts +++ b/src/helpers/truncate.ts @@ -1,11 +1,40 @@ import { isPositiveInt } from "../validators/isNumber"; -export const truncate = (arg: string, limit: number, ellipsis = "...") => { +export const truncate = ( + arg: string, + limit: number, + { + ellipsis, + position, + }: { ellipsis?: string; position?: "start" | "middle" | "end" } = {} +) => { + if (!ellipsis) ellipsis = "..."; + if (!position) position = "end"; + if (!isPositiveInt(limit)) return arg; const argArray = [...arg]; // convert string to array, emoji and unicode safe + const ellipsisLength = ellipsis.length; + if (argArray.length <= limit) return arg; - return argArray.slice(0, limit).join("") + ellipsis; + switch (position) { + case "start": + const startSliceLength = limit - ellipsisLength; + return ellipsis + argArray.slice(-startSliceLength).join(""); + case "middle": { + const startSliceLength = Math.ceil((limit - ellipsisLength) / 2); + const endSliceStart = + argArray.length - Math.floor((limit - ellipsisLength) / 2); + return ( + argArray.slice(0, startSliceLength).join("") + + ellipsis + + argArray.slice(endSliceStart).join("") + ); + } + case "end": + default: + return argArray.slice(0, limit - ellipsisLength).join("") + ellipsis; + } };