Skip to content

Commit

Permalink
improve types of cfg.plugins to be more usable (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanatkn authored Oct 3, 2024
1 parent 97e0c2a commit 3725927
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/old-weeks-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ryanatkn/gro': minor
---

improve config types making `plugins` more usable
11 changes: 4 additions & 7 deletions src/docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const config: Create_Gro_Config = async (cfg) => {
// 'gro_plugin_sveltekit_app', // optional name if they don't match
);
return updated_plugins.concat(create_some_custom_plugin());
// `return get_base_plugins(ctx)` is the base behavior
};

return cfg; // return type is `Raw_Gro_Config`, which is a relaxed superset of `Gro_Config`
Expand Down Expand Up @@ -120,13 +121,9 @@ Read more about plugins and the `Plugin` in
[plugin.md](plugin.md), [dev.md](dev.md#plugin), and [build.md](build.md#plugin).

```ts
export interface Create_Config_Plugins<T_Plugin_Context extends Plugin_Context = Plugin_Context> {
(
ctx: T_Plugin_Context,
):
| (Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>)
| Promise<Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>>;
}
export type Create_Config_Plugins<T_Plugin_Context extends Plugin_Context = Plugin_Context> = (
ctx: T_Plugin_Context,
) => Array<Plugin<T_Plugin_Context>> | Promise<Array<Plugin<T_Plugin_Context>>>;
```

## `map_package_json`
Expand Down
17 changes: 9 additions & 8 deletions src/lib/gro.config.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ const config: Create_Gro_Config = async (cfg) => {
const [has_sveltekit_library_result, has_server_result, has_sveltekit_app_result] =
await Promise.all([has_sveltekit_library(), has_server(), has_sveltekit_app()]);

cfg.plugins = () => [
has_sveltekit_library_result.ok ? gro_plugin_sveltekit_library() : null,
has_server_result.ok ? gro_plugin_server() : null,
has_sveltekit_app_result.ok
? gro_plugin_sveltekit_app({host_target: has_server_result.ok ? 'node' : 'github_pages'})
: null,
gro_plugin_gen(),
];
cfg.plugins = () =>
[
has_sveltekit_library_result.ok ? gro_plugin_sveltekit_library() : null,
has_server_result.ok ? gro_plugin_server() : null,
has_sveltekit_app_result.ok
? gro_plugin_sveltekit_app({host_target: has_server_result.ok ? 'node' : 'github_pages'})
: null,
gro_plugin_gen(),
].filter((v) => v !== null);

return cfg;
};
Expand Down
2 changes: 1 addition & 1 deletion src/lib/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test('replace_plugin', () => {
test('replace_plugin without an array', () => {
const a = {name: 'a'};
const a2 = {name: 'a'};
const p = replace_plugin(a, a2);
const p = replace_plugin([a], a2);
assert.is(p[0], a2);
});

Expand Down
26 changes: 8 additions & 18 deletions src/lib/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import {to_array} from '@ryanatkn/belt/array.js';

import type {Task_Context} from './task.js';

/**
Expand All @@ -15,9 +13,7 @@ export interface Plugin<T_Plugin_Context extends Plugin_Context = Plugin_Context

export type Create_Config_Plugins<T_Plugin_Context extends Plugin_Context = Plugin_Context> = (
ctx: T_Plugin_Context,
) =>
| (Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>)
| Promise<Plugin<T_Plugin_Context> | null | Array<Plugin<T_Plugin_Context> | null>>;
) => Array<Plugin<T_Plugin_Context>> | Promise<Array<Plugin<T_Plugin_Context>>>;

export interface Plugin_Context<T_Args = object> extends Task_Context<T_Args> {
dev: boolean;
Expand All @@ -36,9 +32,7 @@ export class Plugins<T_Plugin_Context extends Plugin_Context> {
): Promise<Plugins<T_Plugin_Context>> {
const {timings} = ctx;
const timing_to_create = timings.start('plugins.create');
const instances: Plugin[] = to_array(await ctx.config.plugins(ctx)).filter(
(v) => v !== null,
) as Plugin[]; // TODO remove cast, should infer the type predicate? `Type '(Plugin<Plugin_Context<object>> | null)[]' is not assignable to type 'Plugin<Plugin_Context<object>>[]'.`
const instances: Plugin[] = await ctx.config.plugins(ctx);
const plugins = new Plugins(ctx, instances);
timing_to_create();
return plugins;
Expand Down Expand Up @@ -96,18 +90,14 @@ export class Plugins<T_Plugin_Context extends Plugin_Context> {
* @param name - @default new_plugin.name
* @returns `plugins` with `new_plugin` at the index of the plugin with `name`
*/
export const replace_plugin = <
T_Plugins extends T_Plugin | null | Array<T_Plugin | null>,
T_Plugin extends Plugin,
>(
plugins: T_Plugins,
export const replace_plugin = (
plugins: Plugin[],
new_plugin: Plugin,
name = new_plugin.name,
): T_Plugin[] => {
const array = to_array(plugins).filter((v) => v !== null);
const index = array.findIndex((p) => p.name === name);
): Plugin[] => {
const index = plugins.findIndex((p) => p.name === name);
if (index === -1) throw Error('Failed to find plugin to replace: ' + name);
const replaced = array.slice();
const replaced = plugins.slice();
replaced[index] = new_plugin;
return replaced as T_Plugin[];
return replaced;
};

0 comments on commit 3725927

Please sign in to comment.