Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: Simplify emitted declarations for plugins #104

Merged
merged 7 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .changeset/witty-poems-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
"astro-integration-kit": minor
---

Simplify emitted declarations for plugins.
Fryuni marked this conversation as resolved.
Show resolved Hide resolved

This avoids problems with too complex or non-portable types for published libraries offering plugins. Previously a simple plugin would result in a declaration like this:

```ts
declare const hookProviderPlugin: astro_integration_kit.Plugin<"hook-provider", {
'astro:config:setup': ({ config }: {
config: astro.AstroConfig;
command: "dev" | "build" | "preview";
isRestart: boolean;
updateConfig: (newConfig: DeepPartial<astro.AstroConfig>) => astro.AstroConfig;
addRenderer: (renderer: astro.AstroRenderer) => void;
addWatchFile: (path: string | URL) => void;
injectScript: (stage: astro.InjectedScriptStage, content: string) => void;
injectRoute: (injectRoute: astro.InjectedRoute) => void;
addClientDirective: (directive: astro.ClientDirectiveConfig) => void;
addDevOverlayPlugin: (entrypoint: string) => void;
addDevToolbarApp: (entrypoint: string | astro.DevToolbarAppEntry) => void;
addMiddleware: (mid: astro.AstroIntegrationMiddleware) => void;
logger: astro.AstroIntegrationLogger;
}) => {
doThing: (thing: string) => void;
};
};
```

Now, the same plugin will emit the following simplified declaration, without inlining any of the AstroHooks types:

```ts
declare const hookProviderPlugin: astro_integration_kit.Plugin<"hook-provider", {
'astro:config:setup': {
doThing: (thing: string) => void;
};
};
```

As shown above, this simplification also removes the unneded re-reclaration of the plugin hook input, which is a breaking change if you are declaring your generic explicitly.
Fryuni marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 10 additions & 12 deletions package/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import type { DevToolbarApp } from "astro";
import type { Prettify } from "../internal/types.js";

export type PluginHooksConstraint = {
[Hook in keyof Hooks]?: (
...args: Parameters<Hooks[Hook]>
) => Record<string, unknown>;
[Hook in keyof Hooks]?: Record<string, unknown>;
};

type PluginPerHookSetup<THooks extends PluginHooksConstraint> = {
[Hook in keyof THooks & keyof Hooks]: (...params: Parameters<Hooks[Hook]>) => THooks[Hook];
};

export type Plugin<
TName extends string,
THooks extends PluginHooksConstraint,
> = {
name: TName;
setup: (params: { name: string }) => THooks;
setup: (params: { name: string }) => PluginPerHookSetup<THooks>;
};

// To avoid having to call this manually for every generic
export type AnyPlugin = Plugin<string, Record<string, unknown>>;
export type AnyPlugin = Plugin<string, Record<string, any>>;

declare global {
namespace AstroIntegrationKit {
Expand All @@ -41,13 +43,9 @@ type AnyFunction = (...args: Array<any>) => any;
*/
type SimplifyPlugin<TPlugin extends AnyPlugin = AnyPlugin> = {
name: TPlugin["name"];
hooks: {
[K in keyof ReturnType<TPlugin["setup"]>]: ReturnType<
TPlugin["setup"]
>[K] extends AnyFunction
? ReturnType<ReturnType<TPlugin["setup"]>[K]>
: never;
};
hooks: TPlugin extends Plugin<any, infer THooks>
? THooks
: Record<string, never>,
};

/**
Expand Down
Loading