import { InputMessage, OutputMessage, Policy } from './types.ts';
/** A policy function with opts to run it with. Used by the pipeline. */
type PolicyTuple
= [policy: P, opts?: InferPolicyOpts
];
/** Infer opts from the policy. */
type InferPolicyOpts
= P extends Policy ? Opts : never;
/** Helper type for proper type inference of PolicyTuples. */
// https://stackoverflow.com/a/75806165
// https://stackoverflow.com/a/54608401
type Policies = {
[K in keyof T]: PolicyTuple | Policy;
};
/** Processes messages through multiple policies, bailing early on rejection. */
async function pipeline(msg: InputMessage, policies: [...Policies]): Promise {
for (const item of policies as (Policy | PolicyTuple)[]) {
const [policy, opts] = toTuple(item);
const result = await policy(msg, opts);
if (result.action !== 'accept') {
return result;
}
}
return {
id: msg.event.id,
action: 'accept',
msg: '',
};
}
/** Coerce item into a tuple if it isn't already. */
function toTuple(item: PolicyTuple
| P): PolicyTuple
{
return typeof item === 'function' ? [item] : item;
}
export default pipeline;
export type { PolicyTuple };