@travetto/context 2.1.4 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +3 -3
- package/src/decorator.ts +10 -5
- package/src/extension/rest.interceptor.ts +1 -1
- package/src/service.ts +9 -8
- package/test-support/suite-context.ts +2 -1
package/README.md
CHANGED
|
@@ -64,4 +64,4 @@ export class SystemInitiatedContext {
|
|
|
64
64
|
|
|
65
65
|
## Extension - Rest
|
|
66
66
|
|
|
67
|
-
Within the [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") module, it can be
|
|
67
|
+
Within the [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") module, it can be challenging to share context across the various layers that may be touched by a request. This module provides [AsyncContextInterceptor](https://github.com/travetto/travetto/tree/main/module/context/src/extension/rest.interceptor.ts#L17) to create a data store that will be private to an individual request. This is used by [Rest Auth](https://github.com/travetto/travetto/tree/main/module/auth-rest#readme "Rest authentication integration support for the travetto framework") to store authenticated user information for built-in authorization and permission validation.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/context",
|
|
3
3
|
"displayName": "Async Context",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"description": "Async-aware state management, maintaining context across asynchronous calls.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"async-hooks",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"directory": "module/context"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/di": "^2.1
|
|
30
|
+
"@travetto/di": "^2.2.1"
|
|
31
31
|
},
|
|
32
32
|
"optionalPeerDependencies": {
|
|
33
|
-
"@travetto/rest": "^2.1
|
|
33
|
+
"@travetto/rest": "^2.2.1"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|
package/src/decorator.ts
CHANGED
|
@@ -4,11 +4,16 @@ import { AsyncContext } from './service';
|
|
|
4
4
|
* Allows running a function while providing an async context
|
|
5
5
|
*/
|
|
6
6
|
export function WithAsyncContext<T extends { context: AsyncContext }>(data?: Record<string, unknown>) {
|
|
7
|
-
return function <U extends unknown[], V = unknown>(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
return function <U extends unknown[], V = unknown>(
|
|
8
|
+
target: T,
|
|
9
|
+
prop: string,
|
|
10
|
+
descriptor: TypedPropertyDescriptor<(...args: U) => Promise<V>>
|
|
11
|
+
): typeof descriptor {
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13
|
+
const og = descriptor.value! as (this: T, ...args: unknown[]) => Promise<V>;
|
|
14
|
+
descriptor.value = function (this: T, ...args: unknown[]): Promise<V> {
|
|
15
|
+
return (this.context.run(og.bind(this, ...args),
|
|
16
|
+
data ? JSON.parse(JSON.stringify(data)) : {}));
|
|
12
17
|
};
|
|
13
18
|
|
|
14
19
|
Object.defineProperty(descriptor.value, 'name', { value: og.name });
|
|
@@ -28,7 +28,7 @@ export class AsyncContextInterceptor implements RestInterceptor {
|
|
|
28
28
|
return !this.config.disabled;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
intercept(req: Request, res: Response, next: () => Promise<void>) {
|
|
31
|
+
intercept(req: Request, res: Response, next: () => Promise<void>): Promise<void> {
|
|
32
32
|
return this.context.run(next);
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/service.ts
CHANGED
|
@@ -21,7 +21,7 @@ export class AsyncContext {
|
|
|
21
21
|
this.iterate = this.iterate.bind(this);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
#store(setAs?: Ctx | null) {
|
|
24
|
+
#store(setAs?: Ctx | null): Ctx {
|
|
25
25
|
const val = this.alStorage.getStore();
|
|
26
26
|
if (!val) {
|
|
27
27
|
throw new AppError('Context is not initialized', 'general');
|
|
@@ -40,13 +40,14 @@ export class AsyncContext {
|
|
|
40
40
|
* Get entire context or a portion by key
|
|
41
41
|
*/
|
|
42
42
|
get<T = unknown>(key: string | symbol): T;
|
|
43
|
-
get():
|
|
44
|
-
get<T>(key?: string | symbol) {
|
|
43
|
+
get(): Ctx;
|
|
44
|
+
get<T>(key?: string | symbol): Ctx | T {
|
|
45
45
|
const root = this.#store();
|
|
46
46
|
if (key) {
|
|
47
|
-
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
48
|
+
return root[key as string] as T;
|
|
48
49
|
} else {
|
|
49
|
-
return root
|
|
50
|
+
return root;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -55,11 +56,11 @@ export class AsyncContext {
|
|
|
55
56
|
*/
|
|
56
57
|
set(key: string | symbol, val: unknown): void;
|
|
57
58
|
set(val: Ctx): void;
|
|
58
|
-
set(keyOrVal: string | symbol | Ctx, valWithKey?: unknown) {
|
|
59
|
+
set(keyOrVal: string | symbol | Ctx, valWithKey?: unknown): void {
|
|
59
60
|
if (typeof keyOrVal === 'string' || typeof keyOrVal === 'symbol') {
|
|
60
|
-
this.get()[keyOrVal
|
|
61
|
+
this.get()[keyOrVal] = valWithKey;
|
|
61
62
|
} else {
|
|
62
|
-
this.#store(keyOrVal
|
|
63
|
+
this.#store(keyOrVal);
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -11,7 +11,7 @@ const Init = Symbol();
|
|
|
11
11
|
* @param data
|
|
12
12
|
*/
|
|
13
13
|
export function WithSuiteContext(data: Record<string, unknown> = {}) {
|
|
14
|
-
return (target: Class) => {
|
|
14
|
+
return (target: Class): void => {
|
|
15
15
|
function wrapped(ctx: AsyncContext, og: Function) {
|
|
16
16
|
return function (this: unknown) {
|
|
17
17
|
return ctx.run(og.bind(this), JSON.parse(JSON.stringify(data)));
|
|
@@ -24,6 +24,7 @@ export function WithSuiteContext(data: Record<string, unknown> = {}) {
|
|
|
24
24
|
this[Init] = true;
|
|
25
25
|
const ctx = await DependencyRegistry.getInstance(AsyncContext);
|
|
26
26
|
for (const t of SuiteRegistry.get(target).tests) {
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
27
28
|
const fn = wrapped(ctx, this[t.methodName] as Function);
|
|
28
29
|
Object.defineProperty(fn, 'name', { value: t.methodName });
|
|
29
30
|
this[t.methodName] = fn;
|