@zhin.js/middleware 1.0.11 → 1.0.13
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/lib/definition.d.ts +31 -8
- package/lib/definition.js +11 -1
- package/lib/index.d.ts +7 -0
- package/lib/index.js +7 -0
- package/lib/middleware-index.d.ts +1 -0
- package/lib/middleware-index.js +10 -3
- package/lib/provider.d.ts +1 -1
- package/package.json +3 -3
- package/src/definition.ts +72 -16
- package/src/index.ts +7 -0
- package/src/middleware-index.ts +16 -3
package/lib/definition.d.ts
CHANGED
|
@@ -1,27 +1,50 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Middleware authoring API consumed from `zhin.js/middleware`.
|
|
3
|
+
* @module zhin.js/middleware
|
|
4
|
+
*/
|
|
5
|
+
import type { AdapterClient, CapabilityContext, RegisteredAdapterName } from '@zhin.js/feature-kit';
|
|
2
6
|
declare const middlewareBrand: "zhin.middleware/1";
|
|
3
7
|
export type MiddlewarePhase = 'before-dispatch' | 'after-dispatch';
|
|
4
8
|
export type MiddlewareTarget = 'inbound' | 'outbound';
|
|
5
9
|
export type MiddlewareNext = () => Promise<void>;
|
|
6
|
-
export interface MiddlewareContext<TInput = unknown, TConfig = unknown> extends CapabilityContext<TConfig> {
|
|
10
|
+
export interface MiddlewareContext<TInput = unknown, TConfig = unknown, TAdapter extends string | undefined = undefined> extends CapabilityContext<TConfig> {
|
|
7
11
|
readonly input: TInput;
|
|
12
|
+
/** Lazily resolved native Client. Without `adapter`, its static type is `unknown`. */
|
|
13
|
+
readonly $client: AdapterClient<TAdapter>;
|
|
8
14
|
}
|
|
9
|
-
export interface MiddlewareDefinition<TInput = unknown, TConfig = unknown> {
|
|
15
|
+
export interface MiddlewareDefinition<TInput = unknown, TConfig = unknown, TAdapter extends string | undefined = string | undefined> {
|
|
16
|
+
/** @internal Runtime feature brand. */
|
|
10
17
|
readonly $feature: typeof middlewareBrand;
|
|
11
18
|
readonly phase: MiddlewarePhase;
|
|
12
19
|
readonly target: MiddlewareTarget;
|
|
13
20
|
readonly order: number;
|
|
14
|
-
|
|
21
|
+
readonly adapter?: TAdapter;
|
|
22
|
+
handle(context: MiddlewareContext<TInput, TConfig, TAdapter>, next: MiddlewareNext): void | Promise<void>;
|
|
15
23
|
}
|
|
16
24
|
declare module '@zhin.js/plugin-runtime' {
|
|
17
|
-
interface PluginSetupContext<TConfig> {
|
|
18
|
-
addMiddleware<TInput = unknown>(localName: string, definition: MiddlewareDefinition<TInput, TConfig>): void;
|
|
25
|
+
interface PluginSetupContext<TConfig = unknown> {
|
|
26
|
+
addMiddleware<TInput = unknown>(localName: string, definition: MiddlewareDefinition<TInput, TConfig, string | undefined>): void;
|
|
19
27
|
}
|
|
20
28
|
}
|
|
21
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Define ordered inbound or outbound middleware.
|
|
31
|
+
* Call `next()` to continue the chain; omit it to stop dispatch deliberately.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
type MiddlewareAuthoringDefinition<TInput, TConfig> = (Omit<MiddlewareDefinition<TInput, TConfig, undefined>, '$feature' | 'phase' | 'target' | 'order'> & {
|
|
22
36
|
readonly phase?: MiddlewarePhase;
|
|
23
37
|
readonly target?: MiddlewareTarget;
|
|
24
38
|
readonly order?: number;
|
|
25
|
-
})
|
|
39
|
+
}) | {
|
|
40
|
+
[TAdapter in RegisteredAdapterName]: Omit<MiddlewareDefinition<TInput, TConfig, TAdapter>, '$feature' | 'phase' | 'target' | 'order'> & {
|
|
41
|
+
readonly adapter: TAdapter;
|
|
42
|
+
readonly phase?: MiddlewarePhase;
|
|
43
|
+
readonly target?: MiddlewareTarget;
|
|
44
|
+
readonly order?: number;
|
|
45
|
+
};
|
|
46
|
+
}[RegisteredAdapterName];
|
|
47
|
+
export declare function defineMiddleware<TInput = unknown, TConfig = unknown>(definition: MiddlewareAuthoringDefinition<TInput, TConfig>): Readonly<MiddlewareDefinition<TInput, TConfig, string | undefined>>;
|
|
48
|
+
/** @internal Runtime validation for convention-discovered modules. */
|
|
26
49
|
export declare function parseMiddlewareDefinition(value: unknown): MiddlewareDefinition;
|
|
27
50
|
export {};
|
package/lib/definition.js
CHANGED
|
@@ -3,6 +3,11 @@ export function defineMiddleware(definition) {
|
|
|
3
3
|
if (typeof definition.handle !== 'function') {
|
|
4
4
|
throw new TypeError('Middleware handle must be a function');
|
|
5
5
|
}
|
|
6
|
+
const adapter = definition.adapter;
|
|
7
|
+
if (adapter !== undefined
|
|
8
|
+
&& (typeof adapter !== 'string' || adapter.trim() === '')) {
|
|
9
|
+
throw new TypeError('Middleware adapter must be a non-empty string');
|
|
10
|
+
}
|
|
6
11
|
const phase = definition.phase ?? 'before-dispatch';
|
|
7
12
|
if (phase !== 'before-dispatch' && phase !== 'after-dispatch') {
|
|
8
13
|
throw new TypeError(`Invalid Middleware phase: ${String(phase)}`);
|
|
@@ -16,6 +21,7 @@ export function defineMiddleware(definition) {
|
|
|
16
21
|
throw new TypeError('Middleware order must be a safe integer');
|
|
17
22
|
return Object.freeze({ ...definition, $feature: middlewareBrand, phase, target, order });
|
|
18
23
|
}
|
|
24
|
+
/** @internal Runtime validation for convention-discovered modules. */
|
|
19
25
|
export function parseMiddlewareDefinition(value) {
|
|
20
26
|
if (!value || typeof value !== 'object')
|
|
21
27
|
throw invalidMiddleware();
|
|
@@ -24,10 +30,14 @@ export function parseMiddlewareDefinition(value) {
|
|
|
24
30
|
|| typeof definition.handle !== 'function'
|
|
25
31
|
|| (definition.phase !== 'before-dispatch' && definition.phase !== 'after-dispatch')
|
|
26
32
|
|| (definition.target !== 'inbound' && definition.target !== 'outbound')
|
|
27
|
-
|| !Number.isSafeInteger(definition.order)
|
|
33
|
+
|| !Number.isSafeInteger(definition.order)
|
|
34
|
+
|| !validAdapterName(definition.adapter))
|
|
28
35
|
throw invalidMiddleware();
|
|
29
36
|
return definition;
|
|
30
37
|
}
|
|
31
38
|
function invalidMiddleware() {
|
|
32
39
|
return new TypeError('Middleware module must default-export defineMiddleware(...)');
|
|
33
40
|
}
|
|
41
|
+
function validAdapterName(adapter) {
|
|
42
|
+
return adapter === undefined || (typeof adapter === 'string' && adapter.trim() !== '');
|
|
43
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordered inbound and outbound middleware authoring contracts.
|
|
3
|
+
* @module @zhin.js/middleware
|
|
4
|
+
*/
|
|
5
|
+
/** @public Middleware authoring contract and `defineMiddleware`. */
|
|
1
6
|
export * from './definition.js';
|
|
7
|
+
/** @internal Runtime middleware projection. */
|
|
2
8
|
export * from './middleware-index.js';
|
|
9
|
+
/** @internal Feature provider installed by the Runtime composition root. */
|
|
3
10
|
export * from './provider.js';
|
|
4
11
|
export { default } from './provider.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordered inbound and outbound middleware authoring contracts.
|
|
3
|
+
* @module @zhin.js/middleware
|
|
4
|
+
*/
|
|
5
|
+
/** @public Middleware authoring contract and `defineMiddleware`. */
|
|
1
6
|
export * from './definition.js';
|
|
7
|
+
/** @internal Runtime middleware projection. */
|
|
2
8
|
export * from './middleware-index.js';
|
|
9
|
+
/** @internal Feature provider installed by the Runtime composition root. */
|
|
3
10
|
export * from './provider.js';
|
|
4
11
|
export { default } from './provider.js';
|
package/lib/middleware-index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createCapabilityContext } from '@zhin.js/feature-kit';
|
|
1
|
+
import { createCapabilityContext, operationClientAdapter, readOperationClient, } from '@zhin.js/feature-kit';
|
|
2
2
|
export class MiddlewareIndex {
|
|
3
3
|
snapshot;
|
|
4
4
|
$projection = 'zhin.middleware-index/1';
|
|
@@ -13,6 +13,7 @@ export class MiddlewareIndex {
|
|
|
13
13
|
phase: slot.definition.phase,
|
|
14
14
|
target: slot.definition.target,
|
|
15
15
|
order: slot.definition.order,
|
|
16
|
+
...(slot.definition.adapter ? { adapter: slot.definition.adapter } : {}),
|
|
16
17
|
slot,
|
|
17
18
|
})).sort((left, right) => compareMiddleware(left, right, topology)));
|
|
18
19
|
}
|
|
@@ -20,7 +21,8 @@ export class MiddlewareIndex {
|
|
|
20
21
|
return this.#records.map(({ slot: _slot, ...descriptor }) => descriptor);
|
|
21
22
|
}
|
|
22
23
|
async run(input, terminal = async () => undefined, target = 'inbound') {
|
|
23
|
-
const
|
|
24
|
+
const clientAdapter = operationClientAdapter(input);
|
|
25
|
+
const records = this.#records.filter((record) => record.target === target && (!record.adapter || record.adapter === clientAdapter));
|
|
24
26
|
let cursor = -1;
|
|
25
27
|
const dispatch = async (index) => {
|
|
26
28
|
if (index <= cursor)
|
|
@@ -29,10 +31,15 @@ export class MiddlewareIndex {
|
|
|
29
31
|
const record = records[index];
|
|
30
32
|
if (!record)
|
|
31
33
|
return terminal();
|
|
32
|
-
const context =
|
|
34
|
+
const context = {
|
|
33
35
|
...createCapabilityContext(this.snapshot, record.owner),
|
|
34
36
|
input,
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(context, '$client', {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: () => readOperationClient(input, record.adapter),
|
|
35
41
|
});
|
|
42
|
+
Object.freeze(context);
|
|
36
43
|
await record.slot.definition.handle(context, () => dispatch(index + 1));
|
|
37
44
|
};
|
|
38
45
|
await dispatch(0);
|
package/lib/provider.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MiddlewareIndex } from './middleware-index.js';
|
|
2
2
|
export declare const middlewareFeatureId: import("@zhin.js/plugin-runtime").FeatureId;
|
|
3
|
-
declare const middlewareFeature: Readonly<import("@zhin.js/feature-kit").FeatureProvider<import("./definition.js").MiddlewareDefinition<unknown, unknown>, MiddlewareIndex>>;
|
|
3
|
+
declare const middlewareFeature: Readonly<import("@zhin.js/feature-kit").FeatureProvider<import("./definition.js").MiddlewareDefinition<unknown, unknown, string | undefined>, MiddlewareIndex>>;
|
|
4
4
|
export { middlewareFeature };
|
|
5
5
|
export default middlewareFeature;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/middleware",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Convention-based Middleware Feature for Zhin Plugin Runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"src"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@zhin.js/feature-kit": "1.0.
|
|
21
|
-
"@zhin.js/plugin-runtime": "1.1.
|
|
20
|
+
"@zhin.js/feature-kit": "1.0.13",
|
|
21
|
+
"@zhin.js/plugin-runtime": "1.1.8"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^26.1.2",
|
package/src/definition.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Middleware authoring API consumed from `zhin.js/middleware`.
|
|
3
|
+
* @module zhin.js/middleware
|
|
4
|
+
*/
|
|
5
|
+
import type {
|
|
6
|
+
AdapterClient,
|
|
7
|
+
CapabilityContext,
|
|
8
|
+
RegisteredAdapterName,
|
|
9
|
+
} from '@zhin.js/feature-kit';
|
|
2
10
|
|
|
3
11
|
const middlewareBrand = 'zhin.middleware/1' as const;
|
|
4
12
|
|
|
@@ -6,41 +14,81 @@ export type MiddlewarePhase = 'before-dispatch' | 'after-dispatch';
|
|
|
6
14
|
export type MiddlewareTarget = 'inbound' | 'outbound';
|
|
7
15
|
export type MiddlewareNext = () => Promise<void>;
|
|
8
16
|
|
|
9
|
-
export interface MiddlewareContext<
|
|
17
|
+
export interface MiddlewareContext<
|
|
18
|
+
TInput = unknown,
|
|
19
|
+
TConfig = unknown,
|
|
20
|
+
TAdapter extends string | undefined = undefined,
|
|
21
|
+
>
|
|
10
22
|
extends CapabilityContext<TConfig> {
|
|
11
23
|
readonly input: TInput;
|
|
24
|
+
/** Lazily resolved native Client. Without `adapter`, its static type is `unknown`. */
|
|
25
|
+
readonly $client: AdapterClient<TAdapter>;
|
|
12
26
|
}
|
|
13
27
|
|
|
14
|
-
export interface MiddlewareDefinition<
|
|
28
|
+
export interface MiddlewareDefinition<
|
|
29
|
+
TInput = unknown,
|
|
30
|
+
TConfig = unknown,
|
|
31
|
+
TAdapter extends string | undefined = string | undefined,
|
|
32
|
+
> {
|
|
33
|
+
/** @internal Runtime feature brand. */
|
|
15
34
|
readonly $feature: typeof middlewareBrand;
|
|
16
35
|
readonly phase: MiddlewarePhase;
|
|
17
36
|
readonly target: MiddlewareTarget;
|
|
18
37
|
readonly order: number;
|
|
19
|
-
|
|
38
|
+
readonly adapter?: TAdapter;
|
|
39
|
+
handle(
|
|
40
|
+
context: MiddlewareContext<TInput, TConfig, TAdapter>,
|
|
41
|
+
next: MiddlewareNext,
|
|
42
|
+
): void | Promise<void>;
|
|
20
43
|
}
|
|
21
44
|
|
|
22
45
|
declare module '@zhin.js/plugin-runtime' {
|
|
23
|
-
interface PluginSetupContext<TConfig> {
|
|
46
|
+
interface PluginSetupContext<TConfig = unknown> {
|
|
24
47
|
addMiddleware<TInput = unknown>(
|
|
25
48
|
localName: string,
|
|
26
|
-
definition: MiddlewareDefinition<TInput, TConfig>,
|
|
49
|
+
definition: MiddlewareDefinition<TInput, TConfig, string | undefined>,
|
|
27
50
|
): void;
|
|
28
51
|
}
|
|
29
52
|
}
|
|
30
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Define ordered inbound or outbound middleware.
|
|
56
|
+
* Call `next()` to continue the chain; omit it to stop dispatch deliberately.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
type MiddlewareAuthoringDefinition<TInput, TConfig> =
|
|
61
|
+
| (Omit<
|
|
62
|
+
MiddlewareDefinition<TInput, TConfig, undefined>,
|
|
63
|
+
'$feature' | 'phase' | 'target' | 'order'
|
|
64
|
+
> & {
|
|
65
|
+
readonly phase?: MiddlewarePhase;
|
|
66
|
+
readonly target?: MiddlewareTarget;
|
|
67
|
+
readonly order?: number;
|
|
68
|
+
})
|
|
69
|
+
| {
|
|
70
|
+
[TAdapter in RegisteredAdapterName]: Omit<
|
|
71
|
+
MiddlewareDefinition<TInput, TConfig, TAdapter>,
|
|
72
|
+
'$feature' | 'phase' | 'target' | 'order'
|
|
73
|
+
> & {
|
|
74
|
+
readonly adapter: TAdapter;
|
|
75
|
+
readonly phase?: MiddlewarePhase;
|
|
76
|
+
readonly target?: MiddlewareTarget;
|
|
77
|
+
readonly order?: number;
|
|
78
|
+
}
|
|
79
|
+
}[RegisteredAdapterName];
|
|
80
|
+
|
|
31
81
|
export function defineMiddleware<TInput = unknown, TConfig = unknown>(
|
|
32
|
-
definition:
|
|
33
|
-
|
|
34
|
-
'$feature' | 'phase' | 'target' | 'order'
|
|
35
|
-
> & {
|
|
36
|
-
readonly phase?: MiddlewarePhase;
|
|
37
|
-
readonly target?: MiddlewareTarget;
|
|
38
|
-
readonly order?: number;
|
|
39
|
-
},
|
|
40
|
-
): Readonly<MiddlewareDefinition<TInput, TConfig>> {
|
|
82
|
+
definition: MiddlewareAuthoringDefinition<TInput, TConfig>,
|
|
83
|
+
): Readonly<MiddlewareDefinition<TInput, TConfig, string | undefined>> {
|
|
41
84
|
if (typeof definition.handle !== 'function') {
|
|
42
85
|
throw new TypeError('Middleware handle must be a function');
|
|
43
86
|
}
|
|
87
|
+
const adapter = (definition as { readonly adapter?: unknown }).adapter;
|
|
88
|
+
if (adapter !== undefined
|
|
89
|
+
&& (typeof adapter !== 'string' || adapter.trim() === '')) {
|
|
90
|
+
throw new TypeError('Middleware adapter must be a non-empty string');
|
|
91
|
+
}
|
|
44
92
|
const phase = definition.phase ?? 'before-dispatch';
|
|
45
93
|
if (phase !== 'before-dispatch' && phase !== 'after-dispatch') {
|
|
46
94
|
throw new TypeError(`Invalid Middleware phase: ${String(phase)}`);
|
|
@@ -51,9 +99,12 @@ export function defineMiddleware<TInput = unknown, TConfig = unknown>(
|
|
|
51
99
|
}
|
|
52
100
|
const order = definition.order ?? 0;
|
|
53
101
|
if (!Number.isSafeInteger(order)) throw new TypeError('Middleware order must be a safe integer');
|
|
54
|
-
return Object.freeze({ ...definition, $feature: middlewareBrand, phase, target, order })
|
|
102
|
+
return Object.freeze({ ...definition, $feature: middlewareBrand, phase, target, order }) as Readonly<
|
|
103
|
+
MiddlewareDefinition<TInput, TConfig, string | undefined>
|
|
104
|
+
>;
|
|
55
105
|
}
|
|
56
106
|
|
|
107
|
+
/** @internal Runtime validation for convention-discovered modules. */
|
|
57
108
|
export function parseMiddlewareDefinition(value: unknown): MiddlewareDefinition {
|
|
58
109
|
if (!value || typeof value !== 'object') throw invalidMiddleware();
|
|
59
110
|
const definition = value as Partial<MiddlewareDefinition>;
|
|
@@ -63,6 +114,7 @@ export function parseMiddlewareDefinition(value: unknown): MiddlewareDefinition
|
|
|
63
114
|
|| (definition.phase !== 'before-dispatch' && definition.phase !== 'after-dispatch')
|
|
64
115
|
|| (definition.target !== 'inbound' && definition.target !== 'outbound')
|
|
65
116
|
|| !Number.isSafeInteger(definition.order)
|
|
117
|
+
|| !validAdapterName((definition as { readonly adapter?: unknown }).adapter)
|
|
66
118
|
) throw invalidMiddleware();
|
|
67
119
|
return definition as MiddlewareDefinition;
|
|
68
120
|
}
|
|
@@ -70,3 +122,7 @@ export function parseMiddlewareDefinition(value: unknown): MiddlewareDefinition
|
|
|
70
122
|
function invalidMiddleware(): TypeError {
|
|
71
123
|
return new TypeError('Middleware module must default-export defineMiddleware(...)');
|
|
72
124
|
}
|
|
125
|
+
|
|
126
|
+
function validAdapterName(adapter: unknown): boolean {
|
|
127
|
+
return adapter === undefined || (typeof adapter === 'string' && adapter.trim() !== '');
|
|
128
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordered inbound and outbound middleware authoring contracts.
|
|
3
|
+
* @module @zhin.js/middleware
|
|
4
|
+
*/
|
|
5
|
+
/** @public Middleware authoring contract and `defineMiddleware`. */
|
|
1
6
|
export * from './definition.js';
|
|
7
|
+
/** @internal Runtime middleware projection. */
|
|
2
8
|
export * from './middleware-index.js';
|
|
9
|
+
/** @internal Feature provider installed by the Runtime composition root. */
|
|
3
10
|
export * from './provider.js';
|
|
4
11
|
export { default } from './provider.js';
|
package/src/middleware-index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { CapabilitySlot, PluginId, RuntimeSnapshot } from '@zhin.js/plugin-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createCapabilityContext,
|
|
4
|
+
operationClientAdapter,
|
|
5
|
+
readOperationClient,
|
|
6
|
+
} from '@zhin.js/feature-kit';
|
|
3
7
|
import type {
|
|
4
8
|
MiddlewareContext,
|
|
5
9
|
MiddlewareDefinition,
|
|
@@ -15,6 +19,7 @@ export interface MiddlewareDescriptor {
|
|
|
15
19
|
readonly phase: MiddlewarePhase;
|
|
16
20
|
readonly target: MiddlewareTarget;
|
|
17
21
|
readonly order: number;
|
|
22
|
+
readonly adapter?: string;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
interface MiddlewareRecord extends MiddlewareDescriptor {
|
|
@@ -37,6 +42,7 @@ export class MiddlewareIndex {
|
|
|
37
42
|
phase: slot.definition.phase,
|
|
38
43
|
target: slot.definition.target,
|
|
39
44
|
order: slot.definition.order,
|
|
45
|
+
...(slot.definition.adapter ? { adapter: slot.definition.adapter } : {}),
|
|
40
46
|
slot,
|
|
41
47
|
})).sort((left, right) => compareMiddleware(left, right, topology)));
|
|
42
48
|
}
|
|
@@ -50,17 +56,24 @@ export class MiddlewareIndex {
|
|
|
50
56
|
terminal: MiddlewareNext = async () => undefined,
|
|
51
57
|
target: MiddlewareTarget = 'inbound',
|
|
52
58
|
): Promise<void> {
|
|
53
|
-
const
|
|
59
|
+
const clientAdapter = operationClientAdapter(input);
|
|
60
|
+
const records = this.#records.filter((record) =>
|
|
61
|
+
record.target === target && (!record.adapter || record.adapter === clientAdapter));
|
|
54
62
|
let cursor = -1;
|
|
55
63
|
const dispatch = async (index: number): Promise<void> => {
|
|
56
64
|
if (index <= cursor) throw new Error('Middleware next() called more than once');
|
|
57
65
|
cursor = index;
|
|
58
66
|
const record = records[index];
|
|
59
67
|
if (!record) return terminal();
|
|
60
|
-
const context
|
|
68
|
+
const context = {
|
|
61
69
|
...createCapabilityContext(this.snapshot, record.owner),
|
|
62
70
|
input,
|
|
71
|
+
} as MiddlewareContext<TInput>;
|
|
72
|
+
Object.defineProperty(context, '$client', {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: () => readOperationClient(input, record.adapter),
|
|
63
75
|
});
|
|
76
|
+
Object.freeze(context);
|
|
64
77
|
await record.slot.definition.handle(context, () => dispatch(index + 1));
|
|
65
78
|
};
|
|
66
79
|
await dispatch(0);
|