@asterflow/plugin 1.0.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,148 +4,63 @@
4
4
 
5
5
  ![license-info](https://img.shields.io/github/license/AsterFlow/AsterFlow?style=for-the-badge&colorA=302D41&colorB=f9e2af&logoColor=f9e2af)
6
6
  ![stars-info](https://img.shields.io/github/stars/AsterFlow/AsterFlow?colorA=302D41&colorB=f9e2af&style=for-the-badge)
7
- ![last-commit](https://img.shields.io/github/last-commit/AsterFlow/AsterFlow?path=packages%2Fresponse&style=for-the-badge&colorA=302D41&colorB=b4befe)
7
+ ![last-commit](https://img.shields.io/github/last-commit/AsterFlow/AsterFlow?path=packages%2Fplugin&style=for-the-badge&colorA=302D41&colorB=b4befe)
8
8
 
9
9
  ![bundle-size](https://img.shields.io/bundlejs/size/@asterflow/plugin?style=for-the-badge&colorA=302D41&colorB=3ac97b)
10
10
 
11
11
  </div>
12
12
 
13
- > A modular and typed plugin system for extending AsterFlow functionality.
13
+ > The plugin-authoring system used to build AsterFlow plugins - a typed builder for context, config and lifecycle hooks.
14
14
 
15
15
  ## 📦 Installation
16
16
 
17
17
  ```bash
18
- npm install @asterflow/plugin
19
- # or
20
18
  bun install @asterflow/plugin
21
19
  ```
22
20
 
23
- ## 💡 About
21
+ ### Features
24
22
 
25
- `@asterflow/plugin` provides a robust and typed system for extending AsterFlow's functionality. It allows developers to create modular plugins that can inject context, manipulate configurations, and react to application lifecycle events, ensuring seamless and type-safe integration.
23
+ - **Fluent builder:** chain `.config()`, `.decorate()`, `.derive()`, `.extends()` and `.on()` off a single `Plugin.create({ name })` call.
24
+ - **Typed config with defaults:** `.config()` sets the plugin's default config and infers its shape.
25
+ - **Static and derived context:** `.decorate()` injects a fixed value; `.derive()` computes a value from the config and context already built, lazily, when the plugin is registered.
26
+ - **Instance extensions:** `.extends()` adds new properties/methods to the AsterFlow instance, computed from the app and the plugin's context.
27
+ - **Lifecycle hooks:** `.on()` registers handlers for `beforeInitialize`, `afterInitialize`, `onRequest` and `onResponse`.
28
+ - **Type inference end-to-end:** every chained call narrows a single `Props` type, so config, context and extensions stay typed without manual generics.
26
29
 
27
- ## Features
30
+ ## How to Use
28
31
 
29
- - **Extensible Plugin System:** Create modular plugins to add custom functionalities to AsterFlow.
30
- - **Dynamic Context:** Inject static values into the plugin's context (`decorate`) or derive complex properties based on configuration and existing context (`derive`).
31
- - **Lifecycle Hooks:** Register handlers for specific AsterFlow application events (such as `beforeInitialize`, `afterInitialize`, `onRequest`, and `onResponse`) to extend behavior at different stages.
32
- - **Typed Configuration:** Define the plugin's configuration structure and its default values, with automatic type inference.
33
- - **Type Safety:** Full TypeScript support to ensure your plugin's context, configuration, and hooks are type-safe.
34
- - **Runtime Optimization:** Hooks are efficiently invoked only when the plugin is registered, allowing for performance optimizations.
32
+ Build a plugin with `Plugin.create`, then chain the pieces it needs. This one adds a config option and exposes a method on the AsterFlow instance:
35
33
 
36
- ## 🚀 Usage
37
-
38
- `@asterflow/plugin` enables the creation of plugins that extend `AsterFlow` in a modular and type-safe manner. Below are examples of how to create and use plugins.
39
-
40
- ### Creating a Basic Plugin
41
-
42
- ```typescript
43
- import { Plugin } from '@asterflow/plugin'
44
-
45
- const myPlugin = Plugin.create({ name: 'my-first-plugin' })
46
- .decorate('appName', 'My AsterFlow Application') // Adds a static value to the plugin's context
47
- .on('beforeInitialize', (app, context) => {
48
- console.log(`Initializing ${context.appName}...`)
49
- // app is the AsterFlow instance
50
- })
51
- .on('afterInitialize', (app, context) => {
52
- console.log(`${context.appName} has been initialized!`)
53
- })
54
-
55
- // This plugin can now be registered with `app.use(myPlugin)`
56
- ```
57
-
58
- ### Using Configuration and Derivation
59
-
60
- Plugins can be configured and can derive values based on their configuration or existing context.
61
-
62
- ```typescript
34
+ ```ts
63
35
  import { Plugin } from '@asterflow/plugin'
64
36
 
65
- interface FeaturePluginConfig {
66
- featureEnabled: boolean;
67
- featureName: string;
68
- }
69
-
70
- const featureTogglePlugin = Plugin.create({ name: 'feature-toggle' })
71
- .withConfig<FeaturePluginConfig>({
72
- featureEnabled: true,
73
- featureName: 'Awesome Feature'
74
- })
75
- .derive('statusMessage', (context) => {
76
- return context.featureEnabled
77
- ? `${context.featureName} is enabled.`
78
- : `${context.featureName} is disabled.`
79
- })
80
- .on('beforeInitialize', (app, context) => {
81
- console.log(context.statusMessage) // "Awesome Feature is enabled."
82
- })
83
-
84
- // This plugin can be configured when registered:
85
- // app.use(featureTogglePlugin, { featureEnabled: false })
37
+ export const fsRoutingPlugin = Plugin.create({ name: 'fs-routing' })
38
+ .config({ routes: [] as unknown[] })
39
+ .extends((instance, context) => ({
40
+ registerRoutes() {
41
+ for (const route of context.routes) instance.controller(route)
42
+ }
43
+ }))
44
+ .on('beforeInitialize', (instance, context) => instance.registerRoutes())
86
45
  ```
87
46
 
88
- ### Lifecycle Hooks
47
+ `.decorate()` and `.derive()` build up the plugin's context the same way - `decorate` for a static value, `derive` for one computed from config/context:
89
48
 
90
- Hooks allow plugins to react to important events in the `AsterFlow` lifecycle.
91
-
92
- ```typescript
93
- import { Plugin } from '@asterflow/plugin'
94
- import { Request } from '@asterflow/request'
95
- import { Response } from '@asterflow/response'
96
-
97
- const loggerPlugin = Plugin.create({ name: 'logger-plugin' })
98
- .on('onRequest', (request, response, context) => {
99
- // Logs request details
100
- console.log(`[REQ] ${request.getMethod()} ${request.getPathname()}`)
101
- })
102
- .on('onResponse', (request, response, context) => {
103
- // Logs response details
104
- console.log(`[RES] ${response.getStatus()} ${request.getPathname()}`)
105
- })
106
-
107
- // Register this plugin for global logging
108
- // app.use(loggerPlugin)
49
+ ```ts
50
+ const withGreeting = Plugin.create({ name: 'greeting' })
51
+ .decorate('appName', 'My App')
52
+ .derive('greeting', (context) => `Hello, ${context.appName}!`)
53
+ .on('afterInitialize', (_app, context) => console.log(context.greeting))
109
54
  ```
110
55
 
111
- ### Integrating with AsterFlow
112
-
113
- To use the created plugins, you register them with the `AsterFlow` instance.
114
-
115
- ```typescript
116
- import { AsterFlow } from 'asterflow'
117
- import { adapters } from '@asterflow/adapter'
118
- import fastify from 'fastify'
119
- // Import your plugins here
120
- // import { myPlugin, featureTogglePlugin, loggerPlugin } from './your-plugins'
121
-
122
- const server = fastify()
123
- const app = new AsterFlow({
124
- driver: adapters.fastify
125
- })
126
-
127
- // Example plugin registration
128
- app.use(myPlugin) // No additional configuration
129
- app.use(featureTogglePlugin, { featureEnabled: false }) // With overridden configuration
130
- app.use(loggerPlugin)
131
-
132
- app.listen(server, { port: 3000 }, (err) => {
133
- if (err) {
134
- console.error(err)
135
- process.exit(1)
136
- }
137
- console.log('AsterFlow server with plugins listening on port 3000!')
138
- })
139
- ```
56
+ The finished plugin is registered on an app with `app.use(fsRoutingPlugin, { routes: [...] })`.
140
57
 
141
58
  ## 🔗 Related Packages
142
59
 
143
- - [asterflow](https://www.npmjs.com/package/asterflow) - The heart of the AsterFlow framework.
144
- - [@asterflow/adapter](https://www.npmjs.com/package/@asterflow/adapter) - HTTP adapters for different runtimes.
145
- - [@asterflow/router](https://www.npmjs.com/package/@asterflow/router) - Type-safe routing system.
146
- - [@asterflow/request](https://www.npmjs.com/package/@asterflow/request) - Unified HTTP request system.
147
- - [@asterflow/response](https://www.npmjs.com/package/@asterflow/response) - Type-safe HTTP response system.
60
+ - Depended on by [asterflow](https://www.npmjs.com/package/asterflow) - the core framework consumes plugin instances and their types to power `app.use()`.
61
+ - Depended on by [@asterflow/multipart](https://www.npmjs.com/package/@asterflow/multipart) - built as a plugin with `Plugin.create()`.
62
+ - Depended on by `@asterflow/fs` - built as a plugin with `Plugin.create()`.
148
63
 
149
64
  ## 📄 License
150
65
 
151
- MIT - See [LICENSE](https://github.com/AsterFlow/AsterFlow/blob/main/LICENSE) for more details.
66
+ This project is licensed under the [MIT License](../../LICENSE).
@@ -1,34 +1,34 @@
1
1
  "use strict";
2
- var r = Object.defineProperty;
3
- var f = Object.getOwnPropertyDescriptor;
4
- var u = Object.getOwnPropertyNames;
2
+ var i = Object.defineProperty;
3
+ var c = Object.getOwnPropertyDescriptor;
4
+ var l = Object.getOwnPropertyNames;
5
5
  var d = Object.prototype.hasOwnProperty;
6
- var g = (o, e) => {
6
+ var f = (t, e) => {
7
7
  for (var n in e)
8
- r(o, n, { get: e[n], enumerable: !0 });
9
- }, h = (o, e, n, t) => {
8
+ i(t, n, { get: e[n], enumerable: !0 });
9
+ }, u = (t, e, n, o) => {
10
10
  if (e && typeof e == "object" || typeof e == "function")
11
- for (let s of u(e))
12
- !d.call(o, s) && s !== n && r(o, s, { get: () => e[s], enumerable: !(t = f(e, s)) || t.enumerable });
13
- return o;
11
+ for (let s of l(e))
12
+ !d.call(t, s) && s !== n && i(t, s, { get: () => e[s], enumerable: !(o = c(e, s)) || o.enumerable });
13
+ return t;
14
14
  };
15
- var x = (o) => h(r({}, "__esModule", { value: !0 }), o);
15
+ var g = (t) => u(i({}, "__esModule", { value: !0 }), t);
16
16
  // packages/plugin/src/index.ts
17
- var y = {};
18
- g(y, {
17
+ var h = {};
18
+ f(h, {
19
19
  Plugin: () => a
20
20
  });
21
- module.exports = x(y);
21
+ module.exports = g(h);
22
22
  // packages/plugin/src/controllers/Plugin.ts
23
- var a = class o {
23
+ var a = class t {
24
24
  name;
25
25
  resolvers;
26
26
  defaultConfig;
27
27
  hooks = {};
28
28
  instance;
29
29
  _extensionFn;
30
- constructor(e, n, t, s, i) {
31
- this.name = e, this.resolvers = n, this.hooks = t, this.defaultConfig = s, this._extensionFn = i;
30
+ constructor(e, n, o, s, r) {
31
+ this.name = e, this.resolvers = n, this.hooks = o, this.defaultConfig = s, this._extensionFn = r;
32
32
  }
33
33
  config(e) {
34
34
  return this.defaultConfig = {
@@ -40,32 +40,32 @@ var a = class o {
40
40
  return this.instance = e, this;
41
41
  }
42
42
  decorate(e, n) {
43
- let t = async (s, i) => ({
44
- ...i,
43
+ let o = async (s, r) => ({
44
+ ...r,
45
45
  [e]: n
46
46
  });
47
- return this.resolvers = [...this.resolvers, t], this;
47
+ return this.resolvers = [...this.resolvers, o], this;
48
48
  }
49
49
  derive(e, n) {
50
- let t = async (s, i) => {
51
- let c = { ...i, ...s }, l = await n(c);
50
+ let o = async (s, r) => {
51
+ let P = { ...r, ...s }, p = await n(P);
52
52
  return {
53
- ...i,
54
- [e]: l
53
+ ...r,
54
+ [e]: p
55
55
  };
56
56
  };
57
- return this.resolvers = [...this.resolvers, t], this;
57
+ return this.resolvers = [...this.resolvers, o], this;
58
58
  }
59
59
  on(e, n) {
60
- let t = this.hooks[e] || [];
60
+ let o = this.hooks[e] || [];
61
61
  return this.hooks = {
62
62
  ...this.hooks,
63
- [e]: [...t, n]
63
+ [e]: [...o, n]
64
64
  }, this;
65
65
  }
66
66
  extends(e) {
67
67
  let n = this._extensionFn;
68
- return this._extensionFn = (t, s) => ({ ...n ? n(t, s) : {}, ...e(t, s) }), this;
68
+ return this._extensionFn = (o, s) => ({ ...n ? n(o, s) : {}, ...e(o, s) }), this;
69
69
  }
70
70
  _build(e) {
71
71
  let n = { ...this.defaultConfig, ...e };
@@ -78,7 +78,7 @@ var a = class o {
78
78
  };
79
79
  }
80
80
  static create(e) {
81
- return new o(e.name, [], {}, {}, void 0);
81
+ return new t(e.name, [], {}, {}, void 0);
82
82
  }
83
83
  };
84
84
  0 && (module.exports = {
package/dist/mjs/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  // packages/plugin/src/controllers/Plugin.ts
2
- var i = class r {
2
+ var r = class i {
3
3
  name;
4
4
  resolvers;
5
5
  defaultConfig;
6
6
  hooks = {};
7
7
  instance;
8
8
  _extensionFn;
9
- constructor(e, n, t, s, o) {
10
- this.name = e, this.resolvers = n, this.hooks = t, this.defaultConfig = s, this._extensionFn = o;
9
+ constructor(e, n, o, s, t) {
10
+ this.name = e, this.resolvers = n, this.hooks = o, this.defaultConfig = s, this._extensionFn = t;
11
11
  }
12
12
  config(e) {
13
13
  return this.defaultConfig = {
@@ -19,32 +19,32 @@ var i = class r {
19
19
  return this.instance = e, this;
20
20
  }
21
21
  decorate(e, n) {
22
- let t = async (s, o) => ({
23
- ...o,
22
+ let o = async (s, t) => ({
23
+ ...t,
24
24
  [e]: n
25
25
  });
26
- return this.resolvers = [...this.resolvers, t], this;
26
+ return this.resolvers = [...this.resolvers, o], this;
27
27
  }
28
28
  derive(e, n) {
29
- let t = async (s, o) => {
30
- let a = { ...o, ...s }, c = await n(a);
29
+ let o = async (s, t) => {
30
+ let a = { ...t, ...s }, P = await n(a);
31
31
  return {
32
- ...o,
33
- [e]: c
32
+ ...t,
33
+ [e]: P
34
34
  };
35
35
  };
36
- return this.resolvers = [...this.resolvers, t], this;
36
+ return this.resolvers = [...this.resolvers, o], this;
37
37
  }
38
38
  on(e, n) {
39
- let t = this.hooks[e] || [];
39
+ let o = this.hooks[e] || [];
40
40
  return this.hooks = {
41
41
  ...this.hooks,
42
- [e]: [...t, n]
42
+ [e]: [...o, n]
43
43
  }, this;
44
44
  }
45
45
  extends(e) {
46
46
  let n = this._extensionFn;
47
- return this._extensionFn = (t, s) => ({ ...n ? n(t, s) : {}, ...e(t, s) }), this;
47
+ return this._extensionFn = (o, s) => ({ ...n ? n(o, s) : {}, ...e(o, s) }), this;
48
48
  }
49
49
  _build(e) {
50
50
  let n = { ...this.defaultConfig, ...e };
@@ -57,9 +57,9 @@ var i = class r {
57
57
  };
58
58
  }
59
59
  static create(e) {
60
- return new r(e.name, [], {}, {}, void 0);
60
+ return new i(e.name, [], {}, {}, void 0);
61
61
  }
62
62
  };
63
63
  export {
64
- i as Plugin
64
+ r as Plugin
65
65
  };
@@ -1,20 +1,22 @@
1
1
  import type { AnyAsterflow, ExtendedAsterflow } from 'asterflow';
2
- import type { PluginHooks, Resolver } from '../types/plugin';
3
- import type { Prettify, UnionToIntersection } from '../types/utils';
4
- export declare class Plugin<Path extends string = string, Instance extends AnyAsterflow = AnyAsterflow, Config extends Record<string, any> = {}, Decorate extends Record<string, any> = {}, Derive extends Record<string, any> = {}, Extension extends Record<string, any> = {}> {
5
- readonly name: Path;
2
+ import type { DefaultPluginProps, PluginHooks, PluginProps, Resolver } from '../types/plugin';
3
+ import type { MergeProps, Prettify, UnionToIntersection } from '../types/utils';
4
+ export declare class Plugin<const Props extends PluginProps = DefaultPluginProps> {
5
+ readonly name: Props['path'];
6
6
  resolvers: Resolver[];
7
- defaultConfig: Partial<Config>;
8
- hooks: PluginHooks<any, Decorate, any>;
9
- instance: Instance;
7
+ defaultConfig: Partial<Props['config']>;
8
+ hooks: PluginHooks<any, Props['decorate'], any>;
9
+ instance: Props['instance'];
10
10
  private _extensionFn?;
11
11
  private constructor();
12
12
  /**
13
13
  * Defines the shape of the configuration and its default values for this plugin.
14
14
  */
15
- config<C extends Record<string, any>>(defaultConfig: C): Plugin<Path, Instance, Prettify<UnionToIntersection<{
16
- defaultConfig: C;
17
- } | C | Config>>, Decorate, Derive, Extension>;
15
+ config<C extends Record<string, any>>(defaultConfig: C): Plugin<MergeProps<Props, {
16
+ config: Prettify<UnionToIntersection<{
17
+ defaultConfig: C;
18
+ } | C | Props["config"]>>;
19
+ }>>;
18
20
  /**
19
21
  * O `defineInstance` agora é mais simples. Ele não precisa mais re-tipar
20
22
  * a classe inteira. Ele só serve para passar o `this` para o `_build`.
@@ -23,12 +25,16 @@ export declare class Plugin<Path extends string = string, Instance extends AnyAs
23
25
  /**
24
26
  * Adds a new static value to the plugin's context (decoration).
25
27
  */
26
- decorate<Key extends string, Value>(key: Key, value: Value): Plugin<Path, Instance, Config, Prettify<UnionToIntersection<Decorate | { [K in Key]: Value; }>>, Derive, Extension>;
28
+ decorate<Key extends string, Value>(key: Key, value: Value): Plugin<MergeProps<Props, {
29
+ decorate: Prettify<UnionToIntersection<Props["decorate"] | { [K in Key]: Value; }>>;
30
+ }>>;
27
31
  /**
28
32
  * Adds a new property to the context that is derived from the configuration and the existing context.
29
33
  * The resolver function is executed lazily when the plugin is registered via `app.use()`.
30
34
  */
31
- derive<Key extends string, Value>(key: Key, resolverFn: (context: Derive & Config & Decorate) => Value | Promise<Value>): Plugin<Path, Instance, Config, Decorate, Prettify<UnionToIntersection<Derive | { [K in Key]: Awaited<Value>; }>>, Extension>;
35
+ derive<Key extends string, Value>(key: Key, resolverFn: (context: Props['derive'] & Props['config'] & Props['decorate']) => Value | Promise<Value>): Plugin<MergeProps<Props, {
36
+ derive: Prettify<UnionToIntersection<Props["derive"] | { [K in Key]: Awaited<Value>; }>>;
37
+ }>>;
32
38
  /**
33
39
  * Registers a handler for a specific lifecycle event.
34
40
  * Adding a hook makes the plugin "runtime-aware". AsterFlow can optimize by only
@@ -39,21 +45,23 @@ export declare class Plugin<Path extends string = string, Instance extends AnyAs
39
45
  * .on('beforeInitialize', (app, context) => { })
40
46
  * .on('beforeInitialize', (app, context) => { });
41
47
  */
42
- on<Event extends keyof PluginHooks<ExtendedAsterflow<Instance>, Prettify<UnionToIntersection<Derive | Config | Decorate>>, Extension>>(event: Event, handler: NonNullable<PluginHooks<ExtendedAsterflow<Instance>, Prettify<UnionToIntersection<Derive | Config | Decorate>>, Extension>[Event]>[number]): this;
48
+ on<Event extends keyof PluginHooks<ExtendedAsterflow<Props['instance']>, Prettify<UnionToIntersection<Props['derive'] | Props['config'] | Props['decorate']>>, Props['extension']>>(event: Event, handler: NonNullable<PluginHooks<ExtendedAsterflow<Props['instance']>, Prettify<UnionToIntersection<Props['derive'] | Props['config'] | Props['decorate']>>, Props['extension']>[Event]>[number]): this;
43
49
  /**
44
50
  * Defines new properties or methods to be added to the AsterFlow instance.
45
51
  * A função recebe a instância do app e o contexto do plugin, e deve retornar um objeto
46
52
  * com as novas propriedades.
47
53
  */
48
- extends<E extends Record<string, any>>(extensionFn: (app: Instance, context: Prettify<UnionToIntersection<Config | Derive | Decorate>>) => E): Plugin<Path, Instance, Config, Decorate, Derive, Prettify<UnionToIntersection<Extension & E>>>;
54
+ extends<E extends Record<string, any>>(extensionFn: (app: Props['instance'], context: Prettify<UnionToIntersection<Props['config'] | Props['derive'] | Props['decorate']>>) => E): Plugin<MergeProps<Props, {
55
+ extension: Prettify<UnionToIntersection<Props["extension"] & E>>;
56
+ }>>;
49
57
  /**
50
58
  * Builds the final context and hooks from the provided configuration.
51
59
  */
52
60
  _build(config: any): {
53
- name: Path;
54
- context: Config & Derive & Decorate;
55
- hooks: PluginHooks<any, Decorate, any>;
56
- _extensionFn: ((app: Instance, context: Prettify<UnionToIntersection<Config & Decorate & Derive>>) => Extension) | undefined;
61
+ name: Props["path"];
62
+ context: Props["config"] & Props["derive"] & Props["decorate"];
63
+ hooks: PluginHooks<any, Props["decorate"], any>;
64
+ _extensionFn: ((app: Props["instance"], context: Prettify<UnionToIntersection<Props["config"] & Props["decorate"] & Props["derive"]>>) => Props["extension"]) | undefined;
57
65
  resolvers: Resolver[];
58
66
  };
59
67
  /**
@@ -61,5 +69,12 @@ export declare class Plugin<Path extends string = string, Instance extends AnyAs
61
69
  */
62
70
  static create<Path extends string, Asterflow extends AnyAsterflow>(options: {
63
71
  name: Path;
64
- }): Plugin<Path, Asterflow, {}, {}, {}, {}>;
72
+ }): Plugin<{
73
+ path: Path;
74
+ instance: Asterflow;
75
+ config: {};
76
+ decorate: {};
77
+ derive: {};
78
+ extension: {};
79
+ }>;
65
80
  }
@@ -5,26 +5,43 @@ import type { AnyRouter } from '@asterflow/router';
5
5
  import type { AnyAsterflow, ExtendedAsterflow, RouteEntry } from 'asterflow';
6
6
  import type { Plugin } from '../controllers/Plugin';
7
7
  import type { AnyRecord, UnionToIntersection } from './utils';
8
+ /** `Plugin`'s single generic parameter - the fields it needs to type a plugin. */
9
+ export interface PluginProps {
10
+ path: string;
11
+ instance: AnyAsterflow;
12
+ config: Record<string, any>;
13
+ decorate: Record<string, any>;
14
+ derive: Record<string, any>;
15
+ extension: Record<string, any>;
16
+ }
17
+ export type DefaultPluginProps = {
18
+ path: string;
19
+ instance: AnyAsterflow;
20
+ config: {};
21
+ decorate: {};
22
+ derive: {};
23
+ extension: {};
24
+ };
8
25
  export type AnyPluginHooks = PluginHooks<AnyAsterflow, AnyRecord, AnyRecord>;
9
- export type AnyPlugin = Plugin<string, AnyAsterflow, AnyRecord, AnyRecord, AnyRecord, AnyRecord>;
26
+ export type AnyPlugin = Plugin<any>;
10
27
  export type AnyPlugins = Record<string, ResolvedPlugin<AnyPlugin>>;
11
28
  export type AnyPluginInstance = ResolvedPlugin<AnyPlugin> & {
12
29
  hooks: AnyPluginHooks;
13
30
  };
14
- export type InferPluginExtension<P> = P extends Plugin<any, any, any, any, any, infer Ext> ? Ext : {};
15
- export type InferPluginContext<P> = P extends Plugin<any, any, infer Config, infer Decorate, infer Derive, any> ? Prettify<UnionToIntersection<Config | Decorate | Derive>> : {};
16
- export type ResolvedPlugin<P extends Plugin<any, any, any, any, any, any>> = P extends Plugin<infer Path, any, any, infer Ctx, any, infer Ext> ? {
17
- name: Path;
18
- context: Ctx;
19
- hooks: PluginHooks<any, Ctx, Ext>;
20
- _extensionFn?: (app: any, context: Ctx) => Ext;
31
+ export type InferPluginExtension<P> = P extends Plugin<infer Props extends PluginProps> ? Props['extension'] : {};
32
+ export type InferPluginContext<P> = P extends Plugin<infer Props extends PluginProps> ? Prettify<UnionToIntersection<Props['config'] | Props['decorate'] | Props['derive']>> : {};
33
+ export type ResolvedPlugin<P extends Plugin<any>> = P extends Plugin<infer Props extends PluginProps> ? {
34
+ name: Props['path'];
35
+ context: InferPluginContext<P>;
36
+ hooks: PluginHooks<any, InferPluginContext<P>, Props['extension']>;
37
+ _extensionFn?: (app: any, context: InferPluginContext<P>) => Props['extension'];
21
38
  resolvers: Resolver[];
22
39
  } : never;
23
40
  /**
24
41
  * Tipo para extrair o objeto de configuração de um plugin.
25
42
  * Ele torna as propriedades com valores padrão opcionais.
26
43
  */
27
- export type InferConfigArgument<P extends Plugin<any, any, any, any, any, any>> = P extends Plugin<any, any, infer C, any, any, any> ? Omit<C, keyof P['defaultConfig']> & Partial<Pick<C, keyof P['defaultConfig'] & keyof C>> : never;
44
+ export type InferConfigArgument<P extends Plugin<any>> = P extends Plugin<infer Props extends PluginProps> ? Omit<Props['config'], keyof P['defaultConfig']> & Partial<Pick<Props['config'], keyof P['defaultConfig'] & keyof Props['config']>> : never;
28
45
  /**
29
46
  * Defines the available lifecycle hooks a plugin can register.
30
47
  */
@@ -3,3 +3,9 @@ export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) ex
3
3
  export type Prettify<T> = {
4
4
  [K in keyof T]: T[K];
5
5
  } & {};
6
+ /**
7
+ * Produces a new `Props` object type equal to `Props` with `Patch`'s keys
8
+ * overridden. Lets a fluent builder method name only the field(s) actually
9
+ * changing instead of respelling every unchanged generic slot.
10
+ */
11
+ export type MergeProps<Props, Patch> = Prettify<Omit<Props, keyof Patch> & Patch>;
package/package.json CHANGED
@@ -1,12 +1,28 @@
1
1
  {
2
2
  "name": "@asterflow/plugin",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
+ "description": "The plugin-authoring system used to build AsterFlow plugins - a typed builder for context, config and lifecycle hooks.",
5
+ "keywords": [
6
+ "asterflow",
7
+ "plugin",
8
+ "plugin-system",
9
+ "typescript"
10
+ ],
4
11
  "main": "dist/cjs/index.cjs",
5
12
  "module": "dist/mjs/index.js",
6
13
  "types": "dist/types/index.d.ts",
7
14
  "typings": "dist/types/index.d.ts",
8
15
  "type": "module",
9
16
  "license": "MIT",
17
+ "author": "Ashu11-A",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/AsterFlow/AsterFlow.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/AsterFlow/AsterFlow/issues"
24
+ },
25
+ "homepage": "https://github.com/AsterFlow/AsterFlow",
10
26
  "exports": {
11
27
  ".": {
12
28
  "types": "./dist/types/index.d.ts",
@@ -18,9 +34,9 @@
18
34
  "node": ">=20"
19
35
  },
20
36
  "devDependencies": {
21
- "asterflow": "0.0.5",
22
- "@asterflow/response": "1.0.10",
23
- "@asterflow/request": "1.0.13"
37
+ "asterflow": "^1.0.0",
38
+ "@asterflow/response": "^1.0.10",
39
+ "@asterflow/request": "^1.0.13"
24
40
  },
25
41
  "peerDependencies": {
26
42
  "typescript": "^5.8.3"