feat(client): implement OpenProject REST API v3 client layer and context scoping

This commit is contained in:
Lucas Winther
2026-09-05 17:26:43 +02:00
parent 5886419b06
commit f5bff8a81f
9 changed files with 1781 additions and 7 deletions
+50
View File
@@ -0,0 +1,50 @@
/**
* Request Context and AsyncLocalStorage Scoping for Multi-User Safety.
*/
import { AsyncLocalStorage } from "node:async_hooks";
import type { OpenProjectClient } from "./client/api-client.ts";
export interface RequestContext {
client: OpenProjectClient;
isReadOnly: boolean;
sessionId?: string;
userId?: string;
}
const asyncLocalStorage = new AsyncLocalStorage<RequestContext>();
/**
* Retrieves the current request context for the active asynchronous execution chain.
* Throws an error if called outside of a runWithContext() scope.
*/
export function getRequestContext(): RequestContext {
const context = asyncLocalStorage.getStore();
if (!context) {
throw new Error(
"No active RequestContext found. Operations must be executed within runWithContext()."
);
}
return context;
}
/**
* Attempts to retrieve the current request context, returning undefined if outside scope.
*/
export function tryGetRequestContext(): RequestContext | undefined {
return asyncLocalStorage.getStore();
}
/**
* Executes a function within the scope of a specific RequestContext.
*
* @param context - Request context holding the isolated OpenProject client and options
* @param fn - Asynchronous or synchronous callback to execute
*/
export function runWithContext<T>(
context: RequestContext,
fn: () => T
): T {
return asyncLocalStorage.run(context, fn);
}