From 3e9052c4a7cab610a2243806d28b66b19097f232 Mon Sep 17 00:00:00 2001 From: ztimson Date: Sat, 29 Nov 2025 11:27:47 -0500 Subject: [PATCH] Fixed path event has checks --- package.json | 2 +- src/path-events.ts | 13 ++++--------- tests/path-events.spec.ts | 12 ++++++++++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 9c9e489..3e38800 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ztimson/utils", - "version": "0.27.12", + "version": "0.27.13", "description": "Utility library", "author": "Zak Timson", "license": "MIT", diff --git a/src/path-events.ts b/src/path-events.ts index 8fdf483..7dc5fc0 100644 --- a/src/path-events.ts +++ b/src/path-events.ts @@ -40,6 +40,7 @@ export function PE(str: TemplateStringsArray, ...args: any[]) { * @param {TemplateStringsArray} str * @param {string} args * @return {string} + * @constructor */ export function PES(str: TemplateStringsArray, ...args: any[]) { let combined = []; @@ -292,11 +293,7 @@ export class PathEvent { static filter(target: string | PathEvent | (string | PathEvent)[], ...filter: (string | PathEvent)[]): PathEvent[] { const parsedTarget = makeArray(target).map(pe => pe instanceof PathEvent ? pe : new PathEvent(pe)); const parsedFilter = makeArray(filter).map(pe => pe instanceof PathEvent ? pe : new PathEvent(pe)); - - return parsedTarget.filter(t => { - const combined = PathEvent.combine(t); - return !!parsedFilter.find(r => PathEvent.matches(r, combined)); - }); + return parsedTarget.filter(t => !!parsedFilter.find(r => PathEvent.matches(r, t))); } /** @@ -338,10 +335,8 @@ export class PathEvent { const parsedTarget = makeArray(target).map(pe => pe instanceof PathEvent ? pe : new PathEvent(pe)); const parsedRequired = makeArray(has).map(pe => pe instanceof PathEvent ? pe : new PathEvent(pe)); - // If target is a single item, check directly; if multiple, combine first - const effectiveTarget = parsedTarget.length === 1 ? parsedTarget[0] : PathEvent.combine(...parsedTarget); - - return !!parsedRequired.find(r => PathEvent.matches(r, effectiveTarget)); + // Check if any target permission matches any required permission + return !!parsedRequired.find(r => !!parsedTarget.find(t => PathEvent.matches(r, t))); } /** diff --git a/tests/path-events.spec.ts b/tests/path-events.spec.ts index a587fb3..5e1ae44 100644 --- a/tests/path-events.spec.ts +++ b/tests/path-events.spec.ts @@ -81,6 +81,7 @@ describe('Path Events', () => { expect(c.methods.has('c')).toBe(true); expect(c.methods.has('r')).toBe(true); expect(c.methods.has('u')).toBe(true); + expect(c.delete).toBe(false); }); it('combine stops at none', () => { @@ -95,6 +96,17 @@ describe('Path Events', () => { expect(d.none).toBe(false); }); + it('combine works with wildcards', () => { + expect(PathEvent.has([ + 'payments/anonymous:d', + 'payments/anonymous:c', + 'payments/system:cr', + 'logs/Momentum:c', + 'products:r', + '*' + ], 'actions/692a92d18afa11e6722e9f2e:r')).toBe(true); + }); + it('filter finds overlap by path and methods', () => { const events = [ new PathEvent('users/sys:cr'),