@holz/pattern-filter 0.2.0 → 0.6.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 ADDED
@@ -0,0 +1,32 @@
1
+ # `@holz/pattern-filter`
2
+
3
+ `@holz/pattern-filter` is a library that allows you to conditionally filter out logs based on a set of patterns. It can be used in combination with other plugins like [`@holz/console-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-console-backend) or [`@holz/ansi-terminal-backend`](https://github.com/PsychoLlama/holz/tree/main/packages/holz-ansi-terminal-backend) to process and display filtered logs.
4
+
5
+ ## Usage
6
+
7
+ To use `@holz/pattern-filter`, you first need to import it and create a filter with `createPatternFilter()`:
8
+
9
+ ```typescript
10
+ import { createPatternFilter } from '@holz/pattern-filter';
11
+
12
+ const filter = createPatternFilter({
13
+ pattern: 'my-app*, library*, -library:chatty*',
14
+ processor: plugin,
15
+ });
16
+ ```
17
+
18
+ The `pattern` option is a comma-separated list of patterns that determine which logs to show and which to hide. In the example above, logs with origins that start with `'my-app'` or `'library'` will be shown, but logs with the origin `'library:chatty'` will be hidden.
19
+
20
+ The `processor` option is where you specify which plugin should process the filtered logs. This can be any Holz plugin.
21
+
22
+ ## Patterns
23
+
24
+ Patterns are strings that match against `log.origin`, which is a property of each log object. Origins are added when you call `logger.namepspace(...)`. The following syntax is supported:
25
+
26
+ - `*` matches zero or more characters.
27
+ - `-` at the beginning of a pattern negates it, so that logs with origins matching the pattern are hidden rather than shown.
28
+
29
+ For example:
30
+
31
+ - `my-app*` matches origins that start with `'my-app'`, such as `'my-app:home'` or `'my-app:login'`.
32
+ - `library*, -library:chatty*` matches origins that start with `'library'`, except for origins that start with `'library:chatty'`.
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=t=>t.split(/[\s,]+/).filter(Boolean).reduce((s,r)=>(r[0]==="-"?s.exclude.push(c(r.slice(1))):s.include.push(c(r)),s),{include:[],exclude:[]}),n=(t,e)=>t.exclude.every(s=>!s.test(e))&&t.include.some(s=>s.test(e)),c=t=>{const e=t.replace(/\*/g,".*?");return new RegExp(`^${e}$`)};class o{constructor(e){this.pattern=e.pattern,this.processor=e.processor,this.filters=l(e.pattern)}processLog(e){n(this.filters,e.origin.join(":"))&&this.processor.processLog(e)}}exports.PatternFilter=o;exports.default=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=t=>t.split(/[\s,]+/).filter(Boolean).reduce((e,n)=>(n[0]==="-"?e.exclude.push(c(n.slice(1))):e.include.push(c(n)),e),{include:[],exclude:[]}),i=(t,r)=>t.exclude.every(e=>!e.test(r))&&t.include.some(e=>e.test(r)),c=t=>{const r=t.replace(/\*/g,".*?");return new RegExp(`^${r}$`)};function l({processor:t,pattern:r}){const e=s(r);return n=>{i(e,n.origin.join(":"))&&t(n)}}exports.createPatternFilter=l;
@@ -1,19 +1,19 @@
1
- const o = (s) => s.split(/[\s,]+/).filter(Boolean).reduce(
2
- (t, r) => (r[0] === "-" ? t.exclude.push(c(r.slice(1))) : t.include.push(c(r)), t),
1
+ const s = (t) => t.split(/[\s,]+/).filter(Boolean).reduce(
2
+ (e, r) => (r[0] === "-" ? e.exclude.push(c(r.slice(1))) : e.include.push(c(r)), e),
3
3
  { include: [], exclude: [] }
4
- ), n = (s, e) => s.exclude.every((t) => !t.test(e)) && s.include.some((t) => t.test(e)), c = (s) => {
5
- const e = s.replace(/\*/g, ".*?");
6
- return new RegExp(`^${e}$`);
4
+ ), i = (t, n) => t.exclude.every((e) => !e.test(n)) && t.include.some((e) => e.test(n)), c = (t) => {
5
+ const n = t.replace(/\*/g, ".*?");
6
+ return new RegExp(`^${n}$`);
7
7
  };
8
- class i {
9
- constructor(e) {
10
- this.pattern = e.pattern, this.processor = e.processor, this.filters = o(e.pattern);
11
- }
12
- processLog(e) {
13
- n(this.filters, e.origin.join(":")) && this.processor.processLog(e);
14
- }
8
+ function l({
9
+ processor: t,
10
+ pattern: n
11
+ }) {
12
+ const e = s(n);
13
+ return (r) => {
14
+ i(e, r.origin.join(":")) && t(r);
15
+ };
15
16
  }
16
17
  export {
17
- i as PatternFilter,
18
- i as default
18
+ l as createPatternFilter
19
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holz/pattern-filter",
3
- "version": "0.2.0",
3
+ "version": "0.6.0",
4
4
  "description": "Only print log messages that match a pattern",
5
5
  "type": "module",
6
6
  "main": "./dist/holz-pattern-filter.cjs",
@@ -40,9 +40,9 @@
40
40
  "test:types": "tsc"
41
41
  },
42
42
  "devDependencies": {
43
- "@holz/core": "0.2.0",
44
- "@vitest/coverage-c8": "0.28.5",
45
- "typescript": "4.9.5",
43
+ "@holz/core": "^0.6.0",
44
+ "@vitest/coverage-c8": "^0.28.5",
45
+ "typescript": "^4.9.5",
46
46
  "vite": "^4.0.0",
47
47
  "vitest": "^0.28.5"
48
48
  }
@@ -1,15 +1,10 @@
1
- import type { LogProcessor } from '@holz/core';
2
1
  import { createLogger } from '@holz/core';
3
- import PatternFilter from '../pattern-filter';
4
-
5
- class TestBackend implements LogProcessor {
6
- processLog = vi.fn();
7
- }
2
+ import { createPatternFilter } from '../pattern-filter';
8
3
 
9
4
  describe('PatternFilter', () => {
10
5
  it('only passes through logs that have the filter', () => {
11
- const backend = new TestBackend();
12
- const filter = new PatternFilter({
6
+ const backend = vi.fn();
7
+ const filter = createPatternFilter({
13
8
  pattern: '-ignored, -*:wild, *',
14
9
  processor: backend,
15
10
  });
@@ -17,13 +12,13 @@ describe('PatternFilter', () => {
17
12
  const logger = createLogger(filter);
18
13
 
19
14
  logger.namespace('ignored').info('excluded by filter');
20
- expect(backend.processLog).not.toHaveBeenCalled();
15
+ expect(backend).not.toHaveBeenCalled();
21
16
 
22
17
  logger.namespace('something').namespace('wild').info('also excluded');
23
- expect(backend.processLog).not.toHaveBeenCalled();
18
+ expect(backend).not.toHaveBeenCalled();
24
19
 
25
20
  logger.namespace('app').info('not ignored');
26
- expect(backend.processLog).toHaveBeenCalledWith(
21
+ expect(backend).toHaveBeenCalledWith(
27
22
  expect.objectContaining({
28
23
  message: 'not ignored',
29
24
  })
@@ -31,12 +26,12 @@ describe('PatternFilter', () => {
31
26
  });
32
27
 
33
28
  it('does not send anything by default', () => {
34
- const backend = new TestBackend();
35
- const filter = new PatternFilter({ pattern: '', processor: backend });
29
+ const backend = vi.fn();
30
+ const filter = createPatternFilter({ pattern: '', processor: backend });
36
31
  const logger = createLogger(filter);
37
32
 
38
33
  logger.info('no include patterns mean this is ignored');
39
34
 
40
- expect(backend.processLog).not.toHaveBeenCalled();
35
+ expect(backend).not.toHaveBeenCalled();
41
36
  });
42
37
  });
package/src/index.ts CHANGED
@@ -1 +1 @@
1
- export { default, default as PatternFilter } from './pattern-filter';
1
+ export { createPatternFilter } from './pattern-filter';
@@ -11,27 +11,22 @@ import { parse, matches } from './string-match';
11
11
  * with the origin `my-app`.
12
12
  *
13
13
  * @example
14
- * new PatternFilter({
14
+ * createPatternFilter({
15
15
  * pattern: 'my-app*, -spammy:library',
16
16
  * processor: backend,
17
17
  * })
18
18
  */
19
- export default class PatternFilter implements LogProcessor {
20
- private filters: ReturnType<typeof parse>;
21
- readonly pattern: string;
22
- private processor: LogProcessor;
19
+ export function createPatternFilter({
20
+ processor,
21
+ pattern,
22
+ }: Config): LogProcessor {
23
+ const filters = parse(pattern);
23
24
 
24
- constructor(config: Config) {
25
- this.pattern = config.pattern;
26
- this.processor = config.processor;
27
- this.filters = parse(config.pattern);
28
- }
29
-
30
- processLog(log: Log) {
31
- if (matches(this.filters, log.origin.join(':'))) {
32
- this.processor.processLog(log);
25
+ return (log: Log) => {
26
+ if (matches(filters, log.origin.join(':'))) {
27
+ processor(log);
33
28
  }
34
- }
29
+ };
35
30
  }
36
31
 
37
32
  interface Config {