Skip to content

Commit

Permalink
feat(helper): add macroable helper
Browse files Browse the repository at this point in the history
  • Loading branch information
jlenon7 committed Jan 22, 2025
1 parent 335c43a commit bbe35a1
Show file tree
Hide file tree
Showing 29 changed files with 624 additions and 33 deletions.
2 changes: 2 additions & 0 deletions bin/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
*/

import { Runner } from '@athenna/test'
import { expectTypeOf } from '@japa/expect-type'

await Runner.setTsEnv()
.addAssertPlugin()
.addPlugin(expectTypeOf())
.addPath('tests/unit/**/*.ts')
.setCliArgs(process.argv.slice(2))
.setGlobalTimeout(5000)
Expand Down
25 changes: 25 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"devDependencies": {
"@athenna/test": "^5.2.0",
"@athenna/tsconfig": "^5.0.0",
"@japa/expect-type": "^2.0.3",
"@types/bytes": "^3.1.5",
"@types/callsite": "^1.0.34",
"@types/deasync": "^0.1.5",
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/Clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

import { Is } from '#src/helpers/Is'
import { Options } from '#src/helpers/Options'
import { Macroable } from '#src/helpers/Macroable'

export class Clean {
export class Clean extends Macroable {
/**
* Remove all falsy values from an array.
*/
Expand Down
116 changes: 110 additions & 6 deletions src/helpers/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,119 @@ import { Collection as CollectJS } from 'collect.js'

export class Collection<T = any> extends CollectJS<T> {
/**
* An alias for macro instance method:
* Add standard property to your class prototype.
*
* @example
* Collection.macro('upperAndTrim', (value) => {
* return value.trim().toUpperCase()
* })
* ```ts
* YourClass.macro('foo', 'bar')
* ```
*/
public static macro<K extends keyof Collection>(
name: K,
value: Collection[K]
) {
this.prototype[name] = value
}

/**
* Add getters to the class prototype using the Object.defineProperty()
* method.
*
* @example
* ```ts
* YourClass.getter('foo', function foo () {
* return 'bar'
* })
*
* const singleton = true
*
* // Add singleton getter:
* YourClass.getter('foo', function foo() {
* return 'bar'
* }, singleton)
* ```
*/
public static macro(name: string, fn: any): void {
return new Collection().macro(name, fn)
public static getter<K extends keyof Collection>(
name: K,
accumulator: () => Collection[K],
singleton: boolean = false
) {
Object.defineProperty(this.prototype, name, {
get() {
const value = accumulator.call(this)

if (singleton) {
Object.defineProperty(this, name, {
configurable: false,
enumerable: false,
value,
writable: false
})
}

return value
},
configurable: true,
enumerable: false
})
}

/**
* Add a standard static property to the class itself.
*
* @example
* ```ts
* YourClass.staticMacro('foo', 'bar')
* ```
*/
public static staticMacro<K extends keyof Collection>(
name: K,
value: Collection[K]
) {
Object.defineProperty(this, name, {
value,
writable: true,
enumerable: true,
configurable: true
})
}

/**
* Add static getters to the class itself using Object.defineProperty().
*
* @example
* ```ts
* YourClass.staticGetter('foo', () => 'bar')
*
* const singleton = true
*
* // Add singleton static getter:
* YourClass.staticGetter('foo', () => 'bar', singleton)
* ```
*/
public static staticGetter<K extends keyof Collection>(
name: K,
accumulator: () => Collection[K],
singleton: boolean = false
) {
Object.defineProperty(this, name, {
get: function () {
const value = accumulator.call(this)

if (singleton) {
Object.defineProperty(this, name, {
configurable: false,
enumerable: true,
value,
writable: false
})
}

return value
},
configurable: true,
enumerable: true
})
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/Color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import { format } from 'node:util'
import { Is } from '#src/helpers/Is'
import { Chalk, type ChalkInstance } from 'chalk'
import { Macroable } from '#src/helpers/Macroable'

export class Color {
export class Color extends Macroable {
/**
* Chalk instance.
*/
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/Enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* file that was distributed with this source code.
*/

export class Enum {
import { Macroable } from '#src/helpers/Macroable'

export class Enum extends Macroable {
/**
* Get all keys from enum.
*
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/Exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import { Transform } from 'node:stream'
import { File } from '#src/helpers/File'
import { Path } from '#src/helpers/Path'
import { Options } from '#src/helpers/Options'
import { Macroable } from '#src/helpers/Macroable'
import { request as requestHttp } from 'node:http'
import { request as requestHttps } from 'node:https'
import { execa, execaNode, execaCommand, type ExecaChildProcess } from 'execa'

export class Exec {
export class Exec extends Macroable {
/**
* Sleep the code in the line that this function
* is being called.
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/FakeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { File } from '#src/helpers/File'
import { Path } from '#src/helpers/Path'
import { Json } from '#src/helpers/Json'
import { Folder } from '#src/helpers/Folder'
import { Macroable } from '#src/helpers/Macroable'
import type { FastifyInstance, HTTPMethods, RouteOptions } from 'fastify'

export class FakeApi {
export class FakeApi extends Macroable {
/**
* Set if the FakeApi server is running.
*/
Expand Down
5 changes: 4 additions & 1 deletion src/helpers/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import prependFile from 'prepend-file'

import type { StreamOptions } from 'node:stream'
import { Macroable } from '#src/helpers/Macroable'
import type { FileJson, ObjectBuilderOptions } from '#src/types'

import {
Expand Down Expand Up @@ -40,7 +41,7 @@ import { isAbsolute, parse, sep } from 'node:path'
import { Json, ObjectBuilder } from '#src/helpers/Json'
import { NotFoundFileException } from '#src/exceptions/NotFoundFileException'

export class File {
export class File extends Macroable {
/**
* The original or faked file directory.
*/
Expand Down Expand Up @@ -147,6 +148,8 @@ export class File {
mockedValues = false,
isCopy = false
) {
super()

const { ext, dir, name, base, mime, path } = File.parsePath(filePath)

this.originalDir = dir
Expand Down
6 changes: 5 additions & 1 deletion src/helpers/Folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ import { Path } from '#src/helpers/Path'
import { randomBytes } from 'node:crypto'
import { Parser } from '#src/helpers/Parser'
import { Options } from '#src/helpers/Options'
import { Macroable } from '#src/helpers/Macroable'
import { isAbsolute, join, parse, resolve, sep } from 'node:path'
import { NotFoundFolderException } from '#src/exceptions/NotFoundFolderException'

export class Folder {
export class Folder extends Macroable {
/**
* The original or faked folder directory.
*/
Expand Down Expand Up @@ -118,6 +119,8 @@ export class Folder {
public originalFolderExists: boolean

public constructor(folderPath: string, mockedValues = false, isCopy = false) {
super()

const { dir, name, path } = Folder.parsePath(folderPath)

this.files = []
Expand Down Expand Up @@ -295,6 +298,7 @@ export class Folder {
return Json.copy({
dir: this.dir,
name: this.name,
base: this.base,
path: this.path,
files: this.files.map(file => file.toJSON()),
folders: this.folders.map(folder => folder.toJSON()),
Expand Down
6 changes: 4 additions & 2 deletions src/helpers/HttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import CacheableLookup from 'cacheable-lookup'
import type { URL } from 'node:url'
import { Is } from '#src/helpers/Is'
import { Json } from '#src/helpers/Json'
import { Macroable } from '#src/helpers/Macroable'

import type { Store } from 'keyv'
import type { ClientHttp2Session } from 'http2'
Expand Down Expand Up @@ -43,13 +44,14 @@ import type {
CreateConnectionFunction
} from 'got'

export class HttpClientBuilder {
export class HttpClientBuilder extends Macroable {
/**
* Got options used to make the request.
*/
private options: Request

public constructor(options: Request = {}) {
super()
this.options = options
}

Expand Down Expand Up @@ -1187,7 +1189,7 @@ export class HttpClientBuilder {
}
}

export class HttpClient {
export class HttpClient extends Macroable {
/**
* The global builder used in all HttpClient static requests.
*/
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/Is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { Uuid } from '#src/helpers/Uuid'
import { Ulid } from '#src/helpers/Ulid'
import { String } from '#src/helpers/String'
import { Exception } from '#src/helpers/Exception'
import { Macroable } from '#src/helpers/Macroable'
import { isCep, isCnpj, isCpf } from 'validator-brazil'

export class Is {
export class Is extends Macroable {
private static styleFileRegex =
/\.(css|less|sass|scss|styl|stylus|pcss|postcss)($|\?)/

Expand Down
5 changes: 4 additions & 1 deletion src/helpers/Json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import lodash from 'lodash'

import { Is } from '#src/helpers/Is'
import { Options } from '#src/helpers/Options'
import { Macroable } from '#src/helpers/Macroable'
import type { ObjectBuilderOptions } from '#src/types'

export class ObjectBuilder {
export class ObjectBuilder extends Macroable {
/**
* The real object that is being built.
*/
Expand All @@ -26,6 +27,8 @@ export class ObjectBuilder {
public options: ObjectBuilderOptions

public constructor(options?: ObjectBuilderOptions) {
super()

this.options = Options.create(options, {
ignoreNull: false,
ignoreUndefined: true,
Expand Down
Loading

0 comments on commit bbe35a1

Please sign in to comment.