diff options
author | Elizabeth Hunt <lizhunt@amazon.com> | 2025-05-12 19:46:51 -0700 |
---|---|---|
committer | Elizabeth Hunt <lizhunt@amazon.com> | 2025-05-12 19:50:40 -0700 |
commit | bbaea13ee7125a9d289a74f0c173e7e75177e53c (patch) | |
tree | f4775a1699e2158a5e6313f3e5d639c4c3740c7b | |
parent | 723fa00cb14513eb1a517728d4464c4f148a29cc (diff) | |
download | ci-bbaea13ee7125a9d289a74f0c173e7e75177e53c.tar.gz ci-bbaea13ee7125a9d289a74f0c173e7e75177e53c.zip |
updates!!
-rwxr-xr-x | hooks/mod.ts | 148 | ||||
-rw-r--r-- | utils/trace.ts | 21 | ||||
-rw-r--r-- | utils/validate_identifier.ts | 4 |
3 files changed, 100 insertions, 73 deletions
diff --git a/hooks/mod.ts b/hooks/mod.ts index 63a05fc..9fc4501 100755 --- a/hooks/mod.ts +++ b/hooks/mod.ts @@ -85,6 +85,39 @@ class HealthCheckActivity implements IHealthCheckActivity { } } +const aPost = (r: Traceable<Request>): Traceable<{ ok?: Request, err?: Response }> => + r.map((req) => { + const {item: request, logger} = req; + const {method} = request; + if (method !== "POST") { + const msg = "that's not how you pet me (⋟﹏⋞) try post instead~"; + logger.warn(msg); + const r405 = new Response(msg + "\n", {status: 405}); + return {err: r405}; + } + return {ok: request}; + }); + +type JsonTransformer<JsonT, R> = (json: Traceable<JsonT>) => Traceable<{ ok?: R; err?: Response }>; +const aJson = <BodyT, JsonT = unknown>(jsonTransformer: JsonTransformer<JsonT, BodyT>) => + (r: Traceable<Request>) => r + .map(async ({item: request, logger}): Promise<{ ok?: JsonT, err?: Response }> => { + + try { + return {ok: <JsonT>(await request.json())}; + } catch (e) { + const err = "seems to be invalid JSON (>//<) can you fix?"; + logger.warn(err); + const r400 = new Response(msg + "\n", {status: 400}); + return {err: r400}; + } + }) + .flatMapAsync(TraceableImpl.promiseify((t): Traceable<{ ok?: BodyT, err?: Response }> => { + const {item: {err, ok: json}} = t; + if (err) return <Traceable<{ err: Response }>>t; + return t.map(() => json!).flatMap(jsonTransformer); + })) + interface IJobHookActivity { processHook(req: Traceable<Request>): Traceable<Promise<Response>>; } @@ -93,73 +126,64 @@ class JobHookActivityImpl implements IJobHookActivity { constructor(private readonly queuer: IJobQueuer) {} private getJob( - { item: { args, jobType }, logger }: Traceable<GetJobRequest>, - ): { ok?: Job; err?: string } { - if (Array.isArray(args) || typeof args !== "object" || args === null) { - return { err: "your reqwest seems compwetewy mawfomed (-.-)/\n" }; - } + j: Traceable<unknown>, + ): Traceable<{ ok?: Job; err?: Response }> { + return j.map(({ logger, item }) => { + const isObject = (o: unknown): o is Record<string, unknown> => + typeof o === "object" && !Array.isArray(o) && !!o; + if (!isObject(item) || !isObject(item.arguments)|| typeof item.type !== "string") { + const err = "your reqwest seems compwetewy mawfomed \\(-.-)/\n"; + logger.warn(err); + return { err: new Response(err, { status: 400 }) }; + } - const invalidArgEntries = invalidExecutionEntriesOf({ - ...args, - jobType, - }); - if (invalidArgEntries.length > 0) { - const err = "your reqwest seems invawid (´。﹏。`) can you fix? uwu"; - logger.error(err, jobType, args); - return { err }; - } + const ok = { type: item.type, arguments: item.arguments }; + const invalidArgEntries = invalidExecutionEntriesOf({type: ok.type, ...ok.arguments}); + if (invalidArgEntries.length > 0) { + const err = "your reqwest seems invawid (´。﹏。`) can you fix? uwu"; + logger.warn(err); + return { err: new Response(err, { status: 400 }) }; + } - return { - ok: <Job> { - type: jobType, - arguments: args, - }, - }; + return { ok: <Job>ok }; + }); } public processHook(r: Traceable<Request>) { - return r.map(async ({ item: request, logger }) => { - const { method } = request; - if (method !== "POST") { - const msg = "that's not how you pet me (⋟﹏⋞) try post instead~"; - logger.log(msg); - const r405 = new Response(msg, { status: 405 }); - return { err: r405 }; - } - - const jobType = new URL(request.url).pathname.split("/")[1]; - const args = await request.json(); - return { ok: <GetJobRequest> { jobType, args } }; - }) - .map(TraceableImpl.promiseify((g) => { - const { item: { ok: jobRequest, err } } = g; - if (jobRequest) { - return g.map(() => jobRequest) - .map(this.getJob) - .map( - ({ item: { ok: jobRequest, err } }) => { - if (err) return { err: new Response(err, { status: 400 }) }; - return { ok: jobRequest }; - }, - ); - } - return g.map(() => ({ ok: undefined, err })); - })) - .map(TraceableImpl.promiseify(({ item: t }) => { - const { item: { ok: job, err } } = t; - if (err) return t.map(() => Promise.resolve(err)); - - return t.map(() => job!) - .map(this.queuer.queue) - .map(TraceableImpl.promiseify(({ item, logger }) => { - if (item.ok) { - return new Response(item.ok, { status: 200 }); - } - logger.error(item.err); - return new Response("i messed up D:\n", { status: 500 }); - })); - })); - } + return r.flatMap(aPost).flatMap((t) => { + const {item: {ok: request, err}} = t; + if (err) return <Traceable<{ err: Response }>> t; + return t.map(() => request!).map(aJson(this.getJob)); + }); +// flatMapAsync(aJsonPost(this.getJob)) +// .map(TraceableImpl.promiseify((g) => { +// if (jobRequest) { +// return g.map(() => jobRequest) +// .map(this.getJob) +// .map( +// ({ item: { ok: jobRequest, err } }) => { +// if (err) return { err: new Response(err, { status: 400 }) }; +// return { ok: jobRequest }; +// }, +// ); +// } +// return g.map(() => ({ ok: undefined, err })); +// })) +// .map(TraceableImpl.promiseify(({ item: t }) => { +// const { item: { ok: job, err } } = t; +// if (err) return t.map(() => Promise.resolve(err)); +// +// return t.map(() => job!) +// .map(this.queuer.queue) +// .map(TraceableImpl.promiseify(({ item, logger }) => { +// if (item.ok) { +// return new Response(item.ok, { status: 200 }); +// } +// logger.error(item.err); +// return new Response("i messed up D:\n", { status: 500 }); +// })); +// })); +// } } class LizCIServerImpl implements ILizCIServer { diff --git a/utils/trace.ts b/utils/trace.ts index 737aa60..eb4ac2f 100644 --- a/utils/trace.ts +++ b/utils/trace.ts @@ -78,7 +78,7 @@ export class TraceableImpl< } public flatMapAsync<U>(mapper: ITraceableMapper<T, L, Promise<ITraceable<U, L>>>): ITraceable<Promise<U>, L> { - return new TraceableImpl(mapper(this).then((i) => ) + return new TraceableImpl(mapper(this).then(({ item }) => item), this.logger); } public peek(peek: ITraceableMapper<T, L, void>) { @@ -94,13 +94,15 @@ export class TraceableImpl< static promiseify<T, L extends ITraceableLogger<L>, U>( mapper: ITraceableMapper<T, L, U>, ): ITraceableMapper<Promise<T>, L, Promise<U>> { - return (traceablePromise) => traceablePromise.map( - async ({ item: promise }) => { - const t = await promise; - return traceablePromise.map(() => t).map(mapper).item; - }); -// return (traceable) => -// traceable.item.then((item) => mapper(new TraceableImpl(item, traceable.logger))); + return (traceablePromise) => + traceablePromise.flatMapAsync(async (t) => { + const item = await t.item; + return t.map(() => item).map(mapper); + }).item; + } + + static withClassTrace<C extends Object, T, L extends ITraceableLogger<L>>(c: C): ITraceableMapper<T, L, ITraceableTuple<T>> { + return (t) => [t.item, () => c.constructor.name]; } static from<T>(t: T) { @@ -108,4 +110,5 @@ export class TraceableImpl< } } -export interface Traceable<T> extends ITraceable<T, TraceableLogger> +export interface Traceable<T, L extends ITraceableLogger<L> = TraceableLogger> extends ITraceable<T, L> { +} diff --git a/utils/validate_identifier.ts b/utils/validate_identifier.ts index c204497..e2a1dc5 100644 --- a/utils/validate_identifier.ts +++ b/utils/validate_identifier.ts @@ -3,8 +3,8 @@ export const validateIdentifier = (token: string) => { }; export const invalidExecutionEntriesOf = ( - obj: Record<string, string>, -): Array<[string, string]> => { + obj: Record<string, unknown>, +): Array<[string, unknown]> => { return Object.entries(obj).filter((e) => !e.every((x) => typeof x === "string" && validateIdentifier(x)) ); |