Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,81 @@ console.log(sortedValue) // a, b or c

---

### Module

> Use Module to resolve modules exports, import modules using hrefs' ensuring compatibility between OS's, creating
> aliases for your modules exports and creating __filename and __dirname properties.

```ts
import { Module } from '@secjs/utils'

const module = await Module.get(import('#src/Helpers/Options'))

console.log(module.name) // Options
```

```ts
import { Module } from '@secjs/utils'

const modules = await Module.getAll([import('#src/Helpers/Number'), import('#src/Helpers/Options')])

console.log(modules[0].name) // Number
console.log(modules[1].name) // Options
```

```ts
import { Module } from '@secjs/utils'

const modules = await Module.getAllWithAlias([
import('#src/Helpers/Number'),
import('#src/Helpers/Options')
], 'App/Helpers')

console.log(modules[0].module.name) // Number
console.log(modules[0].alias) // 'App/Helpers/Number'

console.log(modules[1].module.name) // Options
console.log(modules[1].alias) // 'App/Helpers/Options'
```

```ts
import { Path, Module } from '@secjs/utils'

const module = await Module.getFrom(Path.config('app.js'))

console.log(module.name) // Athenna
console.log(module.description) // Athenna application
console.log(module.environment) // production
```

```ts
import { Path, Module } from '@secjs/utils'

const modules = await Module.getAllFromWithAlias(Path.config(), 'App/Configs')
const appConfigFile = module[0].module
const appConfigAlias = module[0].alias

console.log(appConfigAlias) // App/Configs/App
console.log(appConfigFile.name) // Athenna
console.log(appConfigFile.description) // Athenna application
console.log(appConfigFile.environment) // production
```

```ts
import { Module } from '@secjs/utils'

const setInGlobalTrue = true
const setInGlobalFalse = false

const dirname = Module.createDirname(setInGlobalFalse)
const filename = Module.createFilename(setInGlobalTrue)

console.log(__dirname) // Error! __dirname is not defined in global
console.log(__filename) // '/Users/...'
```

---

### Route

> Use Route to manipulate paths, getParams, getQueryParams, create route matcher RegExp etc.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@secjs/utils",
"version": "1.9.4",
"version": "1.9.5",
"description": "Utils functions and classes for Node.js",
"license": "MIT",
"author": "João Lenon <lenon@athenna.io>",
Expand Down Expand Up @@ -64,7 +64,7 @@
"@japa/run-failed-tests": "1.0.7",
"@japa/runner": "2.0.7",
"@japa/spec-reporter": "1.1.12",
"@otris/jsdoc-tsd": "^2.0.11",
"@otris/jsdoc-tsd": "2.0.11",
"c8": "7.11.2",
"commitizen": "4.2.4",
"cross-env": "7.0.3",
Expand Down
16 changes: 0 additions & 16 deletions src/Helpers/Exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,4 @@ export class Exec {

return { meta, links, data }
}

/**
* Get the module first export match or default.
*
* @param {any,Promise<any>} module
* @return {Promise<any>}
*/
static async getModule(module) {
module = await module

if (module.default) {
return module.default
}

return module[Object.keys(module)[0]]
}
}
188 changes: 188 additions & 0 deletions src/Helpers/Module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { dirname } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'

import { Folder } from '#src/index'

export class Module {
/**
* Get the module first export match or default.
*
* @param {any|Promise<any>} module
* @return {Promise<any>}
*/
static async get(module) {
module = await module

if (module.default) {
return module.default
}

return module[Object.keys(module)[0]]
}

/**
* Get the module first export match or default with alias.
*
* @param {any|Promise<any>} module
* @param {string} subAlias
* @return {Promise<{ alias: string, module: any }>}
*/
static async getWithAlias(module, subAlias) {
module = await Module.get(module)

if (!subAlias.endsWith('/')) {
subAlias = subAlias.concat('/')
}

const alias = subAlias.concat(module.name)

return { alias, module }
}

/**
* Get all modules first export match or default and return
* as array.
*
* @param {any[]|Promise<any[]>} modules
* @return {Promise<any[]>}
*/
static async getAll(modules) {
const promises = modules.map(m => Module.get(m))

return Promise.all(promises)
}

/**
* Get all modules first export match or default with alias and return
* as array.
*
* @param {any[]|Promise<any[]>} modules
* @param {string} subAlias
* @return {Promise<any[]>}
*/
static async getAllWithAlias(modules, subAlias) {
const promises = modules.map(m => Module.getWithAlias(m, subAlias))

return Promise.all(promises)
}

/**
* Same as get method, but import the path directly.
*
* @param {string} path
* @return {Promise<any>}
*/
static async getFrom(path) {
const module = await Module.import(path)

return Module.get(module)
}

/**
* Same as getWithAlias method, but import the path directly.
*
* @param {string} path
* @param {string} subAlias
* @return {Promise<{ alias: string, module: any }>}
*/
static async getFromWithAlias(path, subAlias) {
const module = await Module.import(path)

return Module.getWithAlias(module, subAlias)
}

/**
* Same as getAll method but import everything in the path directly.
*
* @param {string} path
* @return {Promise<any[]>}
*/
static async getAllFrom(path) {
const files = await Module.getAllJSFilesFrom(path)

const promises = files.map(file => Module.getFrom(file.path))

return Promise.all(promises)
}

/**
* Same as getAllWithAlias method but import everything in the path directly.
*
* @param {string} path
* @param {string} subAlias
* @return {Promise<{ alias: string, module: any }[]>}
*/
static async getAllFromWithAlias(path, subAlias) {
const files = await Module.getAllJSFilesFrom(path)

const promises = files.map(f => Module.getFromWithAlias(f.path, subAlias))

return Promise.all(promises)
}

/**
* Verify if folder exists and get all .js files inside.
*
* @param {string} path
* @return {Promise<File[]>}
*/
static async getAllJSFilesFrom(path) {
if (!(await Folder.exists(path))) {
return []
}

if (!(await Folder.isFolder(path))) {
return []
}

const folder = await new Folder(path).load()

// FIXME Why glob pattern *.js is retrieving .d.ts and .js.map files?
return folder
.getFilesByPattern('*/**/*.js', true)
.filter(file => file.extension.endsWith('.js'))
}

/**
* Import a full path using the path href to ensure compatibility
* between OS's.
*
* @param {string} path
* @return {Promise<any>}
*/
static async import(path) {
return import(pathToFileURL(path).href)
}

/**
* Create the __dirname property. Set in global if necessary.
*
* @param {boolean} setInGlobal
* @return {string}
*/
static createDirname(setInGlobal = false) {
const __dirname = dirname(Module.createFilename(false))

if (setInGlobal) {
global.__dirname = __dirname
}

return __dirname
}

/**
* Create the __filename property. Set in global if necessary.
*
* @param {boolean} setInGlobal
* @return {string}
*/
static createFilename(setInGlobal = false) {
const __filename = fileURLToPath(import.meta.url)

if (setInGlobal) {
global.__filename = __filename
}

return __filename
}
}
31 changes: 28 additions & 3 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,6 @@ export declare class Exec {
total: number,
pagination: PaginationContract,
): PaginatedResponse

static getModule(module: any | Promise<any>): Promise<any>
}

export declare class File {
Expand All @@ -170,7 +168,7 @@ export declare class File {
public base: string

public path: string

public href: string

public isCopy: boolean
Expand Down Expand Up @@ -416,6 +414,33 @@ export declare class Json {
static get(object: any, key: string, defaultValue?: any): any | undefined
}

export class Module {
static get(module: any | Promise<any>): Promise<any>

static getWithAlias(module: any | Promise<any>, subAlias: string): Promise<{ alias: string, module: any }>

static getAll(modules: any[] | Promise<any[]>): Promise<any[]>

static getAllWithAlias(modules: any[] | Promise<any[]>, subAlias: string): Promise<{ alias: string, module: any }[]>

static getFrom(path: string): Promise<any>

static getFromWithAlias(path: string, subAlias: string): Promise<{ alias: string, module: any }>

static getAllFrom(path: string): Promise<any>

static getAllFromWithAlias(path: string, subAlias: string): Promise<{ alias: string, module: any }[]>

static getAllJSFilesFrom(path: string): Promise<File[]>

static import(path: string): Promise<any>

static createDirname(setInGlobal?: boolean): string

static createFilename(setInGlobal?: boolean): string
}


export declare class Number {
static getHigher(numbers: number[]): number

Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export * from './Helpers/File.js'
export * from './Helpers/Folder.js'
export * from './Helpers/Is.js'
export * from './Helpers/Json.js'
export * from './Helpers/Module.js'
export * from './Helpers/Number.js'
export * from './Helpers/Options.js'
export * from './Helpers/Parser.js'
Expand Down
Loading