diff --git a/packages/core/src/permission.ts b/packages/core/src/permission.ts index acc0705352c1..763d5e583587 100644 --- a/packages/core/src/permission.ts +++ b/packages/core/src/permission.ts @@ -183,6 +183,12 @@ const layer = Layer.effect( return { effect: event.effect, message: event.message, rules: all } }) + // Metadata is JSON-encoded; drop undefined values tools pass for absent optional inputs. + function metadata(value: AssertInput["metadata"]): Request["metadata"] { + if (!value) return value + return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined)) + } + function request(input: AssertInput, message?: string): Request { return { id: input.id ?? ID.create(), @@ -190,7 +196,7 @@ const layer = Layer.effect( action: input.action, resources: input.resources, save: input.save, - metadata: input.metadata, + metadata: metadata(input.metadata), source: input.source, message, } diff --git a/packages/core/test/permission.test.ts b/packages/core/test/permission.test.ts index 6dba198515b4..30efde2ba588 100644 --- a/packages/core/test/permission.test.ts +++ b/packages/core/test/permission.test.ts @@ -260,6 +260,17 @@ describe("Permission", () => { }), ) + it.effect("omits undefined metadata values from pending requests", () => + Effect.gen(function* () { + yield* setup() + const service = yield* Permission.Service + yield* service.ask(assertion({ metadata: { root: ".", path: undefined, limit: undefined } })) + const request = yield* service.get(Permission.ID.create("per_test")) + expect(request?.metadata).toEqual({ root: "." }) + expect(Object.keys(request?.metadata ?? {})).toEqual(["root"]) + }), + ) + it.effect("defects when an asked permission is declined", () => Effect.gen(function* () { yield* setup()