diff --git a/CHANGELOG.md b/CHANGELOG.md index 210f126..fd060f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # deverything +## 1.1.0 + +### Minor Changes + +- minor fixes and more helpers + ## 1.0.0 ### Major Changes @@ -13,6 +19,7 @@ - randomMaxDate - checkEnvVars is dropped - randomPercentage is dropped + - randomPositivePercentage is dropped ## 0.51.1 diff --git a/README.md b/README.md index 9ce1047..5898de6 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,11 @@ Contributions always welcome! - `arrayDiff()` get the difference of two arrays - `arrayIntersection()` get the intersection of two arrays - `capitalize()` word => Word -- `cleanSpaces()` trims and turns double spaces into single space - `clamp()` clamp number in a range +- `cleanSpaces()` trims and turns double spaces into single space - `enumKeys()` enum FRUIT { APPLE, PEAR } => ["APPLE", "PEAR"] - `enumValues()` enum FRUIT { APPLE = 1, PEAR = 3 } => [1, 3] +- `filterAlphanumeric()` remove non-alphanumeric characters - `first()` get the first element of an array - `firstKey()` get the first key of an object - `firstValue()` get the first value of an object @@ -116,6 +117,7 @@ Contributions always welcome! ### Formatters - `formatCamelCase()` +- `formatCookies()` { cookie1: "1", cookie2: "2" } => "cookie1=1; cookie2=2" - `formatNumber()` 1000 => "1,000" or "1K" or 0.112 => "11.2%" - `formatPercentage()` 0.11 => "11%" - `formatProgress()` => "[2/10]" diff --git a/package.json b/package.json index 25076ae..103737c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "deverything", - "version": "1.0.0", + "version": "1.1.0", "description": "Everything you need for Dev", "main": "./dist/index.js", "module": "./dist/index.mjs", @@ -54,5 +54,6 @@ "ts-node": "^10.9.2", "tsup": "^6.7.0", "typescript": "^4.9.5" - } + }, + "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a" } diff --git a/src/formatters/formatCookies.ts b/src/formatters/formatCookies.ts new file mode 100644 index 0000000..30f065b --- /dev/null +++ b/src/formatters/formatCookies.ts @@ -0,0 +1,12 @@ +import { PlainObject } from "../types/Object"; + +/** + * + * @example formatCookies({}) => "" + * @example formatCookies({ session: "123", _ga: 123 }) => "session=123; _ga=123" + */ +export const formatCookies = (object: PlainObject): string => { + return Object.entries(object) + .map(([key, value]) => `${key}=${value}`) + .join("; "); +}; diff --git a/src/formatters/index.ts b/src/formatters/index.ts index 778759a..2da0b49 100644 --- a/src/formatters/index.ts +++ b/src/formatters/index.ts @@ -1,4 +1,5 @@ export * from "./formatCamelCase"; +export * from "./formatCookies"; export * from "./formatNumber"; export * from "./formatPercentage"; export * from "./formatProgress"; diff --git a/src/helpers/filterAlphanumeric.ts b/src/helpers/filterAlphanumeric.ts new file mode 100644 index 0000000..8d54fba --- /dev/null +++ b/src/helpers/filterAlphanumeric.ts @@ -0,0 +1,7 @@ +/** + * @returns a string with only alphanumeric characters + * @example filterAlphanumeric("!abc()") // returns "abc" + */ +export const filterAlphanumeric = (string: string) => { + return string.replace(/[^a-zA-Z0-9]/g, ""); +}; diff --git a/src/helpers/index.ts b/src/helpers/index.ts index be1c193..c1b724e 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -11,6 +11,7 @@ export * from "./cyclicalItem"; export * from "./dir"; export * from "./enumKeys"; export * from "./enumValues"; +export * from "./filterAlphanumeric"; export * from "./first"; export * from "./firstKey"; export * from "./firstValue"; diff --git a/src/helpers/seriesAll.test.ts b/src/helpers/seriesAll.test.ts index ca12022..a2b8344 100644 --- a/src/helpers/seriesAll.test.ts +++ b/src/helpers/seriesAll.test.ts @@ -3,12 +3,41 @@ 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]); + expect( + await seriesAll([ + Promise.resolve(1), + sleep(1).then(() => 2), + () => Promise.resolve(3), + () => 4, + async () => 5, + async () => { + await sleep(1); + return 6; + }, + async () => { + return sleep(1).then(() => 7); + }, + ]) + ).toStrictEqual([1, 2, 3, 4, 5, 6, 7]); + }); + + test("throw new Error", () => { + expect( + seriesAll([ + () => { + throw new Error("1"); + }, + () => { + throw new Error("2"); + }, + ]) + ).rejects.toThrowError("1"); + }); + + test("Promise.reject", () => { + expect( + seriesAll([Promise.reject("3"), () => Promise.reject("4")]) + ).rejects.toEqual("3"); }); }); diff --git a/src/helpers/seriesAll.ts b/src/helpers/seriesAll.ts index b0c1607..7a1d49b 100644 --- a/src/helpers/seriesAll.ts +++ b/src/helpers/seriesAll.ts @@ -1,17 +1,25 @@ +import { isFunction, isPromise } from "../validators"; + /** * * @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(1), + * sleep(100).then(() => 2), * () => Promise.resolve(3), - * ]); => [1, 2, 3] + * async () => 4, + * ]); => [1, 2, 3, 4] */ -export const seriesAll = async (series: Function[]): Promise => { +export const seriesAll = async ( + series: (Promise | Function)[] +): Promise => { const results: T[] = []; for (const fn of series) { - results.push(await fn()); + if (isPromise(fn)) results.push(await fn); + else if (isFunction(fn)) results.push(await fn()); + // pure value? just return it + else results.push(fn); } return results; }; diff --git a/src/types/Date.ts b/src/types/Date.ts index ea6e726..2f294b9 100644 --- a/src/types/Date.ts +++ b/src/types/Date.ts @@ -1,7 +1,18 @@ export type DateLike = Date | string | number; export type Datey = Date | string; +/** + * @example "2021-01-01T00:00:00.000Z" + */ export type ISODate = string; +/** + * @example "2021-01-01" + */ +export type ISODay = string; +/** + * @example "America/New_York" + */ +export type Timezone = string; export type DateRange = { startDate: DateLike; diff --git a/src/validators/isFunction.ts b/src/validators/isFunction.ts index 3221e2b..f485de5 100644 --- a/src/validators/isFunction.ts +++ b/src/validators/isFunction.ts @@ -1,2 +1,7 @@ -export const isFunction = (arg: any): arg is Function => - Object.prototype.toString.call(arg) === "[object Function]"; +/** + * @returns true if the argument can be called like a function -> fn() or await fn() + */ +export const isFunction = (arg: any): arg is Function => { + const type = Object.prototype.toString.call(arg); + return type === "[object Function]" || type === "[object AsyncFunction]"; +};