Skip to content

Commit

Permalink
✨ feat(minor): add bud.before method (#2606)
Browse files Browse the repository at this point in the history
Add bud.before method, docs, tests.

## Type of change

**PATCH: backwards compatible change**
  • Loading branch information
kellymears authored Jun 25, 2024
1 parent 38e8844 commit 8e19fac
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
80 changes: 80 additions & 0 deletions sources/@repo/docs/content/reference/bud.before/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: bud.before
description: Do something before compilation has started
tags:
- facade
- lifecycle
---

import ConfigExample from '@site/src/components/example';

**bud.before** allows you to execute arbitrary code directly prior to the start of the compilation process.

## Usage

Using an asyncronous function:

<ConfigExample title="bud.config">

```ts
bud.before(async bud => {
// Do something before the compilation has completed
})
```

```js
bud.before(async bud => {
// Do something before the compilation has completed
})
```

```yml
before: >
=> async bud => {
// do someting before the compilation has started
}
```
```json
{
"before": "=> async bud => {
// do something before the compilation has started
}"
}
```

</ConfigExample>

Using a synchronous function:


<ConfigExample title="bud.config">

```ts
bud.before(bud => {
// Do something before the compilation has completed
})
```

```js
bud.before(bud => {
// Do something before the compilation has completed
})
```

```yml
before: >
=> bud => {
// do someting before the compilation has started
}
```
```json
{
"before": "=> bud => {
// do something before the compilation has started
}"
}
```

</ConfigExample>
37 changes: 37 additions & 0 deletions sources/@roots/bud-framework/src/methods/before/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Bud} from '@roots/bud-framework'

declare module '@roots/bud-framework' {
interface Bud {
/**
* Execute a function before compiler has finished
*/
before: before
}
}

export interface before {
(
callback: ((app: Bud) => Promise<unknown>) | ((app: Bud) => unknown),
onError?: (error: Error) => unknown,
): Bud
}

/**
* Execute a function before compiler has finished
*/
export const before: before = function (
this: Bud,
fn: ((app: Bud) => any) | ((app: Bud) => Promise<any>),
onError?: (error: Error) => unknown,
): Bud {
this.hooks.action(`compiler.before`, async bud => {
try {
await bud.resolvePromises()
await fn(bud)
} catch (error) {
onError ? onError(error) : bud.catch(error)
}
})

return this
}
2 changes: 2 additions & 0 deletions sources/@roots/bud-framework/src/methods/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {Bud} from '@roots/bud-framework'

import {addConfig} from '@roots/bud-framework/methods/addConfig'
import {after} from '@roots/bud-framework/methods/after'
import {before} from '@roots/bud-framework/methods/before'
import {bindFacade} from '@roots/bud-framework/methods/bindFacade'
import {close} from '@roots/bud-framework/methods/close'
import {container} from '@roots/bud-framework/methods/container'
Expand Down Expand Up @@ -32,6 +33,7 @@ type methods = Partial<{
const methods = {
addConfig,
after,
before,
bindFacade,
close,
container,
Expand Down
46 changes: 46 additions & 0 deletions sources/@roots/bud-framework/test/methods/before/before.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {type Bud, factory} from '@repo/test-kit'
import {beforeAll, describe, expect, it, vi} from 'vitest'

import {before as subject} from '../../../src/methods/before/index.js'

describe(`@roots/bud-framework/methods/before`, function () {
let before: subject
let bud: Bud

beforeAll(async () => {
bud = await factory()
before = subject.bind(bud)
})

it(`should be a function`, () => {
expect(before).toBeInstanceOf(Function)
})

it(`should return bud`, async () => {
const value = before(async () => {})
expect(value).toBe(bud)
})

it(`should call the callback`, async () => {
const fn = vi.fn(async () => null)
before(fn)
await bud.hooks.fire(`compiler.before`, bud)
expect(fn).toHaveBeenCalled()
})

it(`should work with a synchronous callback`, async () => {
const fn = vi.fn()
before(fn)
await bud.hooks.fire(`compiler.before`, bud)
expect(fn).toHaveBeenCalled()
})

it(`should call the error handler if supplied`, async () => {
const onError = vi.fn()
before(() => {
throw new Error(`test`)
}, onError)
await bud.hooks.fire(`compiler.before`, bud)
expect(onError).toHaveBeenCalled()
})
})

0 comments on commit 8e19fac

Please sign in to comment.