diff --git a/entrypoint.example.ts b/entrypoint.example.ts index 335e1f8..8ec5df6 100644 --- a/entrypoint.example.ts +++ b/entrypoint.example.ts @@ -13,10 +13,10 @@ import { const msg = await readStdin(); const result = await pipeline(msg, [ - [noopPolicy], + noopPolicy, [hellthreadPolicy, { limit: 100 }], - [antiDuplicationPolicy], - [rateLimitPolicy], + antiDuplicationPolicy, + rateLimitPolicy, ]); writeStdout(result); diff --git a/src/pipeline.ts b/src/pipeline.ts index 7d8e6c3..7297844 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -1,15 +1,17 @@ import { InputMessage, OutputMessage, Policy } from './types.ts'; -type PolicyTuple = [policy: Policy, opts?: Opts]; +type PolicyTuple = [policy: Policy, opts?: Opts]; +// https://stackoverflow.com/a/75806165 +// https://stackoverflow.com/a/54608401 type PolicyTuplesRest = { - [K in keyof T]: PolicyTuple + [K in keyof T]: PolicyTuple | Policy } /** Processes messages through multiple policies, bailing early on rejection. */ async function pipeline

(msg: InputMessage, policies: [...PolicyTuplesRest

]): Promise { - for (const tuple of policies) { - const [policy, opts] = tuple; + for (const item of policies) { + const [policy, opts] = toTuple(item); const result = await policy(msg, opts); if (result.action !== 'accept') { return result; @@ -23,4 +25,9 @@ async function pipeline

(msg: InputMessage, policies: [...Policy }; } +/** Coerce item into a tuple if it isn't already. */ +function toTuple(item: PolicyTuple | Policy): PolicyTuple { + return typeof item === 'function' ? [item] : item; +} + export default pipeline;