generated from florian-lefebvre/astro-integration-template
-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add
defineAllHooksPlugin
for plugins working on all hooks (#113)
Co-authored-by: Bryce Russell <[email protected]> Co-authored-by: Florian Lefebvre <[email protected]>
- Loading branch information
1 parent
619bced
commit 25c72f6
Showing
4 changed files
with
68 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"astro-integration-kit": minor | ||
--- | ||
|
||
Adds a new `defineAllHooksPlugin` helper for plugins that provide APIs for any hook, including third-party hooks. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { definePlugin } from "./define-plugin.js"; | ||
import type { Hooks, Plugin } from "./types.js"; | ||
|
||
export type AllHooksPluginDefinition<TName extends string, TApi extends Record<string, unknown>> = { | ||
name: TName; | ||
setup: (...params: Parameters<AllHooksPlugin<TName, TApi>['setup']>) => | ||
<H extends keyof Hooks>(hookName: H) => | ||
(...hookParams: Parameters<Hooks[H]>) => TApi; | ||
}; | ||
|
||
/** | ||
* A plugin that exposes the same API for all hooks. | ||
*/ | ||
export type AllHooksPlugin<TName extends string, TApi extends Record<string, unknown>> = Plugin< | ||
TName, | ||
Record<keyof Hooks, TApi> | ||
>; | ||
|
||
/** | ||
* Allows defining a type-safe plugin that can be used from any Astro hook. | ||
* | ||
* This wraps {@link definePlugin} and receives a factory for the API to be | ||
* called dynamically for each hook. This allows plugins to support any hook | ||
* even those added by new versions of astro or hooks added by other integrations. | ||
* | ||
* @see https://astro-integration-kit.netlify.app/utilities/define-plugin/ | ||
*/ | ||
export const defineAllHooksPlugin = <TName extends string, TApi extends Record<string, unknown>>( | ||
plugin: AllHooksPluginDefinition<TName, TApi> | ||
): AllHooksPlugin<TName, TApi> => | ||
definePlugin({ | ||
...plugin, | ||
setup: (...params) => { | ||
const hookFactory = plugin.setup(...params); | ||
|
||
return new Proxy(Object.freeze({}) as ReturnType<Plugin<any, any>['setup']>, { | ||
has: (_, prop) => typeof prop === 'string', | ||
get: (_, prop) => hookFactory(prop as keyof Hooks), | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters