Skip to content

Commit

Permalink
feat!: add support for subtyping and extra integration fields (#98)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Lefebvre <[email protected]>
Co-authored-by: Bryce Russell <[email protected]>
  • Loading branch information
3 people authored Apr 13, 2024
1 parent aabfbca commit 29d6305
Show file tree
Hide file tree
Showing 22 changed files with 470 additions and 499 deletions.
28 changes: 28 additions & 0 deletions .changeset/nasty-waves-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
"astro-integration-kit": minor
---

Updates `defineIntegration` `setup` returned object shape to allow extra properties

Previously the return of the `setup` function passed to `defineIntegration` was the Astro hooks defined by the integration, and would be set as the `hooks` property in the final integration object.

Now, the expected return of `setup` is the properties of the integration object itself:

```ts title="my-integration.ts" ins={7,11}
import { defineIntegration } from "astro-integration-kit";

export default defineIntegration({
name: "my-integration",
setup({ name }) {
return {
hooks: {
"astro:config:setup": () => {
// ...
},
},
};
},
});
```

If you are using the `withPlugins` utility, you don't need to do anything since that utility now returns the updated shape.
75 changes: 65 additions & 10 deletions docs/src/content/docs/core/define-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ export default defineIntegration({
}),
setup({ options, name }) {
return {
"astro:config:setup": (params) => {
addDts(params, {
name,
content: `declare module ${JSON.stringify(options.virtualModuleId)} {}`
})
hooks: {
"astro:config:setup": (params) => {
addDts(params, {
name,
content: `declare module ${JSON.stringify(options.virtualModuleId)} {}`
})
}
}
}
}
Expand Down Expand Up @@ -87,7 +89,7 @@ import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({
// ...
setup() {
return {}
return {hooks: {}}
}
})
```
Expand All @@ -99,7 +101,7 @@ import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({
// ...
setup({ options, name }) {
return {}
return {hooks: {}}
}
})
```
Expand All @@ -119,18 +121,71 @@ If you want to use those hooks on your integration or plugin, you can import tha

### Astro DB (`@astrojs/db`)

```ts title="my-integration/index.ts" ins={2,8-10}
```ts title="my-integration/index.ts" ins={2,9-11}
import { defineIntegration } from "astro-integration-kit";
import "astro-integration-kit/extras/db";

export default defineIntegration({
// ...
setup() {
return {
"astro:db:setup": ({ extendDb }) => {
// ...
hooks: {
"astro:db:setup": ({ extendDb }) => {
// ...
},
},
};
},
});
```

## Defining extra integration fields

Any extra property present on the return of `setup` will be present on the integration object returned by initializing the integration with the options.

You can use this to define fields you might want to access from outside your integration while having access to it's internal state.

```ts title="my-integration.ts" ins={13-20}
import { defineIntegration } from "astro-integration-kit";

export default defineIntegration({
// ...
setup() {
let counter = 0;
return {
hooks: {
"astro:config:setup": ({ logger }) => {
logger.info(`Counter: ${counter++}`);
},
},
api: {
get counter() {
return counter;
},
increment() {
counter++;
},
},
};
},
});
```

```ts
import { defineConfig } from "astro/config";
import myIntegration from "./my-integration";

const integration = myIntegration();

console.log(myIntegration.api.counter); // 0

myIntegration.api.increment();

console.log(myIntegration.api.counter); // 1

export default defineConfig({
// Will log "Counter: 1" during setup
integrations: [myIntegration],
});
```

2 changes: 1 addition & 1 deletion docs/src/content/docs/core/define-plugin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This utility is for advanced use-cases. It's useful for developers that want to
about the internals.
:::

```ts title="package/plugins/add-vite-plugin.ts"
```ts title="package/plugins/has-vite-plugin.ts"
import type { AstroConfig } from "astro";
import type { Plugin, PluginOption } from "vite";
import { definePlugin } from "astro-integration-kit";
Expand Down
16 changes: 9 additions & 7 deletions docs/src/content/docs/core/define-utility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Even though the syntax looks a bit scary, it's actually very simple!

5. Use the utility in your integration:

```ts "params" {10-13}
```ts "params" {11-14}
import { defineIntegration, createResolver, injectDevRoute } from "astro-integration-kit"

export const integration = defineIntegration({
Expand All @@ -82,15 +82,17 @@ Even though the syntax looks a bit scary, it's actually very simple!
const { resolve } = createResolver(import.meta.url)

return {
"astro:config:setup": (params) => {
injectDevRoute(params, {
pattern: "/",
entrypoint: resolve("./pages/index.astro")
})
hooks: {
"astro:config:setup": (params) => {
injectDevRoute(params, {
pattern: "/",
entrypoint: resolve("./pages/index.astro")
})
}
}
}
}
})
```

</Steps>
</Steps>
34 changes: 33 additions & 1 deletion docs/src/content/docs/core/with-plugins.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,41 @@ export default defineIntegration({
name,
plugins: [hasVitePluginPlugin],
hooks: {
"astro:config:setup": ({ hasVitePluginPlugin }) => {}
"astro:config:setup": ({ hasVitePlugin }) => {}
}
})
}
})
```

## Defining extra integration fields

Any extra property (not `name`, `plugins` or `hooks`) passed to `withPlugins` are returned unchanged.

You can use this to define fields you might want to access from outside your integration while having access to it's internal state.

```ts title="my-integration.ts" "withPlugins"
import { defineIntegration, withPlugins } from "astro-integration-kit";

export default defineIntegration({
// ...
setup() {
let counter = 0;
return withPlugins({
hooks: {
"astro:config:setup": ({ logger }) => {
logger.info(`Counter: ${counter++}`);
},
},
api: {
get counter() {
return counter;
},
increment() {
counter++;
},
},
});
},
});
```
22 changes: 12 additions & 10 deletions docs/src/content/docs/dev/hmr-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Until now, we recommended `watchIntegration` to enable HMR in development. Howev
From now on, we recommend that you use dynamic imports in your local playgrounds, alongside the new `hmrIntegration`
integration exported from `astro-integration-kit/dev`.

```ts title="package/src/integration.ts" del={3-4,10,13}
```ts title="package/src/integration.ts" del={3-4,10,14}
import {
defineIntegration,
createResolver,
Expand All @@ -21,8 +21,10 @@ export const integration = defineIntegration({
setup() {
const { resolve } = createResolver(import.meta.url)
return {
"astro:config:setup": (params) => {
watchIntegration(params, resolve())
hooks: {
"astro:config:setup": (params) => {
watchIntegration(params, resolve())
}
}
}
}
Expand All @@ -37,11 +39,11 @@ import { hmrIntegration } from "astro-integration-kit/dev";
const { default: packageName } = await import("package-name");

export default defineConfig({
integrations: [
packageName(),
hmrIntegration({
directory: createResolver(import.meta.url).resolve("../package/dist")
})
],
integrations: [
packageName(),
hmrIntegration({
directory: createResolver(import.meta.url).resolve("../package/dist")
})
],
});
```
```
31 changes: 31 additions & 0 deletions docs/src/content/docs/getting-started/upgrade-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,37 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';

Features get added and removed, and breaking changes are introduced! This documents how to migrate.

## `0.11.0`

---

### `defineIntegration` `setup` return type updated

Previously the return of the `setup` function passed to `defineIntegration` was the Astro hooks defined by the integration, and would be set as the `hooks` property in the final integration object.

Now, the expected return of `setup` is the properties of the integration object itself:

```ts title="my-integration.ts" ins={7,11}
import { defineIntegration } from "astro-integration-kit";

export default defineIntegration({
name: "my-integration",
setup({ name }) {
return {
hooks: {
"astro:config:setup": () => {
// ...
},
},
};
},
});
```

:::note
If you were using the `withPlugins` utility, you don't need to do anything since that utility now returns the updated shape.
:::

## `0.10.0`

---
Expand Down
12 changes: 7 additions & 5 deletions docs/src/content/docs/getting-started/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ export default defineIntegration({
}),
setup({ options, name }) {
return {
"astro:config:setup": (params) => {
addDts(params, {
name,
content: `declare module ${JSON.stringify(options.virtualModuleId)} {}`
})
hooks: {
"astro:config:setup": (params) => {
addDts(params, {
name,
content: `declare module ${JSON.stringify(options.virtualModuleId)} {}`
})
}
}
}
}
Expand Down
Loading

0 comments on commit 29d6305

Please sign in to comment.