@azure-net/kit 6.0.0-next.13 → 6.0.0-next.15

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 CHANGED
@@ -189,13 +189,13 @@ export {};
189
189
  ```
190
190
 
191
191
  ```ts
192
- import { createApp } from '@azure-net/kit';
192
+ import { createApp, ServerMiddlewareManager } from '@azure-net/kit';
193
193
  import { RequestContext } from '@azure-net/kit/server-context';
194
194
 
195
195
  export const { register } = createApp((app) =>
196
196
  app
197
- .useServer(async ({ event, resolve, useMiddlewares }) => {
198
- await useMiddlewares([ServerAuth]);
197
+ .useServer(async ({ event, resolve }) => {
198
+ await new ServerMiddlewareManager([ServerAuth]).execute();
199
199
  return resolve(event);
200
200
  })
201
201
  .useBoot(({ state }) => {
@@ -300,7 +300,15 @@ only when its turn is reached, on every request/navigation. Resolve dependencies
300
300
  inside that instance, not into module-level request-specific variables.
301
301
 
302
302
  ```ts
303
- import type { IServerMiddleware, ServerMiddlewareContext, IClientMiddleware, ClientMiddlewareContext } from '@azure-net/kit';
303
+ import {
304
+ ServerMiddlewareManager,
305
+ ClientMiddlewareManager,
306
+ type IServerMiddleware,
307
+ type ServerMiddlewareContext,
308
+ type IClientMiddleware,
309
+ type ClientMiddlewareContext
310
+ } from '@azure-net/kit';
311
+ import { beforeNavigate } from '$app/navigation';
304
312
 
305
313
  class ServerAuth implements IServerMiddleware {
306
314
  async execute({ event, next }: ServerMiddlewareContext) {
@@ -317,16 +325,26 @@ class ClientGuard implements IClientMiddleware {
317
325
  }
318
326
  }
319
327
 
328
+ const serverMiddlewares = new ServerMiddlewareManager([ServerAuth]);
329
+ const clientMiddlewares = new ClientMiddlewareManager([ClientGuard]);
330
+
320
331
  app
321
- .useServer(async ({ useMiddlewares, event, resolve }) => {
322
- await useMiddlewares([ServerAuth]);
332
+ .useServer(async ({ event, resolve }) => {
333
+ await serverMiddlewares.execute();
323
334
  return resolve(event);
324
335
  })
325
- .useClient(({ useMiddlewares }) => {
326
- useMiddlewares([ClientGuard]);
336
+ .useClient(() => {
337
+ beforeNavigate((navigation) => clientMiddlewares.execute(navigation));
327
338
  });
339
+
340
+ // Run the same checks without navigating or registering another subscription.
341
+ clientMiddlewares.execute();
328
342
  ```
329
343
 
344
+ Managers snapshot the constructor list and retain no request data or middleware instances, so they can be declared at module scope. `ServerMiddlewareManager.execute()` resolves the current request each time. `ClientMiddlewareManager.execute()` uses the current page URL; `from` and `navigation` are undefined in a manual run. Client execution is a no-op during SSR.
345
+
346
+ `createApp` no longer injects `useMiddlewares` or subscribes to navigation itself. Register `beforeNavigate` synchronously inside `useClient`, before any `await`. A manual run does not create a navigation to cancel: omitting `next()` only stops that run. Avoid calling a manager from middleware that it executes, including indirectly through HTTP recovery. Re-running a full chain also re-runs analytics; use a smaller manager if only auth state must be synchronized.
347
+
330
348
  `IMiddleware<Context, Result>` is the common interface. Client `execute` is strictly
331
349
  synchronous (`undefined` return, normally `return next()`); server `execute` can
332
350
  return `void` or `Promise<void>`. Omitting `next()` blocks the chain. Neither the
@@ -382,7 +400,11 @@ cases. With no `retry` option, a failed request is not repeated. `limit` counts
382
400
  additional attempts: `limit: 1` means at most two HTTP attempts.
383
401
 
384
402
  ```ts
403
+ // A separate session client: no authentication recovery hooks.
404
+ const sessionHttp = new HttpServiceInstance({ prefixUrl: apiUrl });
405
+
385
406
  const http = new HttpServiceInstance({
407
+ prefixUrl: apiUrl,
386
408
  onRequest(request) {
387
409
  const token = readAccessToken();
388
410
  if (token) request.headers.set('Authorization', `Bearer ${token}`);
@@ -392,9 +414,8 @@ const http = new HttpServiceInstance({
392
414
  statuses: [401],
393
415
  async shouldRetry({ error }) {
394
416
  if (!isExpiredAccessToken(error.data)) return false;
395
- const refreshed = await http.post('/api/auth/refresh', {
396
- json: { refreshToken: readRefreshToken() },
397
- retry: { limit: 0 }
417
+ const refreshed = await sessionHttp.post('/api/auth/refresh', {
418
+ json: { refreshToken: readRefreshToken() }
398
419
  });
399
420
  saveTokens(refreshed.data);
400
421
  return true;
@@ -413,16 +434,16 @@ implement token rotation or cross-tab coordination.
413
434
  - `shouldRetry` runs only after the status filter and only while budget remains.
414
435
  Both synchronous and asynchronous booleans are accepted.
415
436
  - Per-request `retry` replaces the entire default policy. Use `{ limit: 0 }` to
416
- disable it, **especially for refresh requests made inside `shouldRetry`**.
417
- A nested HTTP call has its own budget; forgetting this override can recurse.
437
+ disable it. A separate session client with no retry policy does not inherit
438
+ the application client's retries or hooks.
418
439
  - `onRequest` runs before every attempt so refreshed credentials are read again.
419
440
  `onResponse` runs once on success; `onError` runs once on terminal HTTP failure,
420
441
  not for intermediate failures that recover successfully.
421
442
  - Exceptions from hooks (including `shouldRetry`) propagate without further
422
443
  recovery. They are not treated as another failed transport attempt.
423
444
  - Cancelled requests and streaming request bodies are never replayed. Cancellation
424
- is checked again after awaiting recovery; the callback must manage its own async
425
- work and cancellation if needed.
445
+ also stops waiting for recovery; the callback must manage cancellation of its
446
+ own underlying work.
426
447
  - `limit` must be a finite non-negative safe integer. There is no implicit retry
427
448
  delay/backoff. Timeout is applied separately to each HTTP attempt.
428
449
 
@@ -430,3 +451,40 @@ Retries are opt-in for all HTTP methods. Do not blindly retry writes after netwo
430
451
  errors: the server may already have applied them. Use a narrow status/code policy
431
452
  or backend-supported idempotency keys. Numerical `retry: 3` is no longer supported;
432
453
  write `retry: { limit: 3 }` instead.
454
+
455
+ HTTP hooks use these signatures:
456
+
457
+ ```ts
458
+ retry: {
459
+ limit: 1,
460
+ shouldRetry: async ({ error }) => {
461
+ // Delegate refresh to your session service with a separate HTTP client.
462
+ return false;
463
+ }
464
+ },
465
+ onError: ({ error, request }) => {
466
+ // Terminal failure notification / validation mapping. No http is exposed.
467
+ }
468
+ ```
469
+
470
+ This is a breaking change from positional `onError(error, request, http)`.
471
+ Request-level hook overrides use the same signatures. Nested requests use instance
472
+ settings plus their own options, not the outer request's body or signal.
473
+
474
+ AbortSignal stops waiting for hooks as well as transport operations. Arbitrary
475
+ user promises cannot be forcibly terminated: hooks must cooperate to stop their
476
+ own side effects. Hooks have no implicit timeout; supply and abort a signal to
477
+ bound their waiting time. The per-attempt timeout covers transport and body
478
+ parsing, including custom `doFetch`. With `responseFormat: 'body'`, it ends when
479
+ the stream is returned; reading/cancelling that stream is then the caller's job.
480
+ Timers/listeners are removed on success, failure, timeout and cancellation.
481
+
482
+ JSON serialization errors now reject before sending rather than silently sending
483
+ an empty body. The default JSON serializer does not support cyclic values or
484
+ BigInt; provide `stringifyJson` if a custom wire format is required.
485
+
486
+ Removing `http` from `onError` does not prevent recursion through a client captured
487
+ in a closure. Do not initiate the same failing operation from its error handler.
488
+ Neither `shouldRetry` nor `onError` exposes the HTTP client. Use a separate
489
+ session client without recovery hooks for refresh/logout. Limits apply per HTTP
490
+ call, not to arbitrary nested user code.
@@ -66,7 +66,10 @@ export interface IHttpInstanceNormalizedRequest {
66
66
  requestInit: Omit<RequestInit, 'method' | 'headers' | 'body'>;
67
67
  }
68
68
  export type IHttpInstanceOnRequest = (request: IHttpInstanceNormalizedRequest) => void | Promise<void>;
69
- export type IHttpInstanceOnError = (error: HttpServiceError<unknown>, request: IHttpInstanceNormalizedRequest) => void | Promise<void>;
69
+ export type IHttpInstanceOnError = (context: {
70
+ error: HttpServiceError<unknown>;
71
+ request: IHttpInstanceNormalizedRequest;
72
+ }) => void | Promise<void>;
70
73
  export type IHttpInstanceDoFetch = <T = unknown>(request: IHttpInstanceNormalizedRequest) => Promise<IHttpServiceResponse<T>>;
71
74
  export interface IHttpInstanceRetryOptions {
72
75
  /** Number of additional attempts. Zero disables retries, including inherited policies. */
@@ -56,14 +56,7 @@ export class HttpServiceError extends Error {
56
56
  return this.data;
57
57
  }
58
58
  }
59
- const stringifyJsonFunc = (data) => {
60
- try {
61
- return JSON.stringify(data);
62
- }
63
- catch {
64
- return undefined;
65
- }
66
- };
59
+ const stringifyJsonFunc = (data) => JSON.stringify(data);
67
60
  const isAbsoluteUrl = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value);
68
61
  const normalizeHeaders = (headers) => {
69
62
  if (!headers)
@@ -107,7 +100,7 @@ const mergeSearchParams = (base, extra) => {
107
100
  return result;
108
101
  };
109
102
  const mergeOptions = (base = {}, extra = {}) => {
110
- const mergedHeaders = new Headers(normalizeHeaders(base.headers));
103
+ const mergedHeaders = normalizeHeaders(base.headers);
111
104
  for (const [key, value] of normalizeHeaders(extra.headers).entries()) {
112
105
  mergedHeaders.set(key, value);
113
106
  }
@@ -238,28 +231,46 @@ const parseResponse = async (response, request) => {
238
231
  return { data, headers: Object.fromEntries(response.headers.entries()), status: response.status, raw };
239
232
  };
240
233
  const defaultDoFetch = async (request) => {
241
- const timeoutState = withTimeout(request.requestInit.signal, request.timeout);
242
- try {
243
- const response = await request.fetch(request.url, {
244
- ...request.requestInit,
245
- method: request.method,
246
- headers: request.headers,
247
- body: request.body,
248
- signal: timeoutState.signal ?? undefined
234
+ const response = await request.fetch(request.url, {
235
+ ...request.requestInit,
236
+ ...(typeof ReadableStream !== 'undefined' && request.body instanceof ReadableStream ? { duplex: 'half' } : {}),
237
+ method: request.method,
238
+ headers: request.headers,
239
+ body: request.body
240
+ });
241
+ const { data, headers, status, raw } = await parseResponse(response, request);
242
+ return new HttpServiceResponse({ headers, status, success: true, data, message: 'Request completed', raw });
243
+ };
244
+ // Stop waiting even when a custom transport or hook ignores AbortSignal.
245
+ // The underlying operation must cooperate to actually stop its own work.
246
+ const waitForSignal = (value, signal) => {
247
+ if (!signal)
248
+ return Promise.resolve(value);
249
+ return new Promise((resolve, reject) => {
250
+ const abort = () => {
251
+ cleanup();
252
+ reject(signal.reason);
253
+ };
254
+ const cleanup = () => signal.removeEventListener('abort', abort);
255
+ if (signal.aborted)
256
+ abort();
257
+ else
258
+ signal.addEventListener('abort', abort, { once: true });
259
+ Promise.resolve(value).then((result) => {
260
+ cleanup();
261
+ resolve(result);
262
+ }, (error) => {
263
+ cleanup();
264
+ reject(error);
249
265
  });
250
- const { data, headers, status, raw } = await parseResponse(response, request);
251
- return new HttpServiceResponse({ headers, status, success: true, data, message: 'Request completed', raw });
252
- }
253
- finally {
254
- timeoutState.clear();
255
- }
266
+ });
256
267
  };
257
268
  const makeMethod = (method, defaults) => {
258
269
  return async (url, options = {}) => {
259
270
  const merged = mergeOptions(defaults, options);
260
271
  const stringifyJson = merged.stringifyJson ?? stringifyJsonFunc;
261
272
  const fetcher = !BROWSER ? (RequestContext.current()?.event?.fetch ?? fetch) : fetch;
262
- const headers = normalizeHeaders(merged.headers);
273
+ const headers = merged.headers;
263
274
  let body = merged.body;
264
275
  if (merged.json !== undefined && body === undefined) {
265
276
  body = stringifyJson(merged.json);
@@ -297,6 +308,11 @@ const makeMethod = (method, defaults) => {
297
308
  }
298
309
  };
299
310
  // Snapshot the policy per call: hooks and concurrent requests cannot extend its budget.
311
+ const sourceSignal = merged.signal;
312
+ const timeout = normalizedRequest.timeout;
313
+ if (timeout !== false && (!Number.isFinite(timeout) || timeout < 0 || timeout > 2147483647)) {
314
+ throw new RangeError('timeout must be false or a finite number between 0 and 2147483647');
315
+ }
300
316
  const policy = merged.retry;
301
317
  const limit = policy?.limit ?? 0;
302
318
  if (!Number.isSafeInteger(limit) || limit < 0) {
@@ -307,13 +323,22 @@ const makeMethod = (method, defaults) => {
307
323
  const doFetch = merged.doFetch ?? defaultDoFetch;
308
324
  let fetched;
309
325
  for (let attempt = 0;; attempt++) {
310
- normalizedRequest.requestInit.signal?.throwIfAborted();
326
+ sourceSignal?.throwIfAborted();
311
327
  // Re-run authentication/header hooks after recovery, without accumulating headers.
312
- normalizedRequest.headers = new Headers(headers);
313
- await merged.onRequest?.(normalizedRequest);
328
+ normalizedRequest.headers = merged.onRequest ? new Headers(headers) : headers;
329
+ if (merged.onRequest)
330
+ await waitForSignal(merged.onRequest(normalizedRequest), sourceSignal);
314
331
  normalizedRequest.requestInit.signal?.throwIfAborted();
315
332
  try {
316
- fetched = await doFetch(normalizedRequest);
333
+ const timeoutState = withTimeout(sourceSignal, timeout);
334
+ normalizedRequest.requestInit.signal = timeoutState.signal;
335
+ try {
336
+ fetched = await waitForSignal(doFetch(normalizedRequest), timeoutState.signal);
337
+ }
338
+ finally {
339
+ timeoutState.clear();
340
+ normalizedRequest.requestInit.signal = sourceSignal;
341
+ }
317
342
  break;
318
343
  }
319
344
  catch (error) {
@@ -323,19 +348,22 @@ const makeMethod = (method, defaults) => {
323
348
  message: normalizeUnknownError(error).message,
324
349
  original: normalizeUnknownError(error)
325
350
  });
326
- const aborted = normalizedRequest.requestInit.signal?.aborted || normalizedError.original?.name === 'AbortError';
351
+ const aborted = sourceSignal?.aborted || normalizedError.original?.name === 'AbortError';
327
352
  const streaming = typeof ReadableStream !== 'undefined' && normalizedRequest.body instanceof ReadableStream;
328
353
  const eligible = !aborted && !streaming && attempt < limit && (!statuses || statuses.includes(normalizedError.status));
329
- if (eligible && (!shouldRetry || (await shouldRetry({ error: normalizedError })))) {
354
+ if (eligible && (!shouldRetry || (await waitForSignal(shouldRetry({ error: normalizedError }), sourceSignal)))) {
330
355
  normalizedRequest.requestInit.signal?.throwIfAborted();
331
356
  continue;
332
357
  }
333
- await merged.onError?.(normalizedError, normalizedRequest);
358
+ if (merged.onError)
359
+ await waitForSignal(merged.onError({ error: normalizedError, request: normalizedRequest }), sourceSignal);
334
360
  throw normalizedError;
335
361
  }
336
362
  }
337
363
  // Consumer callback failures must never replay a successful HTTP operation.
338
- await merged.onResponse?.(fetched);
364
+ sourceSignal?.throwIfAborted();
365
+ if (merged.onResponse)
366
+ await waitForSignal(merged.onResponse(fetched), sourceSignal);
339
367
  return fetched;
340
368
  };
341
369
  };
@@ -1,9 +1,7 @@
1
1
  import { type TranslationManagerSource } from '../../i18n/Internal.js';
2
2
  import { type ContextData } from '../../shared/request-context/Internal.js';
3
- import { type ServerMiddlewareClass } from './middleware/ServerMiddleware.js';
4
3
  import type { Handle, HandleFetch, HandleServerError, HandleClientError, Reroute, ServerInit, Transport } from '@sveltejs/kit/hooks';
5
4
  import type { RequestEvent } from '@sveltejs/kit';
6
- import { type ClientMiddlewareClass } from './middleware/ClientMiddleware.js';
7
5
  import { useLogger } from '../logger/index.js';
8
6
  type MaybePromise<T> = T | Promise<T>;
9
7
  type HandleInput = Parameters<Handle>[0];
@@ -11,9 +9,7 @@ type Resolve = HandleInput['resolve'];
11
9
  type BuilderFlags = Partial<Record<'useTranslations' | 'useBoot' | 'useClient' | 'useClientInit' | 'useClientError' | 'useServerInit' | 'useServer' | 'useServerError' | 'useServerFetch' | 'useReroute' | 'useTransport', true>>;
12
10
  type WithFlag<TFlags extends BuilderFlags, TKey extends keyof BuilderFlags> = TFlags & Record<TKey, true>;
13
11
  type OnceMethod<TFlags extends BuilderFlags, TKey extends keyof BuilderFlags, TMethod> = TFlags[TKey] extends true ? object : TMethod;
14
- export interface AppClientLifecycleContext {
15
- useMiddlewares: (middlewares: readonly ClientMiddlewareClass[]) => void;
16
- }
12
+ export type AppClientLifecycleContext = void;
17
13
  export type AppClientInitLifecycleContext = void;
18
14
  export type AppClientErrorContext = Parameters<HandleClientError>[0];
19
15
  export type AppServerInitLifecycleContext = void;
@@ -21,7 +17,6 @@ export interface AppServerLifecycleContext {
21
17
  requestContext: ContextData;
22
18
  event: RequestEvent;
23
19
  resolve: Resolve;
24
- useMiddlewares: (middlewares: readonly ServerMiddlewareClass[]) => Promise<void>;
25
20
  }
26
21
  export type AppServerErrorContext = Parameters<HandleServerError>[0] & {
27
22
  requestContext: ContextData;
@@ -4,9 +4,6 @@ import { getContextInternals } from '../../shared/request-context/Internal.js';
4
4
  import { BROWSER } from '../../external/tools/index.js';
5
5
  import { RequestContext } from '../../shared/request-context/Internal.js';
6
6
  import { AzureNetKitInternalError } from '../app-error/AppError.js';
7
- import { executeServerMiddlewares } from './middleware/ServerMiddleware.js';
8
- import { beforeNavigate } from '$app/navigation';
9
- import { executeClientMiddlewares } from './middleware/ClientMiddleware.js';
10
7
  import { useLogger } from '../logger/index.js';
11
8
  const clientLifecycleFlags = new WeakMap();
12
9
  const getRequestContext = () => {
@@ -102,7 +99,6 @@ const createBuilder = (callbacks) => {
102
99
  export const createApp = (callback) => {
103
100
  const appKey = {};
104
101
  const callbacks = {};
105
- let clientInitialized = false;
106
102
  let translationInitPromise;
107
103
  let serverInitPromise;
108
104
  callback(createBuilder(callbacks));
@@ -127,18 +123,7 @@ export const createApp = (callback) => {
127
123
  });
128
124
  return translationInitPromise;
129
125
  }
130
- let internalMiddlewares = [];
131
- if (!clientInitialized) {
132
- beforeNavigate((navigation) => {
133
- executeClientMiddlewares(internalMiddlewares, navigation);
134
- });
135
- clientInitialized = true;
136
- }
137
- return callbacks.useClient?.({
138
- useMiddlewares: (middlewares) => {
139
- internalMiddlewares = middlewares;
140
- }
141
- });
126
+ return callbacks.useClient?.();
142
127
  };
143
128
  const runServerInit = () => {
144
129
  if (BROWSER)
@@ -184,8 +169,7 @@ export const createApp = (callback) => {
184
169
  const serverResult = await callbacks.useServer?.({
185
170
  requestContext,
186
171
  event,
187
- resolve,
188
- useMiddlewares: executeServerMiddlewares
172
+ resolve
189
173
  });
190
174
  if (serverResult)
191
175
  return serverResult;
@@ -1,6 +1,8 @@
1
1
  export { createApp, type AppClientErrorCallback, type AppClientErrorContext, type AppClientInitLifecycleCallback, type AppClientInitLifecycleContext, type AppClientLifecycleCallback, type AppClientLifecycleContext, type AppRegistrar, type AppServerErrorCallback, type AppServerErrorContext, type AppServerFetchCallback, type AppServerFetchContext, type AppServerInitLifecycleCallback, type AppServerInitLifecycleContext, type AppServerLifecycleCallback, type AppServerLifecycleContext, type AppRerouteCallback, type CreateAppInstance } from './App.js';
2
2
  export type { IClientMiddleware, ClientMiddlewareContext, ClientMiddlewareClass } from './middleware/ClientMiddleware.js';
3
+ export { ClientMiddlewareManager } from './middleware/ClientMiddleware.js';
3
4
  export type { IServerMiddleware, ServerMiddlewareContext, ServerMiddlewareClass } from './middleware/ServerMiddleware.js';
5
+ export { ServerMiddlewareManager } from './middleware/ServerMiddleware.js';
4
6
  export type { IMiddleware, MiddlewareClass } from './middleware/Types.js';
5
7
  export type { EnsureRoute, EnsureRouteSource, EnsureRouteTarget } from './middleware/Shared.js';
6
8
  export type { AppBootContext, AppBootCallback } from './App.js';
@@ -1 +1,3 @@
1
1
  export { createApp } from './App.js';
2
+ export { ClientMiddlewareManager } from './middleware/ClientMiddleware.js';
3
+ export { ServerMiddlewareManager } from './middleware/ServerMiddleware.js';
@@ -13,4 +13,10 @@ export interface IClientMiddleware extends IMiddleware<ClientMiddlewareContext,
13
13
  execute(context: ClientMiddlewareContext): undefined;
14
14
  }
15
15
  export type ClientMiddlewareClass = MiddlewareClass<IClientMiddleware>;
16
+ /** Execute manually, or pass the navigation supplied by beforeNavigate. */
17
+ export declare class ClientMiddlewareManager {
18
+ private readonly middlewares;
19
+ constructor(middlewares: readonly ClientMiddlewareClass[]);
20
+ execute(navigation?: BeforeNavigate): void;
21
+ }
16
22
  export declare const executeClientMiddlewares: (middlewares: readonly ClientMiddlewareClass[], navigation?: BeforeNavigate) => void;
@@ -1,6 +1,19 @@
1
1
  import { ensureRoute } from './Shared.js';
2
2
  import { page } from '$app/state';
3
3
  import { goto } from '$app/navigation';
4
+ import { BROWSER } from '../../../external/tools/index.js';
5
+ /** Execute manually, or pass the navigation supplied by beforeNavigate. */
6
+ export class ClientMiddlewareManager {
7
+ middlewares;
8
+ constructor(middlewares) {
9
+ this.middlewares = [...middlewares];
10
+ }
11
+ execute(navigation) {
12
+ if (!BROWSER)
13
+ return;
14
+ executeClientMiddlewares(this.middlewares, navigation);
15
+ }
16
+ }
4
17
  export const executeClientMiddlewares = (middlewares, navigation) => {
5
18
  const from = navigation?.from?.url ?? undefined;
6
19
  const to = navigation?.to?.url ?? page.url;
@@ -13,4 +13,10 @@ export interface IServerMiddleware extends IMiddleware<ServerMiddlewareContext,
13
13
  execute(context: ServerMiddlewareContext): Promise<void> | void;
14
14
  }
15
15
  export type ServerMiddlewareClass = MiddlewareClass<IServerMiddleware>;
16
+ /** Stores definitions only; request context and instances are resolved per execution. */
17
+ export declare class ServerMiddlewareManager {
18
+ private readonly middlewares;
19
+ constructor(middlewares: readonly ServerMiddlewareClass[]);
20
+ execute(): Promise<void>;
21
+ }
16
22
  export declare const executeServerMiddlewares: (middlewares: readonly ServerMiddlewareClass[]) => Promise<void>;
@@ -2,6 +2,16 @@ import { error, redirect } from '@sveltejs/kit';
2
2
  import { ensureRoute } from './Shared.js';
3
3
  import { BROWSER } from '../../../external/tools/index.js';
4
4
  import { RequestContext } from '../../../shared/request-context/Internal.js';
5
+ /** Stores definitions only; request context and instances are resolved per execution. */
6
+ export class ServerMiddlewareManager {
7
+ middlewares;
8
+ constructor(middlewares) {
9
+ this.middlewares = [...middlewares];
10
+ }
11
+ execute() {
12
+ return executeServerMiddlewares(this.middlewares);
13
+ }
14
+ }
5
15
  export const executeServerMiddlewares = async (middlewares) => {
6
16
  if (!BROWSER && middlewares.length) {
7
17
  const event = RequestContext.current().event;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-net/kit",
3
- "version": "6.0.0-next.13",
3
+ "version": "6.0.0-next.15",
4
4
  "license": "MIT",
5
5
  "author": "Pixel1917",
6
6
  "description": "Universal toolkit and library collection, developed as part of the Azure-net ecosystem",