From 6df4c9af71c8fba8c8bd6eff88fe9986c759aa34 Mon Sep 17 00:00:00 2001 From: Orlando Date: Fri, 5 Jan 2024 22:07:35 +0000 Subject: [PATCH] seriesAll and handle suffix --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/helpers/clamp.test.ts | 1 + src/helpers/index.ts | 1 + src/helpers/seriesAll.test.ts | 14 ++++++++++++++ src/helpers/seriesAll.ts | 18 ++++++++++++++++++ src/random/randomEmail.test.ts | 1 + src/random/randomEmail.ts | 9 +++++++-- src/random/randomHandle.ts | 15 ++++++++++++--- src/types/Tuple.ts | 27 +++++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/helpers/seriesAll.test.ts create mode 100644 src/helpers/seriesAll.ts create mode 100644 src/types/Tuple.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ca9ea91..ef4c876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # deverything +## 0.39.0 + +### Minor Changes + +- seriesAll and handle suffix + ## 0.38.0 ### Minor Changes diff --git a/package.json b/package.json index fd06ba3..fef676a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deverything", - "version": "0.38.0", + "version": "0.39.0", "description": "Everything you need for Dev", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/src/helpers/clamp.test.ts b/src/helpers/clamp.test.ts index d03e074..fb42830 100644 --- a/src/helpers/clamp.test.ts +++ b/src/helpers/clamp.test.ts @@ -3,6 +3,7 @@ import { clamp } from "./clamp"; describe("clamp", () => { test("args", async () => { + expect(clamp({ number: 2, min: 1, max: 3 })).toBe(2); expect(clamp({ number: 0, min: 0, max: 0 })).toBe(0); expect(clamp({ number: -10, min: 0, max: 0 })).toBe(0); expect(clamp({ number: 10, min: 0, max: 0 })).toBe(0); diff --git a/src/helpers/index.ts b/src/helpers/index.ts index b967bc3..4aaf6c0 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -26,6 +26,7 @@ export * from "./pretty"; export * from "./promiseWithTimeout"; export * from "./scrambleText"; export * from "./serialize"; +export * from "./seriesAll"; export * from "./setUrlSearchParams"; export * from "./shuffle"; export * from "./sleep"; diff --git a/src/helpers/seriesAll.test.ts b/src/helpers/seriesAll.test.ts new file mode 100644 index 0000000..ca12022 --- /dev/null +++ b/src/helpers/seriesAll.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, test } from "@jest/globals"; +import { seriesAll } from "./seriesAll"; +import { sleep } from "./sleep"; + +describe("seriesAll", () => { + const fn1 = () => Promise.resolve(1); + const fn2 = () => sleep(100).then(() => 2); + const fn3 = () => 3; + + test("simple", async () => { + expect(seriesAll([fn1, fn2, fn3])).resolves.toEqual([1, 2, 3]); + expect(await seriesAll([() => true])).toStrictEqual([true]); + }); +}); diff --git a/src/helpers/seriesAll.ts b/src/helpers/seriesAll.ts new file mode 100644 index 0000000..35e79af --- /dev/null +++ b/src/helpers/seriesAll.ts @@ -0,0 +1,18 @@ +/** + * + * @description Run a series of (async) functions in order and return the results + * @example + * const results = await seriesAll([ + * () => Promise.resolve(1), + * () => sleep(100).then(() => 2), + * () => Promise.resolve(3), + * ]); + * @returns [1, 2, 3] + */ +export const seriesAll = async (series: Function[]): Promise => { + const results = []; + for (const fn of series) { + results.push(await fn()); + } + return results; +}; diff --git a/src/random/randomEmail.test.ts b/src/random/randomEmail.test.ts index a51630c..6593681 100644 --- a/src/random/randomEmail.test.ts +++ b/src/random/randomEmail.test.ts @@ -6,5 +6,6 @@ describe(`randomEmail`, () => { expect(randomEmail().length).toBeGreaterThan(0); expect(randomEmail()).toContain("."); expect(randomEmail()).toContain("@"); + expect(randomEmail({ handleSuffix: "_project" })).toContain("_project"); }); }); diff --git a/src/random/randomEmail.ts b/src/random/randomEmail.ts index 79b61dd..e0ba0c2 100644 --- a/src/random/randomEmail.ts +++ b/src/random/randomEmail.ts @@ -2,5 +2,10 @@ import { DOMAIN_NAMES } from "../constants/domains"; import { randomArrayItem } from "./randomArrayItem"; import { randomHandle } from "./randomHandle"; -export const randomEmail = () => - `${randomHandle()}@${randomArrayItem(DOMAIN_NAMES)}`; +export const randomEmail = ({ + handle, + handleSuffix, +}: { handle?: string; handleSuffix?: string } = {}) => + `${handle || randomHandle({ suffix: handleSuffix })}@${randomArrayItem( + DOMAIN_NAMES + )}`; diff --git a/src/random/randomHandle.ts b/src/random/randomHandle.ts index 979121f..956d6ed 100644 --- a/src/random/randomHandle.ts +++ b/src/random/randomHandle.ts @@ -1,10 +1,19 @@ import { WESTERN_FIRST_NAMES, WESTERN_LAST_NAMES } from "../constants/names"; +import { incrementalId } from "../helpers/incrementalId"; import { randomArrayItem } from "./randomArrayItem"; -import { randomNumericId } from "./randomNumericId"; -export const randomHandle = () => +/** + * + * @returns a unique social-like handle + * @example "john.doe15" + */ +export const randomHandle = ({ suffix }: { suffix?: string } = {}) => ( randomArrayItem(WESTERN_FIRST_NAMES) + "." + randomArrayItem(WESTERN_LAST_NAMES) - ).toLowerCase() + randomNumericId(); // use randomNumericId too keep handles process-unique + ).toLowerCase() + + incrementalId() + // process-unique + suffix + ? suffix + : ""; diff --git a/src/types/Tuple.ts b/src/types/Tuple.ts new file mode 100644 index 0000000..7e2de20 --- /dev/null +++ b/src/types/Tuple.ts @@ -0,0 +1,27 @@ +type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( + k: infer I +) => void + ? I + : never; + +type LastOf = UnionToIntersection< + T extends any ? () => T : never +> extends () => infer R + ? R + : never; + +type Push = [...T, V]; + +type TuplifyUnion< + T, + L = LastOf, + N = [T] extends [never] ? true : false +> = true extends N ? [] : Push>, L>; + +// The magic happens here! +export type Tuple< + T, + A extends T[] = [] +> = TuplifyUnion["length"] extends A["length"] + ? [...A] + : Tuple;