├── .eslintignore ├── .prettierignore ├── src ├── index.ts ├── vue │ ├── index.ts │ └── useMousePosition │ │ └── index.ts ├── core │ ├── removeStorage │ │ ├── index.ts │ │ └── test │ │ │ └── removeStorage.spec.ts │ ├── reverseString │ │ ├── index.ts │ │ └── test │ │ │ └── reverseString.spec.ts │ ├── objectToArray │ │ ├── index.ts │ │ └── test │ │ │ └── objectToArray.spec.ts │ ├── upperFirst │ │ ├── index.ts │ │ └── test │ │ │ └── upperFirst.spec.ts │ ├── useSecurityStorage │ │ ├── models │ │ │ └── use-security-storage.models.ts │ │ ├── test │ │ │ └── useSecurityStorage.spec.ts │ │ └── index.ts │ ├── generateArray │ │ ├── index.ts │ │ └── test │ │ │ └── generateArray.spec.ts │ ├── arrayLastItem │ │ ├── index.ts │ │ └── test │ │ │ └── arrayLastItem.spec.ts │ ├── isEmptyObject │ │ ├── index.ts │ │ └── test │ │ │ └── isEmptyObject.spec.ts │ ├── delay │ │ ├── index.ts │ │ └── test │ │ │ └── delay.spec.ts │ ├── generateRandomColor │ │ ├── index.ts │ │ └── test │ │ │ └── generateRandomColor.spec.ts │ ├── getPercentage │ │ ├── index.ts │ │ └── test │ │ │ └── getPercentage.spec.ts │ ├── setStorage │ │ ├── index.ts │ │ └── test │ │ │ └── setStorage.spec.ts │ ├── generateRandomNumber │ │ ├── index.ts │ │ └── test │ │ │ └── generateRandomNumber.spec.ts │ ├── deepClone │ │ ├── index.ts │ │ └── test │ │ │ └── deepClone.spec.ts │ ├── getStorage │ │ ├── index.ts │ │ └── test │ │ │ └── getStorage.spec.ts │ ├── generateNullArray │ │ ├── index.ts │ │ └── test │ │ │ └── generateNullArray.spec.ts │ ├── getNavigatorCurrentLocation │ │ ├── models │ │ │ └── get-navigator-current-location.models.ts │ │ ├── index.ts │ │ └── test │ │ │ └── getNavigatorCurrentLocation.spec.ts │ ├── removeArrayItemByIndex │ │ ├── index.ts │ │ └── test │ │ │ └── removeArrayItemByIndex.spec.ts │ ├── smartLog │ │ ├── test │ │ │ └── smartLog.spec.ts │ │ └── index.ts │ ├── windowNavigateHandler │ │ ├── index.ts │ │ └── test │ │ │ └── windowNavigateHandler.spec.ts │ ├── useRemoveDuplicates │ │ ├── models │ │ │ └── use-remove-duplicates.models.ts │ │ ├── index.ts │ │ └── test │ │ │ └── useRemoveDuplicates.spec.ts │ ├── removeArrayItemByValue │ │ ├── index.ts │ │ └── test │ │ │ └── removeArrayItemByValue.spec.ts │ ├── arrayToObject │ │ ├── index.ts │ │ └── test │ │ │ └── arrayToObject.spec.ts │ ├── shuffleArray │ │ ├── index.ts │ │ └── test │ │ │ └── shuffleArray.spec.ts │ ├── colorLog │ │ ├── models │ │ │ └── color-log.models.ts │ │ ├── test │ │ │ └── colorLog.spec.ts │ │ └── index.ts │ ├── arrayEquals │ │ ├── index.ts │ │ └── test │ │ │ └── arrayEquals.spec.ts │ ├── generateRandomString │ │ ├── test │ │ │ └── generateRandomString.spec.ts │ │ └── index.ts │ ├── mask │ │ ├── test │ │ │ └── mask.spec.ts │ │ └── index.ts │ └── index.ts ├── react │ ├── useNow │ │ ├── test │ │ │ └── useNow.spec.ts │ │ └── index.ts │ ├── useWidth │ │ ├── test │ │ │ └── useWidth.spec.ts │ │ └── index.ts │ ├── useHeight │ │ ├── test │ │ │ └── useHeight.spec.ts │ │ └── index.ts │ ├── useScroll │ │ ├── test │ │ │ └── useScroll.spec.ts │ │ └── index.ts │ ├── useToggle │ │ ├── test │ │ │ └── useToggle.spec.ts │ │ └── index.ts │ ├── index.ts │ ├── useStorage │ │ ├── tests │ │ │ └── useStorage.spec.ts │ │ └── index.ts │ ├── useDebounce │ │ ├── test │ │ │ └── useDebounce.spec.ts │ │ └── index.ts │ └── useMousePosition │ │ └── index.ts └── utils │ ├── index.ts │ └── constants.ts ├── .gitignore ├── commitlint.config.js ├── docs ├── public │ ├── favicon.png │ ├── favicon.svg │ └── og-img.png ├── src │ ├── components │ │ ├── ContributorsCard │ │ │ ├── index.ts │ │ │ ├── models │ │ │ │ └── contributors-card.models.ts │ │ │ └── components │ │ │ │ └── ContributorsCard.vue │ │ └── ContributorsSection │ │ │ ├── index.ts │ │ │ └── components │ │ │ └── ContributorsSection.vue │ └── utils │ │ └── constants.ts ├── parts │ └── installation.md ├── core │ ├── cepMask │ │ └── index.md │ ├── cpfMask │ │ └── index.md │ ├── cpnjMask │ │ └── index.md │ ├── getStorage │ │ └── index.md │ ├── phoneMask │ │ └── index.md │ ├── removeStorage │ │ └── index.md │ ├── reverseString │ │ └── index.md │ ├── generateRandomColor │ │ └── index.md │ ├── isEmptyObject │ │ └── index.md │ ├── upperFirst │ │ └── index.md │ ├── objectToArray │ │ └── index.md │ ├── generateArray │ │ └── index.md │ ├── generateRandomString │ │ └── index.md │ ├── deepClone │ │ └── index.md │ ├── generateNullArray │ │ └── index.md │ ├── arrayLastItem │ │ └── index.md │ ├── generateRandomNumber │ │ └── index.md │ ├── setStorage │ │ └── index.md │ ├── getPercentage │ │ └── index.md │ ├── arrayEquals │ │ └── index.md │ ├── removeArrayItemByValue │ │ └── index.md │ ├── removeArrayItemByIndex │ │ └── index.md │ ├── shuffleArray │ │ └── index.md │ ├── smartLog │ │ └── index.md │ ├── arrayToObject │ │ └── index.md │ ├── delay │ │ └── index.md │ ├── colorLog │ │ └── index.md │ ├── getNavigatorCurrentLocation │ │ └── index.md │ ├── useSecurityStorage │ │ └── index.md │ └── useRemoveDuplicates │ │ └── index.md ├── react │ ├── useNow │ │ └── index.md │ ├── useWidth │ │ └── index.md │ ├── useHeight │ │ └── index.md │ ├── useScroll │ │ └── index.md │ ├── useMousePosition │ │ └── index.md │ ├── useToggle │ │ └── index.md │ ├── useDebounce │ │ └── index.md │ └── useStorage │ │ └── index.md ├── guide │ ├── installation │ │ └── index.md │ └── what-is-essentials-utils │ │ └── index.md ├── vue │ └── useMousePosition │ │ └── index.md ├── .vitepress │ ├── theme │ │ ├── index.ts │ │ └── styles.css │ └── config.mts └── index.md ├── .husky ├── commit-msg └── pre-commit ├── postcss.config.js ├── tailwind.config.js ├── .prettierrc.json ├── .vscode ├── extensions.json └── settings.json ├── tsconfig.json ├── LICENSE ├── .eslintrc.json ├── .github └── workflows │ └── cicd.yml ├── .all-contributorsrc ├── package.json └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./core"; 2 | -------------------------------------------------------------------------------- /src/vue/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useMousePosition"; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /lib 3 | /docs/.vitepress/cache 4 | /docs/.vitepress/dist -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ["@commitlint/config-conventional"] }; 2 | -------------------------------------------------------------------------------- /docs/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesleyara/essentials-utils/HEAD/docs/public/favicon.png -------------------------------------------------------------------------------- /docs/public/favicon.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesleyara/essentials-utils/HEAD/docs/public/favicon.svg -------------------------------------------------------------------------------- /docs/public/og-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesleyara/essentials-utils/HEAD/docs/public/og-img.png -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit ${1} 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/core/removeStorage/index.ts: -------------------------------------------------------------------------------- 1 | export const removeStorage = (key: string) => { 2 | localStorage.removeItem(key); 3 | }; 4 | -------------------------------------------------------------------------------- /docs/src/components/ContributorsCard/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ContributorsCard } from "./components/ContributorsCard.vue"; 2 | -------------------------------------------------------------------------------- /src/core/reverseString/index.ts: -------------------------------------------------------------------------------- 1 | export const reverseString = (str: string) => { 2 | return str.split("").reverse().join(""); 3 | }; 4 | -------------------------------------------------------------------------------- /docs/src/components/ContributorsSection/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ContributorsSection } from "./components/ContributorsSection.vue"; 2 | -------------------------------------------------------------------------------- /src/core/objectToArray/index.ts: -------------------------------------------------------------------------------- 1 | export const objectToArray = (obj: any) => { 2 | return Object.keys(obj).map(key => obj[key]); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/upperFirst/index.ts: -------------------------------------------------------------------------------- 1 | export const upperFirst = (str: string) => { 2 | return str.charAt(0).toUpperCase() + str.slice(1); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/useSecurityStorage/models/use-security-storage.models.ts: -------------------------------------------------------------------------------- 1 | export interface SecurityStorageOptions { 2 | secret: string; 3 | } 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | yarn test:run && yarn build && npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /src/core/generateArray/index.ts: -------------------------------------------------------------------------------- 1 | export const generateArray = (n: number) => { 2 | return Array.from({ length: n }, (_, i) => i + 1); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/arrayLastItem/index.ts: -------------------------------------------------------------------------------- 1 | export const arrayLastItem = (array: TArray[]) => { 2 | return array[array.length - 1]; 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/isEmptyObject/index.ts: -------------------------------------------------------------------------------- 1 | export const isEmptyObject = (obj: TObject) => { 2 | return JSON.stringify(obj) === "{}"; 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/delay/index.ts: -------------------------------------------------------------------------------- 1 | export const delay = (milliseconds: number) => { 2 | return new Promise(resolve => setTimeout(resolve, milliseconds)); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/generateRandomColor/index.ts: -------------------------------------------------------------------------------- 1 | export const generateRandomColor = () => { 2 | return "#" + Math.floor(Math.random() * 16777215).toString(16); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/getPercentage/index.ts: -------------------------------------------------------------------------------- 1 | export const getPercentage = (currentAmount: number, maxAmount: number) => { 2 | return (currentAmount / maxAmount) * 100; 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/setStorage/index.ts: -------------------------------------------------------------------------------- 1 | export const setStorage = (key: string, value: TValue) => { 2 | localStorage.setItem(key, JSON.stringify(value)); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/generateRandomNumber/index.ts: -------------------------------------------------------------------------------- 1 | export const generateRandomNumber = (min: number, max: number) => { 2 | return Math.floor(Math.random() * (max - min) + min); 3 | }; 4 | -------------------------------------------------------------------------------- /src/core/deepClone/index.ts: -------------------------------------------------------------------------------- 1 | export const deepClone = (item: TItem) => { 2 | const clone = JSON.parse(JSON.stringify(item)); 3 | 4 | return clone as TItem; 5 | }; 6 | -------------------------------------------------------------------------------- /src/core/getStorage/index.ts: -------------------------------------------------------------------------------- 1 | export const getStorage = (key: string) => { 2 | const data = localStorage.getItem(key); 3 | 4 | return data ? JSON.parse(data) : undefined; 5 | }; 6 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./docs/**/*.{vue,md,ts}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /docs/src/components/ContributorsCard/models/contributors-card.models.ts: -------------------------------------------------------------------------------- 1 | export interface ContributorCardProps { 2 | src: string; 3 | name: string; 4 | github: string; 5 | showName: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": false, 5 | "printWidth": 80, 6 | "tabWidth": 2, 7 | "endOfLine": "auto", 8 | "arrowParens": "avoid" 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "editorconfig.editorconfig", 6 | "visualstudioexptteam.vscodeintellicode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /src/core/generateNullArray/index.ts: -------------------------------------------------------------------------------- 1 | export const generateNullArray = (quantity: number) => { 2 | const arr: null[] = []; 3 | for (let i = 0; i < quantity; i++) { 4 | arr.push(null); 5 | } 6 | 7 | return arr; 8 | }; 9 | -------------------------------------------------------------------------------- /src/core/getNavigatorCurrentLocation/models/get-navigator-current-location.models.ts: -------------------------------------------------------------------------------- 1 | export interface GetNavigatorCurrentLocationProps { 2 | successCallback: PositionCallback; 3 | errorCallback: PositionErrorCallback; 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.formatOnPaste": true, 4 | "editor.codeActionsOnSave": { 5 | "source.fixAll.eslint": "explicit" 6 | }, 7 | "prettier.configPath": "./.prettierrc.json" 8 | } 9 | -------------------------------------------------------------------------------- /src/core/removeArrayItemByIndex/index.ts: -------------------------------------------------------------------------------- 1 | export const removeArrayItemByIndex = ( 2 | array: TArray[], 3 | index: number, 4 | ) => { 5 | if (index > -1) { 6 | array.splice(index, 1); 7 | } 8 | 9 | return array; 10 | }; 11 | -------------------------------------------------------------------------------- /src/react/useNow/test/useNow.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useNow } from "../"; 4 | 5 | describe("useNow", () => { 6 | it("should be defined", () => { 7 | expect(useNow).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/smartLog/test/smartLog.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { smartLog } from "../"; 4 | 5 | describe("smartLog", () => { 6 | it("should be defined", () => { 7 | expect(smartLog).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/react/useWidth/test/useWidth.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useWidth } from "../"; 4 | 5 | describe("useWidth", () => { 6 | it("should be defined", () => { 7 | expect(useWidth).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/windowNavigateHandler/index.ts: -------------------------------------------------------------------------------- 1 | export const windowNavigateHandler = ( 2 | targetUrl: string, 3 | inNewWindow: boolean, 4 | ) => { 5 | if (inNewWindow) { 6 | open(targetUrl, "_blank"); 7 | } else { 8 | location.href = targetUrl; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/react/useHeight/test/useHeight.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useHeight } from "../"; 4 | 5 | describe("useHeight", () => { 6 | it("should be defined", () => { 7 | expect(useHeight).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/react/useScroll/test/useScroll.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useScroll } from "../"; 4 | 5 | describe("useScroll", () => { 6 | it("should be defined", () => { 7 | expect(useScroll).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/react/useToggle/test/useToggle.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useToggle } from "../"; 4 | 5 | describe("useToggle", () => { 6 | it("should be defined", () => { 7 | expect(useToggle).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/getStorage/test/getStorage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { getStorage } from "../"; 4 | 5 | describe("getStorage", () => { 6 | it("should be defined", () => { 7 | expect(getStorage).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/setStorage/test/setStorage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { setStorage } from "../"; 4 | 5 | describe("setStorage", () => { 6 | it("should be defined", () => { 7 | expect(setStorage).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/react/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useDebounce"; 2 | export * from "./useWidth"; 3 | export * from "./useHeight"; 4 | export * from "./useScroll"; 5 | export * from "./useNow"; 6 | export * from "./useToggle"; 7 | export * from "./useMousePosition"; 8 | export * from "./useStorage"; 9 | -------------------------------------------------------------------------------- /src/react/useStorage/tests/useStorage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useStorage } from "../"; 4 | 5 | describe("useStorage", () => { 6 | it("should be defined", () => { 7 | expect(useStorage).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/react/useDebounce/test/useDebounce.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useDebounce } from "../"; 4 | 5 | describe("useDebounce", () => { 6 | it("should be defined", () => { 7 | expect(useDebounce).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/removeStorage/test/removeStorage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { removeStorage } from "../"; 4 | 5 | describe("removeStorage", () => { 6 | it("should be defined", () => { 7 | expect(removeStorage).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/useRemoveDuplicates/models/use-remove-duplicates.models.ts: -------------------------------------------------------------------------------- 1 | type AnchorKeysType = keyof TArray | (keyof TArray)[]; 2 | 3 | export interface RemoveDuplicatesOptions { 4 | isObject: boolean; 5 | anchorKeys: AnchorKeysType; 6 | counts: boolean; 7 | } 8 | -------------------------------------------------------------------------------- /src/core/removeArrayItemByValue/index.ts: -------------------------------------------------------------------------------- 1 | export const removeArrayItemByValue = ( 2 | array: TArray[], 3 | value: TArray, 4 | ) => { 5 | const index = array.indexOf(value); 6 | if (index > -1) { 7 | array.splice(index, 1); 8 | } 9 | 10 | return array; 11 | }; 12 | -------------------------------------------------------------------------------- /src/core/arrayToObject/index.ts: -------------------------------------------------------------------------------- 1 | export const arrayToObject = ( 2 | array: TArray[], 3 | key: keyof TArray, 4 | ) => { 5 | const obj: Record = {}; 6 | 7 | array.forEach(item => { 8 | obj[item[key] as string] = item; 9 | }); 10 | 11 | return obj; 12 | }; 13 | -------------------------------------------------------------------------------- /src/core/useSecurityStorage/test/useSecurityStorage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useSecurityStorage } from "../"; 4 | 5 | describe("useSecurityStorage", () => { 6 | it("should be defined", () => { 7 | expect(useSecurityStorage).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/core/smartLog/index.ts: -------------------------------------------------------------------------------- 1 | export const smartLog = ( 2 | value: TValue, 3 | currentFunction: Function, 4 | label?: string, 5 | ) => { 6 | return console.log( 7 | `%c[${currentFunction.name}] -`, 8 | "color: red", 9 | label ? `${label}:` : "DEBUG:", 10 | value, 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /src/core/windowNavigateHandler/test/windowNavigateHandler.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { windowNavigateHandler } from "../"; 4 | 5 | describe("windowNavigateHandler", () => { 6 | it("should be defined", () => { 7 | expect(windowNavigateHandler).toBeDefined(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /docs/parts/installation.md: -------------------------------------------------------------------------------- 1 | ::: code-group 2 | 3 | ```bash [npm] 4 | npm install essentials-utils@latest 5 | ``` 6 | 7 | ```bash [yarn] 8 | yarn add essentials-utils@latest 9 | ``` 10 | 11 | ```bash [pnpm] 12 | pnpm add essentials-utils@latest 13 | ``` 14 | 15 | ```bash [bun] 16 | bun add essentials-utils@latest 17 | ``` 18 | 19 | ::: -------------------------------------------------------------------------------- /src/core/shuffleArray/index.ts: -------------------------------------------------------------------------------- 1 | export const shuffleArray = (array: TArray[]) => { 2 | for (let i = array.length - 1; i > 0; i--) { 3 | const j = Math.floor(Math.random() * (i + 1)); 4 | const temp = array[i]; 5 | array[i] = array[j]; 6 | array[j] = temp; 7 | } 8 | 9 | return array; 10 | }; 11 | -------------------------------------------------------------------------------- /src/core/colorLog/models/color-log.models.ts: -------------------------------------------------------------------------------- 1 | type IColors = 2 | | "black" 3 | | "red" 4 | | "green" 5 | | "yellow" 6 | | "blue" 7 | | "magenta" 8 | | "cyan" 9 | | "white"; 10 | 11 | export interface ColorLogOptions { 12 | color: IColors; 13 | bgColor?: IColors; 14 | bold?: boolean; 15 | underline?: boolean; 16 | } 17 | -------------------------------------------------------------------------------- /src/core/arrayEquals/index.ts: -------------------------------------------------------------------------------- 1 | export const arrayEquals = (a: TArray[], b: TArray[]) => { 2 | if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) { 3 | return false; 4 | } 5 | 6 | for (let i = 0; i < a.length; i++) { 7 | if (a[i] !== b[i]) { 8 | return false; 9 | } 10 | } 11 | 12 | return true; 13 | }; 14 | -------------------------------------------------------------------------------- /src/react/useNow/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useNow = () => { 4 | const [now, setNow] = useState(Date.now()); 5 | 6 | useEffect(() => { 7 | const timer = setInterval(() => { 8 | setNow(Date.now()); 9 | }, 1000); 10 | return () => clearInterval(timer); 11 | }, []); 12 | 13 | return now; 14 | }; 15 | -------------------------------------------------------------------------------- /docs/core/cepMask/index.md: -------------------------------------------------------------------------------- 1 | # cepMask 2 | 3 | Mask a CEP number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { cepMask } from "essentials-utils"; 9 | 10 | cepMask("12345678"); // 12345-678 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function cepMask(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/react/useToggle/index.ts: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | export const useToggle = (initialValue: boolean) => { 4 | const [toggleValue, setToggleValue] = useState(initialValue); 5 | 6 | const handleToggleValue = () => { 7 | setToggleValue(state => !state); 8 | }; 9 | 10 | return { 11 | toggleValue, 12 | handleToggleValue, 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "commonjs", 5 | "outDir": "./lib", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "skipLibCheck": true 10 | }, 11 | "include": ["src"], 12 | "exclude": ["node_modules", "lib", "**/*.test.ts", "**/*.spec.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /docs/core/cpfMask/index.md: -------------------------------------------------------------------------------- 1 | # cpfMask 2 | 3 | Mask a CPF number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { cpfMask } from "essentials-utils"; 9 | 10 | cpfMask("12345678900"); // 123.456.789-00 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function cpfMask(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/core/reverseString/test/reverseString.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { reverseString } from "../"; 4 | 5 | describe("reverseString", () => { 6 | it("should be defined", () => { 7 | expect(reverseString).toBeDefined(); 8 | }); 9 | 10 | it("reverse a string.", () => { 11 | expect(reverseString("foo")).toBe("oof"); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/cpnjMask/index.md: -------------------------------------------------------------------------------- 1 | # cnpjMask 2 | 3 | Mask a CNPJ number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { cnpjMask } from "essentials-utils"; 9 | 10 | cnpjMask("12345678900000"); // 12.345.678/9000-00 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function cnpjMask(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/getStorage/index.md: -------------------------------------------------------------------------------- 1 | # getStorage 2 | 3 | Get a value from the local storage. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { getStorage } from "essentials-utils"; 9 | 10 | getStorage("name"); // Wesley 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function getStorage(key: string): any; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/phoneMask/index.md: -------------------------------------------------------------------------------- 1 | ## phoneMask 2 | 3 | Mask a phone number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { phoneMask } from "essentials-utils"; 9 | 10 | phoneMask("1234567890"); // (12) 3456-7890 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function phoneMask(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/removeStorage/index.md: -------------------------------------------------------------------------------- 1 | # removeStorage 2 | 3 | Remove a value from the local storage. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { removeStorage } from "essentials-utils"; 9 | 10 | removeStorage("name"); 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function getStorage(key: string): void; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/core/isEmptyObject/test/isEmptyObject.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { isEmptyObject } from "../"; 4 | 5 | describe("isEmptyObject", () => { 6 | it("should be defined", () => { 7 | expect(isEmptyObject).toBeDefined(); 8 | }); 9 | 10 | it("check if an object is empty.", () => { 11 | expect(isEmptyObject({})).toBe(true); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/core/upperFirst/test/upperFirst.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { upperFirst } from "../"; 4 | 5 | describe("upperFirst", () => { 6 | it("should be defined", () => { 7 | expect(upperFirst).toBeDefined(); 8 | }); 9 | 10 | it("capitalize the first letter of the string.", () => { 11 | expect(upperFirst("foo")).toBe("Foo"); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/core/arrayEquals/test/arrayEquals.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { arrayEquals } from "../"; 4 | 5 | describe("arrayEquals", () => { 6 | it("should be defined", () => { 7 | expect(arrayEquals).toBeDefined(); 8 | }); 9 | 10 | it("check if two arrays are equal.", () => { 11 | expect(arrayEquals([1, 2, 3], [1, 2, 3])).toBe(true); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/core/arrayLastItem/test/arrayLastItem.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { arrayLastItem } from "../"; 4 | 5 | describe("arrayLastItem", () => { 6 | it("should be defined", () => { 7 | expect(arrayLastItem).toBeDefined(); 8 | }); 9 | 10 | it("get the last item of an array.", () => { 11 | expect(arrayLastItem([1, 2, 3])).toBe(3); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/core/getPercentage/test/getPercentage.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { getPercentage } from "../"; 4 | 5 | describe("getPercentage", () => { 6 | it("should be defined", () => { 7 | expect(getPercentage).toBeDefined(); 8 | }); 9 | 10 | it("get the percentage of a number.", () => { 11 | expect(getPercentage(10, 100)).toBe(10); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/reverseString/index.md: -------------------------------------------------------------------------------- 1 | # reverseString 2 | 3 | Reverse a string. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { reverseString } from "essentials-utils"; 9 | 10 | reverseString("Hello world"); // dlrow olleH 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function reverseString(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/react/useNow/index.md: -------------------------------------------------------------------------------- 1 | # useNow 2 | 3 | Get the current time. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useNow } from "essentials-utils/react"; 9 | 10 | // called in a component 11 | const now = useNow(); 12 | console.log(now); 13 | ``` 14 | 15 | ## Type Declarations 16 | 17 | ::: details Show type declarations 18 | 19 | ```ts 20 | export declare function useNow(): number; 21 | ``` 22 | 23 | ::: 24 | -------------------------------------------------------------------------------- /src/core/generateArray/test/generateArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { generateArray } from "../"; 4 | 5 | describe("generateArray", () => { 6 | it("should be defined", () => { 7 | expect(generateArray).toBeDefined(); 8 | }); 9 | 10 | it("generate an array of numbers.", () => { 11 | expect(generateArray(5)).toEqual([1, 2, 3, 4, 5]); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/generateRandomColor/index.md: -------------------------------------------------------------------------------- 1 | # generateRandomColor 2 | 3 | Generate a random color. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { generateRandomColor } from "essentials-utils"; 9 | 10 | generateRandomColor(); // #f2d1a5 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function generateRandomColor(): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { AES, enc } from "crypto-js"; 2 | 3 | export const generateHash = (message: string, secret: string): string => { 4 | const hash = AES.encrypt(message, secret); 5 | return hash.toString(); 6 | }; 7 | 8 | export const decryptHash = (hash: string, secret: string): string => { 9 | const decrypted = AES.decrypt(hash, secret); 10 | 11 | return decrypted.toString(enc.Utf8); 12 | }; 13 | -------------------------------------------------------------------------------- /docs/core/isEmptyObject/index.md: -------------------------------------------------------------------------------- 1 | # isEmptyObject 2 | 3 | Check if an object is empty. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { isEmptyObject } from "essentials-utils"; 9 | 10 | isEmptyObject({}); // true 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function isEmptyObject(obj: TObject): boolean; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/upperFirst/index.md: -------------------------------------------------------------------------------- 1 | # upperFirst 2 | 3 | Capitalize the first letter of the string. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { upperFirst } from "essentials-utils"; 9 | 10 | upperFirst("hello world"); // Hello world 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function upperFirst(value: string): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/objectToArray/index.md: -------------------------------------------------------------------------------- 1 | # objectToArray 2 | 3 | Convert an object to an array. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { objectToArray } from "essentials-utils"; 9 | 10 | objectToArray({ a: 1, b: 2 }); // [{ a: 1 }, { b: 2 }] 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function objectToArray(object: any): any[]; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/react/useWidth/index.md: -------------------------------------------------------------------------------- 1 | # useWidth 2 | 3 | Get the width of the window. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useWidth } from "essentials-utils/react"; 9 | 10 | // called in a component 11 | const width = useWidth(); 12 | console.log(width); 13 | ``` 14 | 15 | ## Type Declarations 16 | 17 | ::: details Show type declarations 18 | 19 | ```ts 20 | export declare function useWidth(): number; 21 | ``` 22 | 23 | ::: 24 | -------------------------------------------------------------------------------- /src/core/generateNullArray/test/generateNullArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { generateNullArray } from "../"; 4 | 5 | describe("generateNullArray", () => { 6 | it("should be defined", () => { 7 | expect(generateNullArray).toBeDefined(); 8 | }); 9 | 10 | it("generate a null array", () => { 11 | expect(generateNullArray(3)).toEqual([null, null, null]); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/generateArray/index.md: -------------------------------------------------------------------------------- 1 | # generateArray 2 | 3 | Generates an array of numbers. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { generateArray } from "essentials-utils"; 9 | 10 | generateArray(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function generateArray(length: number): number[]; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /docs/core/generateRandomString/index.md: -------------------------------------------------------------------------------- 1 | # generateRandomString 2 | 3 | Generate a random string. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { generateRandomString } from "essentials-utils"; 9 | 10 | generateRandomString(5); // 5f2d1 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function generateRandomString(length: number): string; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/core/generateRandomColor/test/generateRandomColor.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { generateRandomColor } from "../"; 4 | 5 | describe("generateRandomColor", () => { 6 | it("should be defined", () => { 7 | expect(generateRandomColor).toBeDefined(); 8 | }); 9 | 10 | it("generate a random color", () => { 11 | expect(generateRandomColor()).toBeTypeOf("string"); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/deepClone/index.md: -------------------------------------------------------------------------------- 1 | # deepClone 2 | 3 | Clone an item. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { deepClone } from "essentials-utils"; 9 | 10 | const obj = { a: 1, b: 2 }; 11 | const obj2 = deepClone(obj); // { a: 1, b: 2 } 12 | ``` 13 | 14 | ## Type Declarations 15 | 16 | ::: details Show type declarations 17 | 18 | ```ts 19 | export declare function deepClone(item: TItem): TItem; 20 | ``` 21 | 22 | ::: 23 | -------------------------------------------------------------------------------- /docs/core/generateNullArray/index.md: -------------------------------------------------------------------------------- 1 | # generateNullArray 2 | 3 | Generate an array with null values. 4 | 5 | ```js 6 | import { generateNullArray } from "essentials-utils"; 7 | 8 | generateNullArray(5); // [null, null, null, null, null] 9 | ``` 10 | 11 | ## Type Declarations 12 | 13 | ::: details Show type declarations 14 | 15 | ```ts 16 | export declare function generateNullArray(quantity: number): null[]; 17 | ``` 18 | 19 | ::: 20 | -------------------------------------------------------------------------------- /docs/react/useHeight/index.md: -------------------------------------------------------------------------------- 1 | # useHeight 2 | 3 | Get the height of the window. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useHeight } from "essentials-utils/react"; 9 | 10 | // called in a component 11 | const height = useHeight(); 12 | console.log(height); 13 | ``` 14 | 15 | ## Type Declarations 16 | 17 | ::: details Show type declarations 18 | 19 | ```ts 20 | export declare function useHeight(): number; 21 | ``` 22 | 23 | ::: 24 | -------------------------------------------------------------------------------- /docs/core/arrayLastItem/index.md: -------------------------------------------------------------------------------- 1 | # arrayLastItem 2 | 3 | Get the last item of an array. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { arrayLastItem } from "essentials-utils"; 9 | 10 | arrayLastItem([1, 2, 3]); // 3 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function arrayLastItem( 19 | array: TArray[], 20 | ): TArray; 21 | ``` 22 | 23 | ::: 24 | -------------------------------------------------------------------------------- /docs/core/generateRandomNumber/index.md: -------------------------------------------------------------------------------- 1 | # generateRandomNumber 2 | 3 | Generate a random number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { generateRandomNumber } from "essentials-utils"; 9 | 10 | generateRandomNumber(1, 10); // 5 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function generateRandomNumber(min: number, max: number): number; 19 | ``` 20 | 21 | ::: 22 | -------------------------------------------------------------------------------- /src/core/generateRandomString/test/generateRandomString.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { generateRandomString } from "../"; 4 | 5 | describe("generateRandomString", () => { 6 | it("should be defined", () => { 7 | expect(generateRandomString).toBeDefined(); 8 | }); 9 | 10 | it("generate a random string", () => { 11 | expect(generateRandomString(10)).toBeTypeOf("string"); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/core/setStorage/index.md: -------------------------------------------------------------------------------- 1 | # setStorage 2 | 3 | Set a value in the local storage. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { setStorage } from "essentials-utils"; 9 | 10 | setStorage("name", "Wesley"); 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function setStorage( 19 | key: string, 20 | value: TValue, 21 | ): void; 22 | ``` 23 | 24 | ::: 25 | -------------------------------------------------------------------------------- /docs/react/useScroll/index.md: -------------------------------------------------------------------------------- 1 | # useScroll 2 | 3 | Get the scroll position of the window. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useScroll } from "essentials-utils/react"; 9 | 10 | // called in a component 11 | const scroll = useScroll(); 12 | console.log(scroll); 13 | ``` 14 | 15 | ## Type Declarations 16 | 17 | ::: details Show type declarations 18 | 19 | ```ts 20 | export declare function useScroll(): number; 21 | ``` 22 | 23 | ::: 24 | -------------------------------------------------------------------------------- /docs/core/getPercentage/index.md: -------------------------------------------------------------------------------- 1 | # getPercentage 2 | 3 | Get the percentage of a number. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { getPercentage } from "essentials-utils"; 9 | 10 | getPercentage(10, 100); // 10 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function getPercentage( 19 | currentAmount: number, 20 | maxAmount: number, 21 | ): number; 22 | ``` 23 | 24 | ::: 25 | -------------------------------------------------------------------------------- /src/core/removeArrayItemByValue/test/removeArrayItemByValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { removeArrayItemByValue } from "../"; 4 | 5 | describe("removeArrayItemByValue", () => { 6 | it("should be defined", () => { 7 | expect(removeArrayItemByValue).toBeDefined(); 8 | }); 9 | 10 | it("remove an item from an array.", () => { 11 | expect(removeArrayItemByValue([1, 2, 3], 2)).toEqual([1, 3]); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/react/useWidth/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useWidth = () => { 4 | const [width, setWidth] = useState(0); 5 | 6 | const handleResize = () => setWidth(window.innerWidth); 7 | 8 | useEffect(() => { 9 | setWidth(window.innerWidth); 10 | window.addEventListener("resize", handleResize); 11 | return () => window.removeEventListener("resize", handleResize); 12 | }, []); 13 | 14 | return width; 15 | }; 16 | -------------------------------------------------------------------------------- /docs/core/arrayEquals/index.md: -------------------------------------------------------------------------------- 1 | # arrayEquals 2 | 3 | Check if two arrays are equal. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { arrayEquals } from "essentials-utils"; 9 | 10 | arrayEquals([1, 2, 3], [1, 2, 3]); // true 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function arrayEquals( 19 | array1: TArray[], 20 | array2: TArray[], 21 | ): boolean; 22 | ``` 23 | 24 | ::: 25 | -------------------------------------------------------------------------------- /src/core/removeArrayItemByIndex/test/removeArrayItemByIndex.spec.ts: -------------------------------------------------------------------------------- 1 | import { removeArrayItemByIndex } from ".."; 2 | 3 | import { describe, it, expect } from "vitest"; 4 | 5 | describe("removeArrayItemByIndex", () => { 6 | it("should be defined", () => { 7 | expect(removeArrayItemByIndex).toBeDefined(); 8 | }); 9 | 10 | it("remove an item from an array by index.", () => { 11 | expect(removeArrayItemByIndex([1, 2, 3], 1)).toEqual([1, 3]); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/core/delay/test/delay.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { delay } from "../"; 4 | 5 | describe("delay", () => { 6 | it("should be defined", () => { 7 | expect(delay).toBeDefined(); 8 | }); 9 | 10 | it("delay the execution of a function.", async () => { 11 | const start = Date.now(); 12 | await delay(1000); 13 | const end = Date.now(); 14 | expect(end - start).toBeGreaterThanOrEqual(1000); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/react/useHeight/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useHeight = () => { 4 | const [height, setHeight] = useState(0); 5 | 6 | const handleResize = () => setHeight(window.innerHeight); 7 | 8 | useEffect(() => { 9 | setHeight(window.innerHeight); 10 | window.addEventListener("resize", handleResize); 11 | return () => window.removeEventListener("resize", handleResize); 12 | }, []); 13 | 14 | return height; 15 | }; 16 | -------------------------------------------------------------------------------- /src/core/deepClone/test/deepClone.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { deepClone } from "../"; 4 | 5 | describe("deepClone", () => { 6 | it("should be defined", () => { 7 | expect(deepClone).toBeDefined(); 8 | }); 9 | 10 | it("deep clone", () => { 11 | const obj = { a: 1, b: { c: 2 } }; 12 | const clonedObj = deepClone(obj); 13 | 14 | expect(clonedObj).toEqual(obj); 15 | expect(clonedObj).not.toBe(obj); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/core/shuffleArray/test/shuffleArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { shuffleArray } from "../"; 4 | 5 | describe("shuffleArray", () => { 6 | it("should be defined", () => { 7 | expect(shuffleArray).toBeDefined(); 8 | }); 9 | 10 | it("randomly sorting arrays.", () => { 11 | const arr1 = [1, 2, 3, 4, 5]; 12 | const arr2 = shuffleArray(arr1); 13 | expect(arr1.some(item => arr2.includes(item))).toBe(true); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /docs/react/useMousePosition/index.md: -------------------------------------------------------------------------------- 1 | # useMousePosition 2 | 3 | Get the current mouse position. 4 | 5 | ```jsx 6 | import { useMousePosition } from "essentials-utils/react"; 7 | 8 | // called in a component 9 | const { x, y } = useMousePosition(); 10 | 11 | console.log(x, y); 12 | ``` 13 | 14 | ## Type Declarations 15 | 16 | ::: details Show type declarations 17 | 18 | ```ts 19 | export declare function useMousePosition(): { 20 | x: number; 21 | y: number; 22 | }; 23 | ``` 24 | 25 | ::: 26 | -------------------------------------------------------------------------------- /src/core/generateRandomString/index.ts: -------------------------------------------------------------------------------- 1 | export const generateRandomString = (length: number) => { 2 | const charactersWithSymbols = 3 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"; 4 | let result = ""; 5 | const charactersLength = charactersWithSymbols.length; 6 | 7 | for (let i = 0; i < length; i++) { 8 | result += charactersWithSymbols.charAt( 9 | Math.floor(Math.random() * charactersLength), 10 | ); 11 | } 12 | 13 | return result; 14 | }; 15 | -------------------------------------------------------------------------------- /src/react/useDebounce/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useDebounce = (value: TValue, delay: number) => { 4 | const [debouncedValue, setDebouncedValue] = useState(value); 5 | 6 | useEffect(() => { 7 | const handler = setTimeout(() => { 8 | setDebouncedValue(value); 9 | }, delay); 10 | 11 | return () => { 12 | clearTimeout(handler); 13 | }; 14 | }, [value, delay]); 15 | 16 | return debouncedValue; 17 | }; 18 | -------------------------------------------------------------------------------- /docs/guide/installation/index.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Install the package using your package manager of choice: 4 | 5 | 6 | 7 | The package works in different environments, however in some cases it is necessary to differentiate the functions that will be used, as we cannot always make use of them due to syntax differences between the libs/frameworks. 8 | 9 | - **Core** - Functions that work in any environment. 10 | - **React** - Functions that work in React environment. -------------------------------------------------------------------------------- /docs/core/removeArrayItemByValue/index.md: -------------------------------------------------------------------------------- 1 | # removeArrayItemByValue 2 | 3 | Remove an item from an array. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { removeArrayItemByValue } from "essentials-utils"; 9 | 10 | removeArrayItemByValue([1, 2, 3], 2); // [1, 3] 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function removeArrayItemByValue( 19 | array: TArray[], 20 | value: TArray, 21 | ): TArray[]; 22 | ``` 23 | 24 | ::: 25 | -------------------------------------------------------------------------------- /src/core/colorLog/test/colorLog.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, vi } from "vitest"; 2 | 3 | import { colorLog } from "../"; 4 | 5 | describe("colorLog", () => { 6 | it("should be defined", () => { 7 | expect(colorLog).toBeDefined(); 8 | }); 9 | 10 | it("color log", () => { 11 | const mockLog = vi.fn(); 12 | global.console.log = mockLog; 13 | 14 | mockLog(colorLog("foo", { color: "red" })); 15 | 16 | expect(mockLog).toHaveBeenCalledWith("\x1b[31mfoo\x1b[0m"); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/core/getNavigatorCurrentLocation/index.ts: -------------------------------------------------------------------------------- 1 | import { GetNavigatorCurrentLocationProps } from "./models/get-navigator-current-location.models"; 2 | 3 | export const getNavigatorCurrentLocation = async ({ 4 | successCallback, 5 | errorCallback, 6 | }: GetNavigatorCurrentLocationProps) => { 7 | const { coords, timestamp }: GeolocationPosition = await new Promise(() => { 8 | navigator.geolocation.getCurrentPosition(successCallback, errorCallback); 9 | }); 10 | 11 | return { coords, timestamp }; 12 | }; 13 | -------------------------------------------------------------------------------- /docs/vue/useMousePosition/index.md: -------------------------------------------------------------------------------- 1 | # useMousePosition 2 | 3 | Get the current mouse position. 4 | 5 | ```jsx 6 | import { useMousePosition } from "essentials-utils/vue"; 7 | 8 | // called in a component 9 | const { x, y } = useMousePosition(); 10 | 11 | console.log(x, y); 12 | ``` 13 | 14 | ## Type Declarations 15 | 16 | ::: details Show type declarations 17 | 18 | ```ts 19 | export declare function useMousePosition() { 20 | x: Ref; 21 | y: Ref; 22 | } 23 | ``` 24 | 25 | ::: 26 | -------------------------------------------------------------------------------- /src/core/generateRandomNumber/test/generateRandomNumber.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { generateRandomNumber } from "../"; 4 | 5 | describe("generateRandomNumber", () => { 6 | it("should be defined", () => { 7 | expect(generateRandomNumber).toBeDefined(); 8 | }); 9 | 10 | it("generate a random number.", () => { 11 | expect(generateRandomNumber(1, 10)).toBeGreaterThanOrEqual(1); 12 | expect(generateRandomNumber(1, 10)).toBeLessThanOrEqual(10); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /docs/core/removeArrayItemByIndex/index.md: -------------------------------------------------------------------------------- 1 | # removeArrayItemByIndex 2 | 3 | Remove an item from an array by index. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { removeArrayItemByIndex } from "essentials-utils"; 9 | 10 | removeArrayItemByIndex([1, 2, 3], 1); // [1, 3] 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export declare function removeArrayItemByIndex( 19 | array: TArray[], 20 | index: number, 21 | ): TArray[]; 22 | ``` 23 | 24 | ::: 25 | -------------------------------------------------------------------------------- /docs/core/shuffleArray/index.md: -------------------------------------------------------------------------------- 1 | # shuffleArray 2 | 3 | random array method 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { shuffleArray } from "essentials-utils"; 9 | 10 | // called in a component 11 | const arr1 = [1, 2, 3, 4, 5]; 12 | const arr2 = shuffleArray(arr1); 13 | console.log("arr2", arr2); 14 | ``` 15 | 16 | ## Type Declarations 17 | 18 | ::: details Show type declarations 19 | 20 | ```ts 21 | export declare function shuffleArray( 22 | array: TArray[], 23 | ): TArray[]; 24 | ``` 25 | 26 | ::: 27 | -------------------------------------------------------------------------------- /docs/core/smartLog/index.md: -------------------------------------------------------------------------------- 1 | # smartLog 2 | 3 | Log a message in the console. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { smartLog } from "essentials-utils"; 9 | 10 | const App = () => { 11 | smartLog("Hello world", App); // [App] - DEBUG: Hello world 12 | }; 13 | ``` 14 | 15 | ## Type Declarations 16 | 17 | ::: details Show type declarations 18 | 19 | ```ts 20 | export declare function smartLog( 21 | value: TValue, 22 | currentFunction: Function, 23 | label?: string, 24 | ): void; 25 | ``` 26 | 27 | ::: 28 | -------------------------------------------------------------------------------- /src/vue/useMousePosition/index.ts: -------------------------------------------------------------------------------- 1 | import { ref, onMounted, onUnmounted } from "vue"; 2 | 3 | export const useMousePosition = () => { 4 | const x = ref(0); 5 | const y = ref(0); 6 | 7 | const updateMouse = (e: MouseEvent) => { 8 | x.value = e.pageX; 9 | y.value = e.pageY; 10 | }; 11 | 12 | onMounted(() => { 13 | window.addEventListener("mousemove", updateMouse); 14 | }); 15 | 16 | onUnmounted(() => { 17 | window.removeEventListener("mousemove", updateMouse); 18 | }); 19 | 20 | return { x, y }; 21 | }; 22 | -------------------------------------------------------------------------------- /src/react/useMousePosition/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useMousePosition = () => { 4 | const [x, setX] = useState(0); 5 | const [y, setY] = useState(0); 6 | 7 | const updateMouse = (e: MouseEvent) => { 8 | setX(e.pageX); 9 | setY(e.pageY); 10 | }; 11 | 12 | useEffect(() => { 13 | window.addEventListener("mousemove", updateMouse); 14 | 15 | return () => { 16 | window.removeEventListener("mousemove", updateMouse); 17 | }; 18 | }); 19 | 20 | return { x, y }; 21 | }; 22 | -------------------------------------------------------------------------------- /src/react/useScroll/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useScroll = () => { 4 | const [scroll, setScroll] = useState(0); 5 | 6 | const handleScroll = () => setScroll(window.pageYOffset); 7 | 8 | useEffect(() => { 9 | setScroll(window.pageYOffset); 10 | window.removeEventListener("scroll", handleScroll); 11 | window.addEventListener("scroll", handleScroll, { passive: true }); 12 | return () => window.removeEventListener("scroll", handleScroll); 13 | }, []); 14 | 15 | return scroll; 16 | }; 17 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import { h } from 'vue' 3 | import type { Theme } from 'vitepress' 4 | import DefaultTheme from 'vitepress/theme' 5 | import './styles.css' 6 | import 'virtual:group-icons.css' 7 | 8 | export default { 9 | extends: DefaultTheme, 10 | Layout: () => { 11 | return h(DefaultTheme.Layout, null, { 12 | // https://vitepress.dev/guide/extending-default-theme#layout-slots 13 | }) 14 | }, 15 | enhanceApp({ app, router, siteData }) { 16 | // ... 17 | } 18 | } satisfies Theme 19 | -------------------------------------------------------------------------------- /src/core/objectToArray/test/objectToArray.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { objectToArray } from "../"; 4 | 5 | describe("objectToArray", () => { 6 | it("should be defined", () => { 7 | expect(objectToArray).toBeDefined(); 8 | }); 9 | 10 | it("convert an object to an array.", () => { 11 | expect( 12 | objectToArray({ 13 | 1: { id: 1, name: "a" }, 14 | 2: { id: 2, name: "b" }, 15 | }), 16 | ).toEqual([ 17 | { id: 1, name: "a" }, 18 | { id: 2, name: "b" }, 19 | ]); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /docs/core/arrayToObject/index.md: -------------------------------------------------------------------------------- 1 | # arrayToObject 2 | 3 | Convert an array to an object. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { arrayToObject } from "essentials-utils"; 9 | 10 | arrayToObject( 11 | [ 12 | { id: 1, name: "a" }, 13 | { id: 2, name: "b" }, 14 | ], 15 | "id", 16 | ); // { 1: { id: 1, name: "a" }, 2: { id: 2, name: "b" } } 17 | ``` 18 | 19 | ## Type Declarations 20 | 21 | ::: details Show type declarations 22 | 23 | ```ts 24 | export declare function arrayToObject( 25 | array: TArray[], 26 | key: string, 27 | ): Record; 28 | ``` 29 | 30 | ::: 31 | -------------------------------------------------------------------------------- /docs/guide/what-is-essentials-utils/index.md: -------------------------------------------------------------------------------- 1 | # What is Essentials utils? 2 | 3 | Essentials utils is a collection of functions to make your life easier. It is a collection of functions that work in any environment, however in some cases it is necessary to differentiate the functions that will be used, as we cannot always make use of them due to syntax differences between the libs/frameworks. 4 | 5 |
6 | 7 | Do you want to contribute to the project? Check out the [GitHub repository](https://github.com/wesleyara/essentials-utils) and make your contribution. 8 | 9 |
-------------------------------------------------------------------------------- /docs/react/useToggle/index.md: -------------------------------------------------------------------------------- 1 | # useToggle 2 | 3 | Toggle a boolean. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useToggle } from "essentials-utils/react"; 9 | 10 | // called in a component 11 | const { toggleValue, handleToggleValue } = useToggle(); 12 | 13 | console.log(toggleValue); // false 14 | handleToggleValue(); 15 | console.log(toggleValue); // true 16 | ``` 17 | 18 | ## Type Declarations 19 | 20 | ::: details Show type declarations 21 | 22 | ```ts 23 | export declare function useToggle(initialValue: boolean): { 24 | toggleValue: boolean; 25 | handleToggleValue: () => void; 26 | }; 27 | ``` 28 | 29 | ::: 30 | -------------------------------------------------------------------------------- /src/core/arrayToObject/test/arrayToObject.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { arrayToObject } from "../"; 4 | 5 | describe("arrayToObject", () => { 6 | it("should be defined", () => { 7 | expect(arrayToObject).toBeDefined(); 8 | }); 9 | 10 | it("convert an array to an object.", () => { 11 | expect( 12 | arrayToObject( 13 | [ 14 | { id: 1, name: "a" }, 15 | { id: 2, name: "b" }, 16 | ], 17 | "id", 18 | ), 19 | ).toEqual({ 20 | 1: { id: 1, name: "a" }, 21 | 2: { id: 2, name: "b" }, 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /docs/core/delay/index.md: -------------------------------------------------------------------------------- 1 | # delay 2 | 3 | Delay the execution of a function. 4 | 5 | ## Usage 6 | 7 | ### Using then/catch 8 | 9 | ```js 10 | import { delay } from "essentials-utils"; 11 | 12 | delay(1000).then(() => console.log("Hello world")); 13 | ``` 14 | 15 | ### Using async/await 16 | 17 | ```js 18 | import { delay } from "essentials-utils"; 19 | 20 | async function main() { 21 | await delay(1000); 22 | console.log("Hello world"); 23 | } 24 | ``` 25 | 26 | ## Type Declarations 27 | 28 | ::: details Show type declarations 29 | 30 | ```ts 31 | export declare function delay(ms: number): Promise; 32 | ``` 33 | 34 | ::: 35 | -------------------------------------------------------------------------------- /docs/react/useDebounce/index.md: -------------------------------------------------------------------------------- 1 | # useDebounce 2 | 3 | Debounce hook is used to minimize backend requests on inputs. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useDebounce } from "essentials-utils/react"; 9 | 10 | const [value, setValue] = useState(""); 11 | const debouncedValue = useDebounce(value, 1000); 12 | 13 | useEffect(() => { 14 | console.log(debouncedValue); 15 | }, [debouncedValue]); 16 | ``` 17 | 18 | ## Type Declarations 19 | 20 | ::: details Show type declarations 21 | 22 | ```ts 23 | export declare function useDebounce( 24 | value: TValue, 25 | delay: number, 26 | ): T; 27 | ``` 28 | 29 | ::: 30 | -------------------------------------------------------------------------------- /src/core/colorLog/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | backgroundColors, 3 | bright, 4 | fontColors, 5 | reset, 6 | underscore, 7 | } from "../../utils/constants"; 8 | import { ColorLogOptions } from "./models/color-log.models"; 9 | 10 | export const colorLog = (str: string, options: ColorLogOptions) => { 11 | const { color, bgColor, bold, underline } = options; 12 | 13 | let result = ""; 14 | if (color) { 15 | result += fontColors[color]; 16 | } 17 | if (bgColor) { 18 | result += backgroundColors[bgColor]; 19 | } 20 | if (bold) { 21 | result += bright; 22 | } 23 | if (underline) { 24 | result += underscore; 25 | } 26 | 27 | return `${result}${str}${reset}`; 28 | }; 29 | -------------------------------------------------------------------------------- /docs/src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const contributors = [ 2 | { 3 | name: "Patryck Silva", 4 | image: "https://avatars.githubusercontent.com/u/41785386?v=4", 5 | github: "https://github.com/PatryckSilva", 6 | }, 7 | { 8 | name: "João Ianuci", 9 | image: "https://avatars.githubusercontent.com/u/42063789?v=4", 10 | github: "https://github.com/joaoianuci", 11 | }, 12 | { 13 | name: "Guilherme Felipe", 14 | image: "https://avatars.githubusercontent.com/u/62507710?v=4", 15 | github: "https://github.com/Glerme", 16 | }, 17 | { 18 | name: "Heron Amaral", 19 | image: "https://avatars.githubusercontent.com/u/71283373?v=4", 20 | github: "https://github.com/heronoa", 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /docs/src/components/ContributorsCard/components/ContributorsCard.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /docs/core/colorLog/index.md: -------------------------------------------------------------------------------- 1 | # colorLog 2 | 3 | Log a message in the console with color. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { colorLog } from "essentials-utils"; 9 | 10 | console.log(colorLog("Hello world", { color: "red" })); 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | type IColors = 19 | | "black" 20 | | "red" 21 | | "green" 22 | | "yellow" 23 | | "blue" 24 | | "magenta" 25 | | "cyan" 26 | | "white"; 27 | 28 | export interface ColorLogOptions { 29 | color: IColors; 30 | bgColor?: IColors; 31 | bold?: boolean; 32 | underline?: boolean; 33 | } 34 | 35 | export declare function colorLog(str: string, options: ColorLogOptions): string; 36 | ``` 37 | 38 | ::: 39 | -------------------------------------------------------------------------------- /docs/core/getNavigatorCurrentLocation/index.md: -------------------------------------------------------------------------------- 1 | # getNavigatorCurrentLocation 2 | 3 | Get the current location of the navigator. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { getNavigatorCurrentLocation } from "essentials-utils"; 9 | 10 | getNavigatorCurrentLocation().then(location => console.log(location)); 11 | ``` 12 | 13 | ## Type Declarations 14 | 15 | ::: details Show type declarations 16 | 17 | ```ts 18 | export interface GetNavigatorCurrentLocationProps { 19 | successCallback: PositionCallback; 20 | errorCallback: PositionErrorCallback; 21 | } 22 | 23 | export declare function getNavigatorCurrentLocation({ 24 | successCallback, 25 | errorCallback, 26 | }: GetNavigatorCurrentLocationProps): Promise<{ 27 | coords: GeolocationCoordinates; 28 | timestamp: number; 29 | }>; 30 | ``` 31 | 32 | ::: 33 | -------------------------------------------------------------------------------- /src/core/mask/test/mask.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { cepMask, cnpjMask, cpfMask, phoneMask } from "../"; 4 | 5 | describe("mask", () => { 6 | it("should be defined", () => { 7 | expect(cepMask).toBeDefined(); 8 | expect(cnpjMask).toBeDefined(); 9 | expect(cpfMask).toBeDefined(); 10 | expect(phoneMask).toBeDefined(); 11 | }); 12 | 13 | it("phone mask", () => { 14 | expect(phoneMask("11999999999")).toBe("(11) 99999-9999"); 15 | }); 16 | 17 | it("cpf mask", () => { 18 | expect(cpfMask("99999999999")).toBe("999.999.999-99"); 19 | }); 20 | 21 | it("cnpj mask", () => { 22 | expect(cnpjMask("99999999999999")).toBe("99.999.999/9999-99"); 23 | }); 24 | 25 | it("cep mask", () => { 26 | expect(cepMask("99999999")).toBe("99999-999"); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/core/useSecurityStorage/index.ts: -------------------------------------------------------------------------------- 1 | import { decryptHash, generateHash } from "../../utils"; 2 | import { SecurityStorageOptions } from "./models/use-security-storage.models"; 3 | 4 | export const useSecurityStorage = ( 5 | options: SecurityStorageOptions, 6 | ) => { 7 | const { secret } = options; 8 | 9 | const setStorage = (key: string, value: TValue) => { 10 | const valueHash = generateHash(JSON.stringify(value), secret); 11 | 12 | localStorage.setItem(key, valueHash); 13 | }; 14 | 15 | const getStorage = (key: string) => { 16 | const valueHash = localStorage.getItem(key) || ""; 17 | 18 | const value = decryptHash(valueHash, secret); 19 | 20 | return value; 21 | }; 22 | 23 | const removeStorage = (key: string) => { 24 | localStorage.removeItem(key); 25 | }; 26 | 27 | return { 28 | setStorage, 29 | getStorage, 30 | removeStorage, 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /docs/react/useStorage/index.md: -------------------------------------------------------------------------------- 1 | # useStorage 2 | 3 | `useStorage` is a React hook that allows you to store a value in the browser's local storage. This hook is useful when you want to persist a value across page reloads and multi tabs synchronization. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useStorage } from "essentials-utils/react"; 9 | 10 | const App = () => { 11 | const [count, setCount] = useStorage("count", 0); 12 | 13 | return ( 14 |
15 | 16 | 17 |

{count}

18 |
19 | ); 20 | }; 21 | ``` 22 | 23 | ## Type Declarations 24 | 25 | ::: details Show type declarations 26 | 27 | ```ts 28 | export declare function useStorage( 29 | key: string, 30 | delay: TValue, 31 | ): readonly [TValue, React.Dispatch>]; 32 | ``` 33 | 34 | ::: 35 | -------------------------------------------------------------------------------- /docs/src/components/ContributorsSection/components/ContributorsSection.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /src/core/mask/index.ts: -------------------------------------------------------------------------------- 1 | export const phoneMask = (value: string) => { 2 | return value 3 | .replace(/\D/g, "") 4 | .replace(/(\d{2})(\d)/, "($1) $2") 5 | .replace(/(\d{5})(\d)/, "$1-$2") 6 | .replace(/(-\d{4})\d+?$/, "$1"); 7 | }; 8 | 9 | export const cpfMask = (value: string) => { 10 | return value 11 | .replace(/\D/g, "") 12 | .replace(/(\d{3})(\d)/, "$1.$2") 13 | .replace(/(\d{3})(\d)/, "$1.$2") 14 | .replace(/(\d{3})(\d)/, "$1-$2") 15 | .replace(/(-\d{2})\d+?$/, "$1"); 16 | }; 17 | 18 | export const cnpjMask = (value: string) => { 19 | return value 20 | .replace(/\D/g, "") 21 | .replace(/(\d{2})(\d)/, "$1.$2") 22 | .replace(/(\d{3})(\d)/, "$1.$2") 23 | .replace(/(\d{3})(\d)/, "$1/$2") 24 | .replace(/(\d{4})(\d)/, "$1-$2") 25 | .replace(/(-\d{2})\d+?$/, "$1"); 26 | }; 27 | 28 | export const cepMask = (value: string) => { 29 | if (value.length > 9) { 30 | return value.slice(0, 9); 31 | } 32 | 33 | return value.replace(/\D/g, "").replace(/(\d{5})(\d)/, "$1-$2"); 34 | }; 35 | -------------------------------------------------------------------------------- /src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./arrayEquals"; 2 | export * from "./arrayLastItem"; 3 | export * from "./arrayToObject"; 4 | export * from "./colorLog"; 5 | export * from "./deepClone"; 6 | export * from "./delay"; 7 | export * from "./generateArray"; 8 | export * from "./generateNullArray"; 9 | export * from "./generateRandomColor"; 10 | export * from "./generateRandomNumber"; 11 | export * from "./generateRandomString"; 12 | export * from "./getNavigatorCurrentLocation"; 13 | export * from "./getPercentage"; 14 | export * from "./getStorage"; 15 | export * from "./isEmptyObject"; 16 | export * from "./mask"; 17 | export * from "./objectToArray"; 18 | export * from "./removeArrayItemByIndex"; 19 | export * from "./removeArrayItemByValue"; 20 | export * from "./removeStorage"; 21 | export * from "./reverseString"; 22 | export * from "./setStorage"; 23 | export * from "./shuffleArray"; 24 | export * from "./smartLog"; 25 | export * from "./upperFirst"; 26 | export * from "./useRemoveDuplicates"; 27 | export * from "./useSecurityStorage"; 28 | export * from "./windowNavigateHandler"; 29 | -------------------------------------------------------------------------------- /docs/core/useSecurityStorage/index.md: -------------------------------------------------------------------------------- 1 | # useSecurityStorage 2 | 3 | Save data in the local storage with encryption. 4 | 5 | ## Usage 6 | 7 | ```js 8 | import { useSecurityStorage } from "essentials-utils"; 9 | 10 | const { setStorage, getStorage, removeStorage } = useSecurityStorage({ 11 | secret: import.meta.env.VITE_SECRET, 12 | }); 13 | ``` 14 | 15 | ### Save data 16 | 17 | ```js 18 | setStorage("key", "value"); 19 | ``` 20 | 21 | ### Get data 22 | 23 | ```js 24 | const data = getStorage("key"); 25 | 26 | console.log(data); // value 27 | ``` 28 | 29 | ### Remove data 30 | 31 | ```js 32 | removeStorage("key"); 33 | ``` 34 | 35 | ## Type Declarations 36 | 37 | ::: details Show type declarations 38 | 39 | ```ts 40 | interface SecurityStorageOptions { 41 | secret: string; 42 | } 43 | 44 | export declare function useSecurityStorage( 45 | options: SecurityStorageOptions, 46 | ): { 47 | setStorage: (key: string, value: TValue) => void; 48 | getStorage: (key: string) => TValue | null; 49 | removeStorage: (key: string) => void; 50 | }; 51 | ``` 52 | 53 | ::: 54 | -------------------------------------------------------------------------------- /src/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const reset = "\x1b[0m"; 2 | export const bright = "\x1b[1m"; 3 | export const underscore = "\x1b[4m"; 4 | 5 | const fgBlack = "\x1b[30m"; 6 | const fgRed = "\x1b[31m"; 7 | const fgGreen = "\x1b[32m"; 8 | const fgYellow = "\x1b[33m"; 9 | const fgBlue = "\x1b[34m"; 10 | const fgMagenta = "\x1b[35m"; 11 | const fgCyan = "\x1b[36m"; 12 | const fgWhite = "\x1b[37m"; 13 | 14 | const bgBlack = "\x1b[40m"; 15 | const bgRed = "\x1b[41m"; 16 | const bgGreen = "\x1b[42m"; 17 | const bgYellow = "\x1b[43m"; 18 | const bgBlue = "\x1b[44m"; 19 | const bgMagenta = "\x1b[45m"; 20 | const bgCyan = "\x1b[46m"; 21 | const bgWhite = "\x1b[47m"; 22 | 23 | export const fontColors = { 24 | black: fgBlack, 25 | red: fgRed, 26 | green: fgGreen, 27 | yellow: fgYellow, 28 | blue: fgBlue, 29 | magenta: fgMagenta, 30 | cyan: fgCyan, 31 | white: fgWhite, 32 | }; 33 | 34 | export const backgroundColors = { 35 | black: bgBlack, 36 | red: bgRed, 37 | green: bgGreen, 38 | yellow: bgYellow, 39 | blue: bgBlue, 40 | magenta: bgMagenta, 41 | cyan: bgCyan, 42 | white: bgWhite, 43 | }; 44 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # https://vitepress.dev/reference/default-theme-home-page 3 | layout: home 4 | 5 | hero: 6 | name: "Essentials utils" 7 | text: "Powerfull js/ts functions" 8 | tagline: A collection of functions to make your life easier 9 | actions: 10 | - theme: brand 11 | text: What is Essentials utils? 12 | link: /guide/what-is-essentials-utils 13 | - theme: alt 14 | text: Installation 15 | link: /guide/installation 16 | - theme: alt 17 | text: GitHub 18 | link: https://github.com/wesleyara/essentials-utils 19 | image: 20 | src: /favicon.png 21 | alt: essentials-utils logo 22 | 23 | features: 24 | - title: Simple 25 | icon: 🚀 26 | details: Simple and easy to use functions 27 | - title: Powerful 28 | icon: 💪 29 | details: Functions that will make your life easier 30 | - title: Flexible 31 | icon: 🤖 32 | details: Functions that work in any environment 33 | --- 34 | 35 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Wesley Araújo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es2021": true, 4 | "node": true, 5 | "jest": true 6 | }, 7 | "extends": [ 8 | "standard", 9 | "eslint:recommended", 10 | "plugin:prettier/recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parser": "@typescript-eslint/parser", 14 | "plugins": ["eslint-plugin-import-helpers"], 15 | "parserOptions": { 16 | "ecmaVersion": "latest", 17 | "sourceType": "module" 18 | }, 19 | "rules": { 20 | "@typescript-eslint/naming-convention": "off", 21 | "import/prefer-default-export": "off", 22 | "no-console": "off", 23 | "import/extensions": "off", 24 | "import/no-unresolved": "off", 25 | "@typescript-eslint/ban-types": "off", 26 | "no-unused-vars": [ 27 | "error", 28 | { 29 | "argsIgnorePattern": "^_", 30 | "varsIgnorePattern": "^_" 31 | } 32 | ], 33 | "import-helpers/order-imports": [ 34 | "warn", 35 | { 36 | "newlinesBetween": "always", 37 | "groups": ["module", "/^@shared/", ["parent", "sibling", "index"]], 38 | "alphabetize": { 39 | "order": "asc", 40 | "ignoreCase": true 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/cicd.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/cicd.yml 2 | 3 | name: Env CI/CD 4 | 5 | on: 6 | push: 7 | branches: ["main", "develop"] 8 | pull_request: 9 | branches: ["main", "develop"] 10 | 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | 15 | strategy: 16 | matrix: 17 | node-version: [22.x] 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Use Node.js ${{ matrix.node-version }} 22 | uses: actions/setup-node@v3 23 | with: 24 | node-version: ${{ matrix.node-version }} 25 | - run: yarn && yarn format && yarn lint 26 | 27 | test: 28 | runs-on: ubuntu-latest 29 | 30 | strategy: 31 | matrix: 32 | node-version: [22.x] 33 | 34 | steps: 35 | - uses: actions/checkout@v3 36 | - name: Use Node.js ${{ matrix.node-version }} 37 | uses: actions/setup-node@v3 38 | with: 39 | node-version: ${{ matrix.node-version }} 40 | - run: yarn && yarn test 41 | 42 | build: 43 | runs-on: ubuntu-latest 44 | 45 | strategy: 46 | matrix: 47 | node-version: [22.x] 48 | 49 | steps: 50 | - uses: actions/checkout@v3 51 | - name: Use Node.js ${{ matrix.node-version }} 52 | uses: actions/setup-node@v3 53 | with: 54 | node-version: ${{ matrix.node-version }} 55 | - run: yarn && yarn build 56 | -------------------------------------------------------------------------------- /src/react/useStorage/index.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | import { getStorage, setStorage } from "../../core"; 4 | 5 | export const useStorage = (key: string, value: TValue) => { 6 | const [state, setState] = useState(() => { 7 | try { 8 | const item = getStorage(key); 9 | const response = item || value; 10 | return response as TValue; 11 | } catch (error) { 12 | console.error("Erro ao ler o localStorage", error); 13 | return value; 14 | } 15 | }); 16 | 17 | useEffect(() => { 18 | try { 19 | setStorage(key, state); 20 | } catch (error) { 21 | console.error("Erro ao escrever no localStorage", error); 22 | } 23 | }, [key, state]); 24 | 25 | useEffect(() => { 26 | const handleStorageChange = (event: StorageEvent) => { 27 | if (event.key === key) { 28 | try { 29 | const response = event.newValue ? JSON.parse(event.newValue) : value; 30 | setState(response as TValue); 31 | } catch (error) { 32 | console.error("Erro ao parsear o valor do localStorage", error); 33 | } 34 | } 35 | }; 36 | 37 | window.addEventListener("storage", handleStorageChange); 38 | return () => { 39 | window.removeEventListener("storage", handleStorageChange); 40 | }; 41 | }, [key, value]); 42 | 43 | return [state, setState] as const; 44 | }; 45 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "wesleyara", 10 | "name": "Wesley Araújo", 11 | "avatar_url": "https://avatars.githubusercontent.com/u/89321125?v=4", 12 | "profile": "https://wesleyaraujo.dev/", 13 | "contributions": [ 14 | "author" 15 | ] 16 | }, 17 | { 18 | "login": "Patryck-Silva", 19 | "name": "Patryck Silva", 20 | "avatar_url": "https://avatars.githubusercontent.com/u/41785386?v=4", 21 | "profile": "https://github.com/Patryck-Silva", 22 | "contributions": [ 23 | "features" 24 | ] 25 | }, 26 | { 27 | "login": "joaoianuci", 28 | "name": "João Vitor Ianuci", 29 | "avatar_url": "https://avatars.githubusercontent.com/u/42063789?v=4", 30 | "profile": "https://github.com/joaoianuci", 31 | "contributions": [ 32 | "features" 33 | ] 34 | }, 35 | { 36 | "login": "Glerme", 37 | "name": "Guilherme Felipe", 38 | "avatar_url": "https://avatars.githubusercontent.com/u/62507710?v=4", 39 | "profile": "https://github.com/Glerme", 40 | "contributions": [ 41 | "features" 42 | ] 43 | }, 44 | { 45 | "login": "heronoa", 46 | "name": "Heron Amaral", 47 | "avatar_url": "https://avatars.githubusercontent.com/u/71283373?v=4", 48 | "profile": "https://github.com/heronoa", 49 | "contributions": [ 50 | "features" 51 | ] 52 | } 53 | ], 54 | "contributorsPerLine": 7, 55 | "projectName": "essentials-utils", 56 | "projectOwner": "essentials-utils", 57 | "repoType": "github", 58 | "repoHost": "https://github.com", 59 | "skipCi": true 60 | } -------------------------------------------------------------------------------- /docs/core/useRemoveDuplicates/index.md: -------------------------------------------------------------------------------- 1 | # useRemoveDuplicates 2 | 3 | Remove duplicates from a array, you can define with keys you want to prevent to stack and count how many duplicates you have. 4 | 5 | ## Usage 6 | 7 | ### Remove duplicates from a array 8 | 9 | ```js 10 | import { useRemoveDuplicates } from "essentials-utils"; 11 | 12 | const arrayFullOfDuplicates = [1, 2, 2, 3, 4, 4, 5]; 13 | const noDuplicateArray = useRemoveDuplicates(arrayFullOfDuplicates); 14 | 15 | console.log(noDuplicateArray); // [1, 2, 3, 4, 5] 16 | ``` 17 | 18 | ### Remove duplicates from a array of objects 19 | 20 | ```ts 21 | import { useRemoveDuplicates } from "essentials-utils"; 22 | 23 | const arrayFullOfDuplicates = [ 24 | { id: 1, name: "John" }, 25 | { id: 2, name: "Jane" }, 26 | { id: 1, name: "John" }, 27 | { id: 3, name: "Doe" }, 28 | { id: 2, name: "Jane" }, 29 | ]; 30 | 31 | const options = { 32 | isObject: true, 33 | anchorKeys: ["id"], 34 | counts: true, 35 | }; 36 | 37 | const noDuplicateArray = useRemoveDuplicates(arrayFullOfDuplicates, options); 38 | 39 | console.log(noDuplicateArray); 40 | // [ 41 | // { id: 1, name: "John", _quantity: 2 }, 42 | // { id: 2, name: "Jane", _quantity: 2 }, 43 | // { id: 3, name: "Doe", _quantity: 1 }, 44 | // ] 45 | ``` 46 | 47 | ## Type Declarations 48 | 49 | ::: details Show type declarations 50 | 51 | ```ts 52 | type AnchorKeysType = keyof TArray | (keyof TArray)[]; 53 | 54 | export interface RemoveDuplicatesOptions { 55 | isObject: boolean; 56 | anchorKeys: AnchorKeysType; 57 | counts: boolean; 58 | } 59 | 60 | export declare function useRemoveDuplicates( 61 | array: TArray[], 62 | options?: Partial>, 63 | ): TArray[]; 64 | ``` 65 | 66 | ::: 67 | -------------------------------------------------------------------------------- /src/core/useRemoveDuplicates/index.ts: -------------------------------------------------------------------------------- 1 | import { RemoveDuplicatesOptions } from "./models/use-remove-duplicates.models"; 2 | 3 | export const useRemoveDuplicates = ( 4 | array: TArray[], 5 | options?: Partial>, 6 | ) => { 7 | const isArrayOfPrimitives = array.every( 8 | item => item !== null && typeof item !== "object", 9 | ); 10 | 11 | if (options?.isObject) { 12 | if (isArrayOfPrimitives) { 13 | throw new Error( 14 | "The array is not an array of objects. Please set the isObject option to false.", 15 | ); 16 | } 17 | } else { 18 | if (!isArrayOfPrimitives) { 19 | throw new Error( 20 | "The array is not an array of primitives. Please set the isObject option to true.", 21 | ); 22 | } 23 | } 24 | 25 | const noDuplicateMap = new Map(); 26 | 27 | array.forEach(item => { 28 | let key; 29 | 30 | if (options?.isObject) { 31 | if (!options?.anchorKeys) { 32 | throw new Error( 33 | "You must provide an anchor key for the object to be compared.", 34 | ); 35 | } 36 | 37 | const anchorArray = Array.isArray(options.anchorKeys) 38 | ? options.anchorKeys 39 | : [options.anchorKeys]; 40 | 41 | key = anchorArray.map(anchorKey => item[anchorKey]).join("@"); 42 | } else { 43 | key = item; 44 | } 45 | 46 | if (noDuplicateMap.has(key)) { 47 | if (options?.counts) { 48 | const existingItem = noDuplicateMap.get(key); 49 | noDuplicateMap.set(key, { 50 | ...existingItem, 51 | _quantity: noDuplicateMap.get(key)?._quantity + 1, 52 | }); 53 | } 54 | return; 55 | } 56 | 57 | noDuplicateMap.set(key, options?.counts ? { ...item, _quantity: 1 } : item); 58 | }); 59 | 60 | return Array.from(noDuplicateMap.values()) as TArray[]; 61 | }; 62 | -------------------------------------------------------------------------------- /src/core/getNavigatorCurrentLocation/test/getNavigatorCurrentLocation.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, vi } from "vitest"; 2 | 3 | import { getNavigatorCurrentLocation } from "../"; 4 | 5 | describe("getNavigatorCurrentLocation", () => { 6 | it("should be defined", () => { 7 | expect(getNavigatorCurrentLocation).toBeDefined(); 8 | }); 9 | 10 | it("get current location", async () => { 11 | const mockSuccessCallback = vi.fn(); 12 | const mockErrorCallback = vi.fn(); 13 | const mockToJSON = vi.fn(); 14 | 15 | if (!global.navigator.geolocation) { 16 | return; 17 | } 18 | 19 | global.navigator.geolocation.getCurrentPosition = vi.fn(success => { 20 | success({ 21 | coords: { 22 | latitude: 10, 23 | longitude: 20, 24 | accuracy: 1, 25 | altitude: null, 26 | altitudeAccuracy: null, 27 | heading: null, 28 | speed: null, 29 | toJSON: mockToJSON, 30 | }, 31 | timestamp: 123, 32 | toJSON: mockToJSON, 33 | }); 34 | }); 35 | 36 | const result = await getNavigatorCurrentLocation({ 37 | successCallback: mockSuccessCallback, 38 | errorCallback: mockErrorCallback, 39 | }); 40 | 41 | expect(result).toEqual({ 42 | coords: { 43 | latitude: 10, 44 | longitude: 20, 45 | accuracy: 1, 46 | altitude: null, 47 | altitudeAccuracy: null, 48 | heading: null, 49 | speed: null, 50 | }, 51 | timestamp: 123, 52 | }); 53 | }); 54 | 55 | it("get current location", async () => { 56 | const mockSuccessCallback = vi.fn(); 57 | const mockErrorCallback = vi.fn(); 58 | const mockToJSON = vi.fn(); 59 | 60 | if (!global.navigator.geolocation) { 61 | return; 62 | } 63 | 64 | global.navigator.geolocation.getCurrentPosition = vi.fn(success => { 65 | success({ 66 | coords: { 67 | latitude: 10, 68 | longitude: 20, 69 | accuracy: 1, 70 | altitude: null, 71 | altitudeAccuracy: null, 72 | heading: null, 73 | speed: null, 74 | toJSON: mockToJSON, 75 | }, 76 | timestamp: 123, 77 | toJSON: mockToJSON, 78 | }); 79 | }); 80 | 81 | const result = await getNavigatorCurrentLocation({ 82 | successCallback: mockSuccessCallback, 83 | errorCallback: mockErrorCallback, 84 | }); 85 | 86 | expect(result).toEqual({ 87 | coords: { 88 | latitude: 10, 89 | longitude: 20, 90 | accuracy: 1, 91 | altitude: null, 92 | altitudeAccuracy: null, 93 | heading: null, 94 | speed: null, 95 | }, 96 | timestamp: 123, 97 | }); 98 | }); 99 | }); 100 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "essentials-utils", 3 | "version": "1.2.11", 4 | "description": "A powerfull js/ts functions", 5 | "main": "./lib/index.js", 6 | "types": "./lib/index.d.ts", 7 | "exports": { 8 | ".": { 9 | "import": "./lib/index.js", 10 | "default": "./lib/index.js", 11 | "types": "./lib/index.d.ts" 12 | }, 13 | "./react": { 14 | "import": "./lib/react/index.js", 15 | "default": "./lib/react/index.js", 16 | "types": "./lib/react/index.d.ts" 17 | }, 18 | "./vue": { 19 | "import": "./lib/vue/index.js", 20 | "default": "./lib/vue/index.js", 21 | "types": "./lib/vue/index.d.ts" 22 | } 23 | }, 24 | "scripts": { 25 | "test": "vitest", 26 | "test:run": "vitest run", 27 | "dev": "ts-node src/index.ts", 28 | "build": "rimraf lib && tsc --declaration", 29 | "format": "prettier --check src", 30 | "format:fix": "prettier --write src", 31 | "lint": "eslint --ext js,ts src", 32 | "lint:fix": "eslint --ext js,ts src --fix", 33 | "prepare": "husky install", 34 | "postversion": "git push && git push --tags && rm -rf build/temp", 35 | "docs:dev": "vitepress dev docs", 36 | "docs:build": "vitepress build docs", 37 | "docs:preview": "vitepress preview docs" 38 | }, 39 | "lint-staged": { 40 | "src/**/*.{js,ts,jsx,tsx}": [ 41 | "prettier --write src", 42 | "eslint --ext js,ts src --fix" 43 | ] 44 | }, 45 | "files": [ 46 | "lib/**/*" 47 | ], 48 | "repository": { 49 | "type": "git", 50 | "url": "git+https://github.com/wesleyara/essentials-utils.git" 51 | }, 52 | "keywords": [ 53 | "react", 54 | "typescript", 55 | "javascript", 56 | "and", 57 | "utils." 58 | ], 59 | "author": "Wesley Araújo", 60 | "license": "MIT", 61 | "bugs": { 62 | "url": "https://github.com/wesleyara/essentials-utils/issues" 63 | }, 64 | "homepage": "https://github.com/wesleyara/essentials-utils#readme", 65 | "dependencies": { 66 | "crypto-js": "^4.2.0", 67 | "react": "^18.2.0", 68 | "rimraf": "^3.0.2", 69 | "vue": "^3.5.13" 70 | }, 71 | "devDependencies": { 72 | "@commitlint/cli": "^17.3.0", 73 | "@commitlint/config-conventional": "^17.1.0", 74 | "@types/crypto-js": "^4.2.2", 75 | "@types/jsdom": "^21.1.2", 76 | "@types/node": "^18.11.9", 77 | "@types/react": "^18.0.25", 78 | "@typescript-eslint/eslint-plugin": "^5.45.0", 79 | "@typescript-eslint/parser": "^5.45.0", 80 | "autoprefixer": "^10.4.20", 81 | "eslint": "^8.28.0", 82 | "eslint-config-prettier": "^8.5.0", 83 | "eslint-config-standard": "^17.0.0", 84 | "eslint-plugin-import": "^2.26.0", 85 | "eslint-plugin-import-helpers": "^1.2.1", 86 | "eslint-plugin-n": "^15.3.0", 87 | "eslint-plugin-prettier": "^4.2.1", 88 | "eslint-plugin-promise": "^6.0.1", 89 | "husky": "^8.0.2", 90 | "jsdom": "^22.1.0", 91 | "lint-staged": "^13.0.4", 92 | "postcss": "^8.5.1", 93 | "prettier": "^2.8.0", 94 | "tailwindcss": "3", 95 | "ts-node": "^10.9.1", 96 | "typescript": "^4.9.3", 97 | "vite": "^5.4.8", 98 | "vitepress": "^1.6.3", 99 | "vitepress-plugin-group-icons": "^1.3.5", 100 | "vitest": "^1.4.0" 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | essentials-utils 3 |

4 | 5 |

essentials-utils provides important functions for react and vanilla javascript/typescript

6 | 7 | [![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.png?v=103)](https://github.com/ellerbrock/open-source-badges/) 8 | [![MIT Licence](https://badges.frapsoft.com/os/mit/mit.png?v=103)](https://opensource.org/licenses/mit-license.php) 9 | [![npm version](https://img.shields.io/npm/v/essentials-utils.svg?style=flat-square)](https://www.npmjs.com/package/essentials-utils) 10 | [![npm downloads](https://img.shields.io/npm/dm/essentials-utils.svg?style=flat-square)](http://npm-stat.com/charts.html?package=cz-conventional-changelog&from=2015-08-01) [![All Contributors](https://img.shields.io/badge/all_contributors-2-green.svg?style=flat-square)](#contributors-) 11 | 12 |

13 | :rocket: How use • 14 | 🛠️ Tools • 15 | :pencil: Contributing • 16 | :adult: Thanks • 17 | :page_facing_up: License 18 |

19 | 20 | 21 | See the documentation: https://essentials-utils.wesleyaraujo.dev/ 22 | 23 |
24 | 25 | # :rocket: How use 26 | 27 | Instalation: 28 | 29 | ```bash 30 | npm install essentials-utils 31 | #or 32 | yarn add essentials-utils 33 | ``` 34 | 35 | Answer the questions (When choosing the tool, use the arrows keys to navigate, the spacebar to select and enter to finish) 36 | 37 | # 🛠️ Tools 38 | 39 | Example: 40 | 41 | ## upperFirst 42 | 43 | Capitalize the first letter of the string. 44 | 45 | ```js 46 | import { upperFirst } from "essentials-utils"; 47 | 48 | upperFirst("hello world"); // Hello world 49 | ``` 50 | 51 | ## useDebounce 52 | 53 | Debounce hook is used to minimize backend requests on inputs. 54 | 55 | ```js 56 | import { useDebounce } from "essentials-utils"; 57 | 58 | const [value, setValue] = useState(""); 59 | const debouncedValue = useDebounce(value, 1000); 60 | 61 | useEffect(() => { 62 | console.log(debouncedValue); 63 | }, [debouncedValue]); 64 | ``` 65 | 66 | # :pencil: Contributing 67 | 68 | Your contribution to the `essentials-utils` is essential for the evolution of the project, you can do it as follows: 69 | 70 | - Open an [issue](https://github.com/wesleyara/essentials-utils/issues) to clear doubts, report bugs or give ideas 71 | - Open a [pull request](https://github.com/wesleyara/essentials-utils/pulls) to give ideas for code improvement, implementation of new features and bug fixes 72 | 73 | These are just some of the ways you can contribute to the project read the [CONTRIBUTING](https://github.com/wesleyara/essentials-utils/blob/main/.github/CONTRIBUTING.md) for more information 74 | 75 | # :adult: Authors 76 | 77 | 78 | 79 | 80 | 81 |

Wesley Araújo

82 | 83 | ## ✨ Contributors 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 |

Patryck Silva


João Vitor Ianuci


Guilherme Felipe


Heron Amaral

93 | 94 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 105 | 106 | # :page_facing_up: License 107 | 108 | essentials-utils is a open source project licensed as [MIT](LICENSE). 109 | 110 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * 9 | * Each colors have exact same color scale system with 3 levels of solid 10 | * colors with different brightness, and 1 soft color. 11 | * 12 | * - `XXX-1`: The most solid color used mainly for colored text. It must 13 | * satisfy the contrast ratio against when used on top of `XXX-soft`. 14 | * 15 | * - `XXX-2`: The color used mainly for hover state of the button. 16 | * 17 | * - `XXX-3`: The color for solid background, such as bg color of the button. 18 | * It must satisfy the contrast ratio with pure white (#ffffff) text on 19 | * top of it. 20 | * 21 | * - `XXX-soft`: The color used for subtle background such as custom container 22 | * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors 23 | * on top of it. 24 | * 25 | * The soft color must be semi transparent alpha channel. This is crucial 26 | * because it allows adding multiple "soft" colors on top of each other 27 | * to create a accent, such as when having inline code block inside 28 | * custom containers. 29 | * 30 | * - `default`: The color used purely for subtle indication without any 31 | * special meanings attached to it such as bg color for menu hover state. 32 | * 33 | * - `brand`: Used for primary brand colors, such as link text, button with 34 | * brand theme, etc. 35 | * 36 | * - `tip`: Used to indicate useful information. The default theme uses the 37 | * brand color for this by default. 38 | * 39 | * - `warning`: Used to indicate warning to the users. Used in custom 40 | * container, badges, etc. 41 | * 42 | * - `danger`: Used to show error, or dangerous message to the users. Used 43 | * in custom container, badges, etc. 44 | * -------------------------------------------------------------------------- */ 45 | @tailwind base; 46 | @tailwind components; 47 | @tailwind utilities; 48 | 49 | :root { 50 | --vp-c-default-1: var(--vp-c-gray-1); 51 | --vp-c-default-2: var(--vp-c-gray-2); 52 | --vp-c-default-3: var(--vp-c-gray-3); 53 | --vp-c-default-soft: var(--vp-c-gray-soft); 54 | 55 | --vp-c-brand-1: var(--vp-c-indigo-1); 56 | --vp-c-brand-2: var(--vp-c-indigo-2); 57 | --vp-c-brand-3: var(--vp-c-indigo-3); 58 | --vp-c-brand-soft: var(--vp-c-indigo-soft); 59 | 60 | --vp-c-tip-1: var(--vp-c-brand-1); 61 | --vp-c-tip-2: var(--vp-c-brand-2); 62 | --vp-c-tip-3: var(--vp-c-brand-3); 63 | --vp-c-tip-soft: var(--vp-c-brand-soft); 64 | 65 | --vp-c-warning-1: var(--vp-c-yellow-1); 66 | --vp-c-warning-2: var(--vp-c-yellow-2); 67 | --vp-c-warning-3: var(--vp-c-yellow-3); 68 | --vp-c-warning-soft: var(--vp-c-yellow-soft); 69 | 70 | --vp-c-danger-1: var(--vp-c-red-1); 71 | --vp-c-danger-2: var(--vp-c-red-2); 72 | --vp-c-danger-3: var(--vp-c-red-3); 73 | --vp-c-danger-soft: var(--vp-c-red-soft); 74 | } 75 | 76 | /** 77 | * Component: Button 78 | * -------------------------------------------------------------------------- */ 79 | 80 | :root { 81 | --vp-button-brand-border: transparent; 82 | --vp-button-brand-text: var(--vp-c-white); 83 | --vp-button-brand-bg: var(--vp-c-brand-3); 84 | --vp-button-brand-hover-border: transparent; 85 | --vp-button-brand-hover-text: var(--vp-c-white); 86 | --vp-button-brand-hover-bg: var(--vp-c-brand-2); 87 | --vp-button-brand-active-border: transparent; 88 | --vp-button-brand-active-text: var(--vp-c-white); 89 | --vp-button-brand-active-bg: var(--vp-c-brand-1); 90 | } 91 | 92 | /** 93 | * Component: Home 94 | * -------------------------------------------------------------------------- */ 95 | 96 | :root { 97 | --vp-home-hero-name-color: transparent; 98 | --vp-home-hero-name-background: -webkit-linear-gradient( 99 | 120deg, 100 | #bd34fe 30%, 101 | #41d1ff 102 | ); 103 | 104 | --vp-home-hero-image-background-image: linear-gradient( 105 | -45deg, 106 | #bd34fe 50%, 107 | #47caff 50% 108 | ); 109 | --vp-home-hero-image-filter: blur(44px); 110 | } 111 | 112 | @media (min-width: 640px) { 113 | :root { 114 | --vp-home-hero-image-filter: blur(56px); 115 | } 116 | } 117 | 118 | @media (min-width: 960px) { 119 | :root { 120 | --vp-home-hero-image-filter: blur(68px); 121 | } 122 | } 123 | 124 | /** 125 | * Component: Custom Block 126 | * -------------------------------------------------------------------------- */ 127 | 128 | :root { 129 | --vp-custom-block-tip-border: transparent; 130 | --vp-custom-block-tip-text: var(--vp-c-text-1); 131 | --vp-custom-block-tip-bg: var(--vp-c-brand-soft); 132 | --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); 133 | } 134 | 135 | /** 136 | * Component: Algolia 137 | * -------------------------------------------------------------------------- */ 138 | 139 | .DocSearch { 140 | --docsearch-primary-color: var(--vp-c-brand-1) !important; 141 | } 142 | -------------------------------------------------------------------------------- /docs/.vitepress/config.mts: -------------------------------------------------------------------------------- 1 | import { type DefaultTheme, defineConfig } from 'vitepress' 2 | import { groupIconMdPlugin, groupIconVitePlugin, localIconLoader } from 'vitepress-plugin-group-icons' 3 | 4 | // https://vitepress.dev/reference/site-config 5 | export default defineConfig({ 6 | lang: 'en-US', 7 | title: "Essentials utils", 8 | description: "Powerfull js/ts functions", 9 | srcExclude: ["**/parts/**.md"], 10 | markdown: { 11 | config(md) { 12 | md.use(groupIconMdPlugin) 13 | }, 14 | }, 15 | head: [ 16 | ['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }], 17 | ['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }], 18 | ['meta', { name: 'theme-color', content: '#5f67ee' }], 19 | ['meta', { property: 'og:type', content: 'website' }], 20 | ['meta', { property: 'og:locale', content: 'en' }], 21 | ['meta', { property: 'og:title', content: 'Essentials Utils' }], 22 | ['meta', { property: 'og:site_name', content: 'EssentialsUtils' }], 23 | ['meta', { property: 'og:image', content: 'https://essentials-utils.wesleyaraujo.dev/og-img.png' }], 24 | ['meta', { property: 'og:url', content: 'https://essentials-utils.wesleyaraujo.dev/' }], 25 | ], 26 | themeConfig: { 27 | // https://vitepress.dev/reference/default-theme-config 28 | nav: [ 29 | { text: 'Home', link: '/' }, 30 | { text: 'Instalation', link: '/guide/Instalation' } 31 | ], 32 | 33 | sidebar: sidebarGuide(), 34 | 35 | socialLinks: [ 36 | { icon: 'github', link: 'https://github.com/wesleyara/essentials-utils' } 37 | ], 38 | 39 | editLink: { 40 | pattern: 'https://github.com/wesleyara/essential-utils/edit/main/docs/:path', 41 | text: 'Suggest changes to this page' 42 | }, 43 | 44 | lastUpdated: { 45 | text: 'Updated at', 46 | formatOptions: { 47 | dateStyle: 'short', 48 | timeStyle: 'medium' 49 | } 50 | }, 51 | 52 | footer: { 53 | message: 'Released under the MIT License.', 54 | copyright: `Copyright © 2022-${new Date().getFullYear()} Wesley Araújo` 55 | }, 56 | 57 | search: { 58 | provider: 'local' 59 | }, 60 | }, 61 | vite: { 62 | plugins: [ 63 | groupIconVitePlugin() as any, 64 | ] 65 | } 66 | }) 67 | 68 | 69 | function sidebarGuide(): DefaultTheme.SidebarItem[] { 70 | return [ 71 | { 72 | text: 'Introduction', 73 | base: '/guide', 74 | collapsed: false, 75 | items: [ 76 | { text: 'What is Essentials utils?', link: '/what-is-essentials-utils/' }, 77 | { text: 'Installation', link: '/installation/' }, 78 | ] 79 | }, 80 | { 81 | text: 'Core', 82 | base: '/core', 83 | collapsed: false, 84 | items: [ 85 | { text: 'arrayEquals', link: '/arrayEquals/' }, 86 | { text: 'arrayLastItem', link: '/arrayLastItem/' }, 87 | { text: 'arrayToObject', link: '/arrayToObject/' }, 88 | { text: 'cepMask', link: '/cepMask/' }, 89 | { text: 'colorLog', link: '/colorLog/' }, 90 | { text: 'cpfMask', link: '/cpfMask/' }, 91 | { text: 'cpnjMask', link: '/cpnjMask/' }, 92 | { text: 'deepClone', link: '/deepClone/' }, 93 | { text: 'delay', link: '/delay/' }, 94 | { text: 'generateArray', link: '/generateArray/' }, 95 | { text: 'generateNullArray', link: '/generateNullArray/' }, 96 | { text: 'generateRandomColor', link: '/generateRandomColor/' }, 97 | { text: 'generateRandomNumber', link: '/generateRandomNumber/' }, 98 | { text: 'generateRandomString', link: '/generateRandomString/' }, 99 | { 100 | text: 'getNavigatorCurrentLocation', 101 | link: '/getNavigatorCurrentLocation/' 102 | }, 103 | { text: 'getPercentage', link: '/getPercentage/' }, 104 | { text: 'getStorage', link: '/getStorage/' }, 105 | { text: 'isEmptyObject', link: '/isEmptyObject/' }, 106 | { text: 'objectToArray', link: '/objectToArray/' }, 107 | { text: 'phoneMask', link: '/phoneMask/' }, 108 | { text: 'removeArrayItemByIndex', link: '/removeArrayItemByIndex/' }, 109 | { text: 'removeArrayItemByValue', link: '/removeArrayItemByValue/' }, 110 | { text: 'removeStorage', link: '/removeStorage/' }, 111 | { text: 'reverseString', link: '/reverseString/' }, 112 | { text: 'setStorage', link: '/setStorage/' }, 113 | { text: 'shuffleArray', link: '/shuffleArray/' }, 114 | { text: 'smartLog', link: '/smartLog/' }, 115 | { text: 'upperFirst', link: '/upperFirst/' }, 116 | { text: 'useRemoveDuplicates', link: '/useRemoveDuplicates/' }, 117 | { text: 'useSecurityStorage', link: '/useSecurityStorage/' }, 118 | ].sort((a, b) => a.text.localeCompare(b.text)) 119 | }, 120 | { 121 | text: 'React', 122 | base: '/react', 123 | collapsed: false, 124 | items: [ 125 | { text: "useDebounce", link: '/useDebounce/' }, 126 | { text: "useHeight", link: '/useHeight/' }, 127 | { text: "useNow", link: '/useNow/' }, 128 | { text: "useScroll", link: '/useScroll/' }, 129 | { text: "useToggle", link: '/useToggle/' }, 130 | { text: "useWidth", link: '/useWidth/' }, 131 | { text: "useMousePosition", link: "/useMousePosition/" }, 132 | { text: "useStorage", link: "/useStorage/" }, 133 | ].sort((a, b) => a.text.localeCompare(b.text)) 134 | }, 135 | { 136 | text: 'Vue', 137 | base: '/vue', 138 | collapsed: false, 139 | items: [ 140 | { text: "useMousePosition", link: "/useMousePosition/" }, 141 | ].sort((a, b) => a.text.localeCompare(b.text)) 142 | } 143 | ] 144 | } 145 | -------------------------------------------------------------------------------- /src/core/useRemoveDuplicates/test/useRemoveDuplicates.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | 3 | import { useRemoveDuplicates } from "../"; 4 | 5 | describe("useRemoveDuplicates", () => { 6 | it("should be defined", () => { 7 | expect(useRemoveDuplicates).toBeDefined(); 8 | }); 9 | 10 | it("remove duplicates from an array of primitives", () => { 11 | const arrayWithDuplicates = [1, 2, 2, 3, 3, 3, 4, 5, 5]; 12 | const result = useRemoveDuplicates(arrayWithDuplicates); 13 | expect(result).toEqual([1, 2, 3, 4, 5]); 14 | }); 15 | 16 | it("remove duplicates from an array of objects", () => { 17 | const arrayWithDuplicates = [ 18 | { id: 1, name: "a" }, 19 | { id: 2, name: "b" }, 20 | { id: 1, name: "a" }, 21 | { id: 3, name: "c" }, 22 | { id: 2, name: "b" }, 23 | ]; 24 | const result = useRemoveDuplicates(arrayWithDuplicates, { 25 | isObject: true, 26 | anchorKeys: "id", 27 | }); 28 | expect(result).toEqual([ 29 | { id: 1, name: "a" }, 30 | { id: 2, name: "b" }, 31 | { id: 3, name: "c" }, 32 | ]); 33 | }); 34 | 35 | it("remove duplicates from an array of objects with counts", () => { 36 | const arrayWithDuplicates = [ 37 | { id: 1, name: "a" }, 38 | { id: 2, name: "b" }, 39 | { id: 1, name: "a" }, 40 | { id: 3, name: "c" }, 41 | { id: 2, name: "b" }, 42 | ]; 43 | const result = useRemoveDuplicates(arrayWithDuplicates, { 44 | isObject: true, 45 | anchorKeys: "id", 46 | counts: true, 47 | }); 48 | expect(result).toEqual([ 49 | { id: 1, name: "a", _quantity: 2 }, 50 | { id: 2, name: "b", _quantity: 2 }, 51 | { id: 3, name: "c", _quantity: 1 }, 52 | ]); 53 | }); 54 | 55 | it("remove duplicates from a large array of objects", () => { 56 | const arrayWithDuplicates = [ 57 | { id: 1, name: "a" }, 58 | { id: 4, name: "d" }, 59 | { id: 2, name: "b" }, 60 | { id: 4, name: "d" }, 61 | { id: 1, name: "a" }, 62 | { id: 4, name: "d" }, 63 | { id: 3, name: "c" }, 64 | { id: 4, name: "d" }, 65 | { id: 2, name: "b" }, 66 | { id: 4, name: "d" }, 67 | ]; 68 | const result = useRemoveDuplicates(arrayWithDuplicates, { 69 | isObject: true, 70 | anchorKeys: "id", 71 | }); 72 | expect(result).toEqual([ 73 | { id: 1, name: "a" }, 74 | { id: 4, name: "d" }, 75 | { id: 2, name: "b" }, 76 | { id: 3, name: "c" }, 77 | ]); 78 | }); 79 | 80 | it("remove duplicates from a large array of objects with counts", () => { 81 | const arrayWithDuplicates = [ 82 | { id: 4, name: "d" }, 83 | { id: 1, name: "a" }, 84 | { id: 4, name: "d" }, 85 | { id: 2, name: "b" }, 86 | { id: 4, name: "d" }, 87 | { id: 1, name: "a" }, 88 | { id: 3, name: "c" }, 89 | { id: 4, name: "c" }, 90 | { id: 4, name: "d" }, 91 | { id: 2, name: "b" }, 92 | { id: 4, name: "d" }, 93 | ]; 94 | const result = useRemoveDuplicates(arrayWithDuplicates, { 95 | isObject: true, 96 | anchorKeys: "id", 97 | counts: true, 98 | }); 99 | expect(result).toEqual([ 100 | { id: 4, name: "d", _quantity: 6 }, 101 | { id: 1, name: "a", _quantity: 2 }, 102 | { id: 2, name: "b", _quantity: 2 }, 103 | { id: 3, name: "c", _quantity: 1 }, 104 | ]); 105 | }); 106 | 107 | it("throws an error when removing duplicates from an array of primitives with isObject set to true", () => { 108 | const arrayWithDuplicates = [1, 2, 2, 3, 3, 3, 4, 5, 5]; 109 | expect(() => 110 | useRemoveDuplicates(arrayWithDuplicates, { isObject: true }), 111 | ).toThrow( 112 | "The array is not an array of objects. Please set the isObject option to false.", 113 | ); 114 | }); 115 | 116 | it("throws an error when removing duplicates from an array of objects with isObject set to false", () => { 117 | const arrayWithDuplicates = [ 118 | { id: 1, name: "a" }, 119 | { id: 2, name: "b" }, 120 | { id: 1, name: "a" }, 121 | { id: 3, name: "c" }, 122 | { id: 2, name: "b" }, 123 | ]; 124 | expect(() => 125 | useRemoveDuplicates(arrayWithDuplicates, { isObject: false }), 126 | ).toThrow( 127 | "The array is not an array of primitives. Please set the isObject option to true.", 128 | ); 129 | }); 130 | 131 | it("throws an error when removing duplicates from an array of objects without providing anchor keys", () => { 132 | const arrayWithDuplicates = [ 133 | { id: 1, name: "a" }, 134 | { id: 2, name: "b" }, 135 | { id: 1, name: "a" }, 136 | { id: 3, name: "c" }, 137 | { id: 2, name: "b" }, 138 | ]; 139 | expect(() => 140 | useRemoveDuplicates(arrayWithDuplicates, { isObject: true }), 141 | ).toThrow("You must provide an anchor key for the object to be compared."); 142 | }); 143 | 144 | it("handles an array with a single element correctly", () => { 145 | const arrayWithDuplicates = [1]; 146 | const result = useRemoveDuplicates(arrayWithDuplicates); 147 | expect(result).toEqual([1]); 148 | }); 149 | 150 | it("handles an array with all unique elements correctly", () => { 151 | const arrayWithDuplicates = [1, 2, 3, 4, 5]; 152 | const result = useRemoveDuplicates(arrayWithDuplicates); 153 | expect(result).toEqual([1, 2, 3, 4, 5]); 154 | }); 155 | 156 | it("handles an array with all duplicate elements correctly", () => { 157 | const arrayWithDuplicates = [1, 1, 1, 1, 1]; 158 | const result = useRemoveDuplicates(arrayWithDuplicates); 159 | expect(result).toEqual([1]); 160 | }); 161 | 162 | it("handles an array of objects with multiple anchor keys correctly", () => { 163 | const arrayWithDuplicates = [ 164 | { id: 1, name: "a", value: 10 }, 165 | { id: 2, name: "b", value: 20 }, 166 | { id: 1, name: "a", value: 10 }, 167 | { id: 3, name: "c", value: 30 }, 168 | { id: 2, name: "b", value: 20 }, 169 | ]; 170 | const result = useRemoveDuplicates(arrayWithDuplicates, { 171 | isObject: true, 172 | anchorKeys: ["id", "name"], 173 | }); 174 | expect(result).toEqual([ 175 | { id: 1, name: "a", value: 10 }, 176 | { id: 2, name: "b", value: 20 }, 177 | { id: 3, name: "c", value: 30 }, 178 | ]); 179 | }); 180 | }); 181 | --------------------------------------------------------------------------------