diff --git a/src/lib/request-parameters.ts b/src/lib/request-parameters.ts index 4c05d59d..c414d832 100644 --- a/src/lib/request-parameters.ts +++ b/src/lib/request-parameters.ts @@ -2,7 +2,7 @@ export type RequireAtLeastOne< T, Keys extends keyof T = keyof T, > = Keys extends keyof T - ? Required> & Partial> + ? { [Key in Keys]-?: Exclude } & Partial> : never export const assertValidRequestParameters = ( @@ -25,9 +25,10 @@ export const assertValidRequestParameters = ( throw new TypeError(`Parameters for ${path} must be an object`) } - if (hasRequiredParameters && Object.keys(parameters).length === 0) { - throw new TypeError( - `Parameters for ${path} must contain at least one property`, - ) + if ( + hasRequiredParameters && + Object.values(parameters).every((value) => value === undefined) + ) { + throw new TypeError(`At least one parameter is required for ${path}`) } } diff --git a/test/seam/connect/request-parameters.test.ts b/test/seam/connect/request-parameters.test.ts index e1125b5d..8e9551e1 100644 --- a/test/seam/connect/request-parameters.test.ts +++ b/test/seam/connect/request-parameters.test.ts @@ -15,6 +15,17 @@ test('endpoint rejects missing required parameters', (t) => { message: 'Parameters are required for /devices/get', }, ) + + t.throws( + () => { + // @ts-expect-error Verify an explicitly required schema property makes the argument required. + seam.devices.reportProviderMetadata() + }, + { + instanceOf: TypeError, + message: 'Parameters are required for /devices/report_provider_metadata', + }, + ) }) test('endpoint rejects an empty required parameters object', (t) => { @@ -25,7 +36,20 @@ test('endpoint rejects an empty required parameters object', (t) => { }, { instanceOf: TypeError, - message: 'Parameters for /devices/get must contain at least one property', + message: 'At least one parameter is required for /devices/get', + }, + ) +}) + +test('endpoint rejects required parameters with only undefined values', (t) => { + t.throws( + () => { + // @ts-expect-error Verify RequireAtLeastOne requires a defined value. + seam.devices.get({ device_id: undefined }) + }, + { + instanceOf: TypeError, + message: 'At least one parameter is required for /devices/get', }, ) }) @@ -50,4 +74,5 @@ test('endpoint accepts omitted optional parameters', (t) => { test('endpoint accepts required parameters', (t) => { t.notThrows(() => seam.devices.get({ device_id: 'device-id' })) t.notThrows(() => seam.devices.get({ name: 'Front Door' })) + t.notThrows(() => seam.devices.reportProviderMetadata({ devices: [] })) })