Modular Station - API
This utility allows you, as an integration author, to expose APIs for other integrations that might be in use alogside yours. Instead of requiring them to call addIntegration
instantiating yours, which has multiple limitations, they can use the API from your integration regardless of how it was installed.
How to use as an author
Assuming you already have an integration, you can just wrap it in the withApi
function to give it superpowers:
import { withApi } from '@inox-tools/modular-station';
export default (options: Options) => {export default withApi((options: Options) => { const sharedState = ...;
return { hooks: { // ... using the shared state }, };};});
With this, you can now expose APIs alongside your hooks:
import { withApi } from '@inox-tools/modular-station';
export default withApi((options: Options) => { const sharedState = ...;
return { hooks: { // ... using the shared state }, addSomething(thing: string) { // add the thing to shared state }, };});
onHook
By default, accessing your API from any hook besides astro:config:setup
using the AIK plugin will throw an error. This is because that is the only hook where nearly everything can be done in Astro’s lifecycle.
If you have an API that also works when called from other hooks, you can wrap them with onHook
to declare which hooks are supported. For example, if you expose a method to register information that is only used on astro:build:start
you can allow it to be used on any hook before that:
import { withApi, onHook } from '@inox-tools/modular-station';
export default withApi((options: Options) => { const sharedState = ...;
return { hooks: { // ... using the shared state }, addSomething: onHook([ 'astro:config:setup', 'astro:config:done', 'astro:build:setup', ], (thing: string) { // add the thing to shared state }), };});
How to use as a consumer
To use the APIs provided by an integration on your own, you have multiple options.
Without Astro Integration Kit (the boring way)
If you don’t use Astro Integration Kit, first off you should, but if you really don’t want to have an easy life, read ahead.
On your astro:config:setup
or astro:config:done
hooks you can get the API from the provided AstroConfig
like so:
import otherIntegration from 'other-integration';
export default () => { return { name: 'my-integration', hooks: { 'astro:config:setup': ({ config }) => { const api = otherIntegration.fromConfig(config);
api?.addSomething(); }, }, };};
The API might be null
if the integration is not present. If needed, you can instantiate and add the integration yourself or use the optional API.
With Astro Integration Kit (the fun way)
Integration providing APIs using Modular Station can be used as AIK Plugins. You can use as either an optional plugin or a required plugin.
Optional plugin
You can call asOptionalPlugin
on integrations using Modular Station to get an AIK Plugin that exposes that integration’s API under a name of your choosing. If the integration is not present, the value in your hooks will be null.
Contrary to the method without AIK, this allows the API to be used on any hook:
import { withPlugins } from 'astro-integration-kit';import otherIntegration from 'other-integration';
export default () => { return withPlugins({ name: 'my-integration', plugins: [otherIntegration.asOptionalPlugin('otherApi')] hooks: { 'astro:config:setup': ({ otherApi }) => { otherApi?.addSomething(); }, 'astro:server:start': ({ otherApi }) => { otherApi?.addSomething(); }, }, };};
Required plugin
You can call asPlugin
on integrations using Modular Station to get an AIK Plugin that exposes that integration’s API under a name of your choosing. If the integration is not present, it will be added using the provided options. You must always provide the options even if it is already installed because that check happens later.
import { withPlugins } from 'astro-integration-kit';import otherIntegration from 'other-integration';
export default () => { return withPlugins({ name: 'my-integration', plugins: [otherIntegration.asPlugin('otherApi', {foo: 'bar'})] hooks: { 'astro:config:setup': ({ otherApi }) => { otherApi.addSomething(); }, 'astro:server:start': ({ otherApi }) => { otherApi.addSomething(); }, }, };};