@lopan/filterchain 1.0.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/FilterChain.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @author afu
3
+ * @license MIT
4
+ */
5
+ import type IFilter from './IFilter.ts';
6
+ import type IFilterChain from './IFilterChain.ts';
7
+ import type IResource from './IResource.ts';
8
+
9
+ /**
10
+ * Filter chain implementation
11
+ *
12
+ * ```
13
+ * -- req --> | | -- req --> | | -- req --> |
14
+ * | filter1 | | filter2 | | RESOURCE
15
+ * <-- res -- | | <-- res -- | | <-- res -- |
16
+ * ```
17
+ */
18
+ export default class FilterChain implements IFilterChain {
19
+ private resource: IResource | null = null;
20
+
21
+ /**
22
+ * The current position of the filter chain
23
+ */
24
+ private position: number = 0;
25
+
26
+ /**
27
+ * The filter collection
28
+ */
29
+ private filters: IFilter[] = [];
30
+
31
+ /**
32
+ * @inheritdoc
33
+ */
34
+ public async doFilter(payload: unknown): Promise<unknown> {
35
+ if (this.position >= this.filters.length) {
36
+ const resource = this.resource;
37
+ this.clearFilters();
38
+
39
+ if(resource === null) {
40
+ return null;
41
+ }
42
+
43
+ const res = await resource.run(payload);
44
+ return res;
45
+ }
46
+
47
+ const filter = this.filters[this.position++];
48
+ return await filter.doFilter(payload, this);
49
+ }
50
+
51
+ /**
52
+ * Add a filter to the filter chain
53
+ */
54
+ public addFilter(filter: IFilter): void {
55
+ this.filters.push(filter);
56
+ }
57
+
58
+ /**
59
+ * Clear all filters
60
+ */
61
+ public clearFilters(): void {
62
+ this.position = 0;
63
+ this.filters = [];
64
+ this.resource = null;
65
+ }
66
+
67
+ /**
68
+ * Set the resource
69
+ */
70
+ public setResource(resource: IResource | null): void {
71
+ this.resource = resource;
72
+ }
73
+ }
package/IFilter.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @author afu
3
+ * @license MIT
4
+ */
5
+ import type IFilterChain from './IFilterChain.ts';
6
+
7
+ /**
8
+ * Filter interface
9
+ *
10
+ * The class that implements the `doFilter` method considers to be a filter
11
+ */
12
+ export default interface IFilter {
13
+ /**
14
+ * The filter method
15
+ *
16
+ * This method needs to call `filterChain.doFilter(payload)` manually to execute the next filter
17
+ */
18
+ doFilter(payload: unknown, filterChain: IFilterChain): Promise<unknown>;
19
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @author afu
3
+ * @license MIT
4
+ */
5
+
6
+ /**
7
+ * Filter chain interface
8
+ */
9
+ export default interface IFilterChain {
10
+ /**
11
+ * Invoked the next filter or the resource
12
+ */
13
+ doFilter(payload: unknown): Promise<unknown>;
14
+ }
package/IResource.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @author afu
3
+ * @license MIT
4
+ */
5
+
6
+ /**
7
+ * Class implementing this interface is a resource class
8
+ */
9
+ export default interface IResource {
10
+ /**
11
+ * Run the resource
12
+ */
13
+ run(payload: unknown): Promise<unknown>;
14
+ }
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # filter chain
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@lopan/filterchain",
3
+ "version": "1.0.0",
4
+ "main": "FilterChain.ts",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "author": "",
9
+ "license": "ISC",
10
+ "description": ""
11
+ }
package/test/index.ts ADDED
@@ -0,0 +1,35 @@
1
+ import FilterChain from '../FilterChain.ts';
2
+ import type IFilter from '../IFilter.ts';
3
+
4
+
5
+ class ImgFilter1 implements IFilter {
6
+ public async doFilter(payload: unknown, filterChain: FilterChain): Promise<unknown> {
7
+ console.log('ImgFilter1 before');
8
+ const res = await filterChain.doFilter(payload);
9
+ console.log('ImgFilter1 after');
10
+ return res;
11
+ }
12
+ }
13
+ class ImgFilter2 implements IFilter {
14
+ public async doFilter(payload: unknown, filterChain: FilterChain): Promise<unknown> {
15
+ console.log('ImgFilter2 before');
16
+ const res = await filterChain.doFilter(payload);
17
+ console.log('ImgFilter2 after');
18
+ return res;
19
+ }
20
+ }
21
+
22
+
23
+ class Main {
24
+ static async run() {
25
+ const chain = new FilterChain()
26
+ // chain.setResource(null)
27
+ chain.addFilter(new ImgFilter1())
28
+ chain.addFilter(new ImgFilter2())
29
+
30
+ const res = await chain.doFilter(null)
31
+ console.log(res)
32
+ }
33
+ }
34
+
35
+ Main.run()