Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork0
🔧 Utils functions and classes for Node.js
License
SecJS/Utils
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Utils functions and classes to any NodeJS project
The intention behind this repository is to always maintain aUtils package with varied functions and classes to anyNodeJS project.
npm install @secjs/utils
Use the collection to work with arrays and objects.
Collectionusesthecollect.jspackage under the hood. This class offers an (almost) identical apitoLaravel Collections.
import{Collection}from'@secjs/utils'constcollection=newCollection([1,2,3])
Use File to create an instance of a File, it's existing or not.
import{File}from'@secjs/utils'// With file you can manipulate an existing file, or create a new oneconstexistentFile=newFile('path/to/existent/file.txt')constnonExistentFile=newFile('path/to/nonExistent/file.txt',Buffer.from('File content'))// Now existentFile and nonExistentFile instances are created, but not loaded/created// using load here because the file already exists, if using create, would generate an exceptionexistentFile.loadSync({withContent:true})// property withContent if true, will save the file content in the instance, Be careful with big filesnonExistentFile.createSync().loadSync({withContent:true})// now the files will have this propertiesconsole.log(existentFile.createdAt)console.log(existentFile.accessedAt)console.log(existentFile.modifiedAt)console.log(existentFile.fileSize)console.log(existentFile.content)// you can delete the file using remove methodexistentFile.removeSync()// void// you can get the content of the file with getContent methodconsole.log(existentFile.getContentSync())// Some Buffer instance// you can use toJSON method to get the instance informations in JSONconsole.log(existentFile.toJSON())// { ...infos }// you can make a copy from existentFile using copyconsole.log(existentFile.copySync('path/to/copy.txt'))// you can move existentFile to other path using moveconsole.log(existentFile.moveSync('path/to/move.txt'))// you can add content to the end of the file with appendconsole.log(existentFile.appendSync(Buffer.from('Content\n')))// you can add content to the top of the file with prependconsole.log(existentFile.prependSync(Buffer.from('Content\n')))// File uses readable streams in async methods to not block the event loop when handling huge files contentawaitexistentFile.load()awaitexistentFile.copy()awaitexistentFile.move()awaitexistentFile.remove()awaitexistentFile.create()awaitexistentFile.append()awaitexistentFile.prepend()awaitexistentFile.getContent()// You can use safeRemove method to delete the file without any exception if it does no existsawaitFile.safeRemove(existentFile.path)// You can use isFileSync to verify if path is a file or directoryawaitFile.isFileSync('package.json')// You can use existsSync to verify if file existsawaitFile.existsSync('package.json')// You can use createFileOfSize to create a fake file with determined size// 100MBawaitFile.createFileOfSize('fake.js',1024*1024*100)
Use Folder to create an instance of a Folder, it's existing or not.
import{Folder}from'@secjs/utils'// With folder you can manipulate an existing folder, or create a new oneconstexistentFolder=newFolder('path/to/existent/folder')constnonExistentFolder=newFolder('path/to/nonExistent/folder')// Now existentFolder and nonExistentFolder instances are created, but not loaded/created// using load here because the file already exists, if using create, would generate an exceptionexistentFolder.loadSync({withSub:true,withFileContent:false})// property withSub if true, will load files and subFolders from the folder// property withFileContent if true, will get the content of all files in the folder, Be careful with big filesnonExistentFolder.createSync().loadSync({withSub:true,withFileContent:true})// now the folders will have this propertiesconsole.log(existentFolder.createdAt)console.log(existentFolder.accessedAt)console.log(existentFolder.modifiedAt)console.log(existentFolder.folderSize)// you can delete the folder using remove methodexistentFolder.removeSync()// void// you can use toJSON method to get the instance informations in JSONconsole.log(existentFolder.toJSON())// { ...infos }// you can make a copy from existentFolder using copyconsole.log(existentFolder.copySync('path/to/copy'))// you can move existentFolder to other path using moveconsole.log(existentFolder.moveSync('path/to/move'))// you can use getFilesByPattern method to get all files in the folder that match some pattern// if recursive is true, will go inside subFolders tooconstrecursive=trueconsole.log(existentFolder.getFilesByPattern('**/*.ts',recursive))// [...files instance]// you can use getFoldersByPattern method to get all folders in the folder that match some patternconsole.log(existentFolder.getFoldersByPattern('**',recursive))// [...folders instance]// Folder uses readable streams in async methods to not block the event loop when handling huge files contentawaitexistentFolder.load()awaitexistentFolder.copy()awaitexistentFolder.move()awaitexistentFolder.remove()awaitexistentFolder.create()// You can use safeRemove method to delete the folder without any exception if it does no existsawaitFolder.safeRemove(existentFile.path)// You can use isFolderSync to verify if path directory or fileawaitFolder.isFolderSync('path/to/folder')// You can use existsSync to verify if folders existsawaitFolder.existsSync('path/to/folder')
Use Is to validate if value is from some type or is empty, is uuid, is cpf, is cep, etc...
import{Is}from'@secjs/utils'// Is class is a validator. It validates if the value matches the name of the function and returns a booleanIs.Empty('')// trueIs.Empty([])// trueIs.Empty([1])// falseIs.Empty({})// trueIs.Empty({hello:'world'})// falseIs.Empty(' ')// trueIs.Empty('hello')// falseIs.Json('not-valid-json')// falseIs.Ip('not-valid-ip')// falseIs.Uuid('not-valid-uuid')// falseIs.Cep('not-valid-cep')// falseIs.Cpf('not-valid-cpf')// falseIs.Cnpj('not-valid-cnpj')// falseIs.Async(()=>{})// falseIs.Async(async()=>{})// trueIs.Async(()=>{newPromise((resolve=>resolve()))})// trueIs.String('value')// trueIs.Undefined('value')// falseIs.Null('value')// falseIs.Boolean('value')// falseIs.Buffer('value')// falseIs.Number('value')// falseIs.Object('value')// falseIs.Date('value')// falseIs.Array('value')// falseIs.Regexp('value')// falseIs.Error('value')// falseIs.Function('value')// falseIs.Class('value')// falseIs.Integer('value')// falseIs.Float('value')// falseIs.ArrayOfObjects('')// falseIs.ArrayOfObjects([1,2,3])// falseIs.ArrayOfObjects([{hello:'world'}])// true
Use String to generate random strings, normalizations and case changes
import{String}from'@secjs/utils'// With String you can change the case of stringsconststring='Hello world'constcapitalize=trueString.toCamelCase(string)// 'helloWorld'String.toPascalCase(string)// 'HelloWorld'String.toNoCase(string)// 'hello world'String.toConstantCase(string)// HELLO_WORLDString.toDashCase(string)// 'hello-world'String.toDashCase(string,capitalize)// 'Hello-World'String.toDotCase(string)// 'hello.world'String.toDotCase(string,capitalize)// 'Hello.World'String.toSnakeCase(string)// 'hello_world'String.toSnakeCase(string,capitalize)// 'Hello_World'String.toSentenceCase(string)// 'Hello world'String.toSentenceCase(string,capitalize)// 'Hello World'// You can generate random strings by size and random hexadecimal colorsString.generateRandom(10)// 'GpXuZScThi'String.generateRandomColor()// '#d5063b'// You can put a string in plural or in singular and in ordinal numberString.pluralize(string)// 'Hello worlds'String.singularize(String.pluralize(string))// 'Hello world'String.ordinalize('1')// '1st'String.ordinalize('2')// '2nd'String.ordinalize('3')// '3rd'String.ordinalize('10')// '10th'// And you can also normalize base64 stringString.normalizeBase64('+++///===')// '---___'
Use exception to extend the Error object and create custom exceptions
import{Exception}from'@secjs/utils'constcontent='An error has ocurred in your application!'conststatus=500constcode='APPLICATION_ERROR'consthelp='Delete your code and start again'constexception=newException(content,status,code,help)constwithStack=trueconsole.log(exception.toJSON(withStack))/** * { * code: 'APPLICATION_ERROR', * status: 500, * content: 'An error has ocurred in your application!', * help: 'Delete your code and start again', * stack: ..., * } */console.log(awaitexception.prettify())// Pretty exception log using Youch API
Extending Exception helper
import{Exception}from'@secjs/utils'exportclassInternalServerExceptionextendsException{publicconstructor(content='An internal server error has ocurred',status=500){super(content,status)}}thrownewInternalServerException()
Use Path to get the absolute path from project folders.
import{Path}from'@secjs/utils'constsubPath='/hello'Path.pwd(subPath,beforePath)// '/home/your/computer/path/your-project-name/hello'// You can set a default before path for most Path methodsPath.defaultBeforePath='build'Path.pwd(subPath,beforePath)// '/home/your/computer/path/your-project-name/build/hello'Path.pwd('/src/')// '/home/your/computer/path/your-project-name/build/src'
Handle configurations files values inside your application ecosystem
// First you need to create your configuration file using the file template// app.tsexportdefault{name:'secjs'}// database.tsexportdefault{host:'127.0.0.1',port:Env('PORT',5432),// You can use Config.get inside this config files and Config class will handle it for youdatabase:Config.get('app.name')}
Loading configuration files and get then
// To load configuration files you need to create a instance of Configconstconfig=newConfig()// Loading database.ts will automatic load app.ts, because database.ts depends on app.tsconfig.load('database.ts')// So now we can get information of bothconsole.log(Config.get('app.name'))// 'secjs'console.log(Config.get('database.port'))// 5432console.log(Config.get('database.database'))// 'secjs'// You can call load again and you will never lose the previous statesconfig.load('example.ts')// You can also use safeLoad to not reload files that were already loadedconfig.safeLoad('app.ts')// Will just return without errors, but app.ts will not be reloaded.console.log(Config.get('app.name'))// 'secjs'
Be careful with Config.get() in configuration files
⚠️ 🛑
// Lets create this two configuration files as example// recursive-errorA.tsexportdefault{// Here we are using a property from recursive-errorBrecursive:Config.get('recursive-errorB.recursive')}// recursive-errorB.tsexportdefault{// And here we are using a property from recursive-errorArecursive:Config.get('recursive-errorA.recursive')}// If you try to load any of this two files you will get an error from Config class// Config class will start going file to file and she cant resolve any of then because one depends on the other
Use Json to parse json without errors, deep copy, observeChanges inside objects and more.
import{Json}from'@secjs/utils'consttextWithJsons='string with a Json inside of it {"text":"hello"} and one more Json {"hello":"world"}'Json.getJson(textWithJsons)// ['{"text":"hello"}', '{"hello":"world"}']consttext='a string that is not a valid JSON'Json.parse(text)// null
constobject={test:'hello',hello:()=>'hy',}constobjectCopy=Json.copy(object)objectCopy.test='hello from copy'objectCopy.hello=()=>'hy from copy'console.log(object.test)// helloconsole.log(object.hello())// hyconsole.log(objectCopy.test)// hello from copyconsole.log(objectCopy.hello())// hy from copy
constdata={}constdoSomething=(value,args)=>{console.log(`Name changed to:${value}`,args)}constargs={value:'args are the same second parameter of doSomething function'}Json.observeChanges(data,'name',doSomething,args)data.name='João'// Name changed to: João { value: 'args are the same second parameter of doSomething function' }constobject={number1:'good string',number2:'bad string',}constreadyToSaveOnDatabase=Json.fillable(object,['number1'])console.log(readyToSaveOnDatabase)// { number1: 'good string' }
constarray=[1,1,2,4,4]console.log(Json.removeDuplicated(array))// [1, 2, 4]
constarray=['a','b','c']// Array length = 2 (0, 1, 2)constraffledValue=Json.raffle(array)// Raffled value from the array, could be a, b or cconsole.log(raffledValue)// a, b or c
constobject={hello:{world:{value:{hello:'Hello World!',},},},}constvalue=Json.get(object,'hello.world.value.hello')// 'Hello World!'constundefinedValue=Json.get(object,'hello.worlld.value.hello')// undefinedconstdefaultValue=Json.get(object,'hello.worlld.value.hello','Hi World!')// 'Hi World!'constfullObject=Json.get(object,'')// Same as object { hello: { world: { value: { hello: 'Hello World!' }}}}constdefaultValueInObjectNull=Json.get(undefined,'',{hello:'world'})// { hello: 'world' }
Use Module to resolve modules exports, import modules using hrefs' ensuring compatibility between OS's, creatingaliases for your modules exports and creating __filename and __dirname properties.
import{Module}from'@secjs/utils'constmodule=awaitModule.get(import('#src/Helpers/Options'))console.log(module.name)// Options
import{Module}from'@secjs/utils'constmodules=awaitModule.getAll([import('#src/Helpers/Number'),import('#src/Helpers/Options')])console.log(modules[0].name)// Numberconsole.log(modules[1].name)// Options
import{Module}from'@secjs/utils'constmodules=awaitModule.getAllWithAlias([import('#src/Helpers/Number'),import('#src/Helpers/Options')],'App/Helpers')console.log(modules[0].module.name)// Numberconsole.log(modules[0].alias)// 'App/Helpers/Number'console.log(modules[1].module.name)// Optionsconsole.log(modules[1].alias)// 'App/Helpers/Options'
import{Path,Module}from'@secjs/utils'constmodule=awaitModule.getFrom(Path.config('app.js'))console.log(module.name)// Athennaconsole.log(module.description)// Athenna applicationconsole.log(module.environment)// production
import{Path,Module}from'@secjs/utils'constmodules=awaitModule.getAllFromWithAlias(Path.config(),'App/Configs')constappConfigFile=module[0].moduleconstappConfigAlias=module[0].aliasconsole.log(appConfigAlias)// App/Configs/Appconsole.log(appConfigFile.name)// Athennaconsole.log(appConfigFile.description)// Athenna applicationconsole.log(appConfigFile.environment)// production
import{Module}from'@secjs/utils'constsetInGlobalTrue=trueconstsetInGlobalFalse=falseconstdirname=Module.createDirname(import.meta.url,setInGlobalFalse)constfilename=Module.createFilename(import.meta.url,setInGlobalTrue)console.log(__dirname)// Error! __dirname is not defined in globalconsole.log(__filename)// '/Users/...'
Use Route to manipulate paths, getParams, getQueryParams, create route matcher RegExp etc.
import{Route}from'@secjs/utils'constabsolutePath='/tests/:id/users/:user_id'constpath='/tests/1/users/2?page=1&limit=10'Route.getQueryString(path)// ?page=1&limit=10Route.removeQueryParams(path)// /tests/1/users/2Route.getQueryParamsValue(path)// { page: '1', limit: '10' }Route.getQueryParamsName(path)// ['path', 'limit']Route.getParamsValue(absolutePath,path)// { id: '1', user_id: '10' }Route.getParamsName(absolutePath)// ['id', 'user_id']constregExpMatcher=Route.createMatcher(absolutePath)// /^(?:\/tests\b)(?:\/[\w-]+)(?:\/users\b)(?:\/[\w-]+)$/regExpMatcher.test(path)// false - because of queryParamsregExpMatcher.test(Route.removeQueryParams(path))// true
Use Number to manipulate numbers the best way
import{Number}from'@secjs/utils'constarrayOfNumbers=[2,4]conststringNumber="Hello my name is João, I'm 20 year old!"// Get the lower/higher number from the arrayconsole.log(Number.getLower(arrayOfNumbers))// 2console.log(Number.getHigher(arrayOfNumbers))// 4// Extract numbers from stringsconsole.log(Number.extractNumber(stringNumber))// '20'console.log(Number.extractNumbers(stringNumber))// ['20']// Return the average from infinite parameters or array of numbersconsole.log(Number.argsAverage(2,4))// 3console.log(Number.arrayAverage(arrayOfNumbers))// 3// Generate random integers values between intervalconsole.log(Number.randomIntFromInterval(1,1))// 1console.log(Number.randomIntFromInterval(1,2))// 1console.log(Number.randomIntFromInterval(1,2))// 2console.log(Number.randomIntFromInterval(1,10))// 8
Generate U UID tokens using a prefix, and validate it to using uuidv4 lib
import{Token}from'@secjs/utils'// Do not use the char "-", it would break token.verify() methodconstuuidGeneratedToken=Token.generate('yourServicePrefix')console.log(uuidGeneratedToken)// yourServicePrefix-c546b11c-2c2b-11eb-adc1-0242ac120002constisUuid=Token.verify(uuidGeneratedToken)console.log(isUuid)// true
Use Parser to parse all type of data of you application
import{Parser}from'@secjs/utils'// Convert a string to array using a separatorconststring1='1,2,3'constseparator=','constparsed1=Parser.stringToArray(string1,separator)console.log(parsed1)// ['1', '2', '3']
// Convert an array to string using separatorsParser.arrayToString(['1','2','3','4'])// '1, 2, 3 and 4'Parser.arrayToString(['1','2','3','4'],// '1|2|3-4'{separator:'|',lastSeparator:'-'})// Pair separator is only for two indexes arraysParser.arrayToString(['1','2'],{// '1_2'pairSeparator:'_',})
conststring2='aaaasadzczaaa21313'constparsed2=Parser.stringToNumber(string2)console.log(parsed2)// 21313
constobject={joao:'joao',email:'lenonsec7@gmail.com',}constparsed3=Parser.jsonToFormData(object)console.log(parsed3)// &joao=joao&email=lenonSec7%40gmail.com
constparsed4=Parser.formDataToJson('?joao=joao&email=lenonSec7%40gmail.com')console.log(parsed4)// { joao: 'joao', email: 'lenonsec7@gmail.com'}
constmessage='Link: https://google.com'// Convert url to and HTML hrefconsole.log(Parser.linkToHref(message))// Link: <a href="https://google.com">https://google.com</a>
// Convert number size to bytesParser.sizeToByte(1024)// '1KB'Parser.sizeToByte(1048576)// '1MB'Parser.sizeToByte(1073741824)// '1GB'Parser.sizeToByte(1099511627776)// '1TB'Parser.sizeToByte(1125899906842624)// '1PB'// Convert bytes to number sizeParser.byteToSize('1KB')// 1024Parser.byteToSize('1MB')// 1048576Parser.byteToSize('1GB')// 1073741824Parser.byteToSize('1TB')// 1099511627776Parser.byteToSize('1PB')// 1125899906842624
// Convert time string to msParser.timeToMs('2 days')// 172800000Parser.timeToMs('1d')// 86400000Parser.timeToMs('10h')// 36000000Parser.timeToMs('-10h')// -36000000Parser.timeToMs('1 year')// 31557600000Parser.timeToMs('-1 year')// -31557600000// Convert ms to time stringconstlong=trueParser.msToTime(172800000,long)// '2 days'Parser.msToTime(86400000)// 1dParser.msToTime(36000000)// 10hParser.msToTime(-36000000)// -10hParser.msToTime(31557600000,long)// 1 yearParser.msToTime(-31557600000,long)// -1 year
// Convert status code to reasonParser.statusCodeToReason(200)// OKParser.statusCodeToReason('201')// CREATEDParser.statusCodeToReason(404)// NOT_FOUNDParser.statusCodeToReason('500')// INTERNAL_SERVER_ERROR// Convert reason to status codeParser.reasonToStatusCode('OK')// 200Parser.reasonToStatusCode('created')// 201Parser.reasonToStatusCode('NOT_found')// 404Parser.reasonToStatusCode('internal server error')// 500
consturl='postgresql://postgres:root@127.0.0.1:5432/postgres?paramOne=1¶mTwo=2¶mThree=3'// Convert database connection url to connection objectconstconnectionObject=Parser.dbUrlToConnectionObj(url)/** connectionObject result * { * protocol: 'postgresql', * user: 'postgres', * password: 'root', * host: '127.0.0.1', * port: 5432, * database: 'postgres', * options: { * paramOne: '1', * paramTwo: '2', * paramThree: '3', * } * } */// Convert connection object to database connection urlconstconnectionUrl=Parser.connectionObjToDbUrl(connectionObject)/** connectionUrl result * postgresql://postgres:root@127.0.0.1:5432/postgres?paramOne=1¶mTwo=2¶mThree=3 */
Use Clean to clean arrays and objects
import{Clean}from'@secjs/utils'constarray=[null,undefined,1,"number"]console.log(Clean.cleanArray(array))// [1, "number"]constobject={number1:"number",number2:null,number3:undefined,number4:1,}constobject2={number1:null,number2:[object],}console.log(Clean.cleanObject(object))// { number1: "number", number4: 1 }console.log(Clean.cleanArraysInObject(object2))// { number2: [{ number1: "number", number4: 1 }]}
Use Debug to generate debug logs in SecJS format
import{Debug}from'@secjs/utils'constcontext='API'constnamespace='api:main'constdebug=newDebug(context,namespace)// You can still change the context/namespace of the instance in runtimedebug.buildContext(context).buildNamespace(namespace).log('Hello World!')// api:main [SecJS Debugger] - PID: 85580 - 02/15/2022, 11:47:56 AM [API] Hello World! +0ms// You can log objects too, it will be converted to string in the formatterdebug.buildContext('Object').buildNamespace('api:object').log({hello:'world'})// api:object [SecJS Debugger] - PID: 85770 - 02/15/2022, 11:53:48 AM [Object] {"hello":"world"} +0ms
Made with 🖤 byjlenon7 👋
About
🔧 Utils functions and classes for Node.js
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.

