@loutrejs/loutre 0.6.0 → 0.8.0

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.
Files changed (71) hide show
  1. package/dist/adapters/bun.d.ts +2 -4
  2. package/dist/adapters/bun.js +36 -28
  3. package/dist/adapters/cloudflare-workers.d.ts +2 -4
  4. package/dist/adapters/cloudflare-workers.js +6 -11
  5. package/dist/adapters/server-transports.d.ts +4 -0
  6. package/dist/adapters/server-transports.js +18 -0
  7. package/dist/adapters/websocket-native.d.ts +24 -0
  8. package/dist/adapters/websocket-native.js +150 -0
  9. package/dist/application/kernel.d.ts +2 -1
  10. package/dist/core/extension.d.ts +26 -3
  11. package/dist/core/extension.js +19 -0
  12. package/dist/core/index.d.ts +2 -1
  13. package/dist/core/instrumentation.d.ts +36 -0
  14. package/dist/core/instrumentation.js +1 -0
  15. package/dist/core/model/modules.js +13 -17
  16. package/dist/core/model.js +14 -4
  17. package/dist/core/module.d.ts +3 -3
  18. package/dist/devtools/capsule.d.ts +51 -0
  19. package/dist/devtools/capsule.js +247 -0
  20. package/dist/devtools/index.d.ts +11 -0
  21. package/dist/devtools/index.js +6 -0
  22. package/dist/devtools/inspector.d.ts +57 -0
  23. package/dist/devtools/inspector.js +1 -0
  24. package/dist/devtools/module.d.ts +18 -0
  25. package/dist/devtools/module.js +26 -0
  26. package/dist/devtools/observer.d.ts +77 -0
  27. package/dist/devtools/observer.js +10 -0
  28. package/dist/devtools/protocol.d.ts +1 -0
  29. package/dist/devtools/protocol.js +1 -0
  30. package/dist/devtools/provider-instrumentation.d.ts +14 -0
  31. package/dist/devtools/provider-instrumentation.js +117 -0
  32. package/dist/devtools/runtime.d.ts +20 -0
  33. package/dist/devtools/runtime.js +519 -0
  34. package/dist/devtools/values.d.ts +35 -0
  35. package/dist/devtools/values.js +172 -0
  36. package/dist/generated/version.d.ts +1 -1
  37. package/dist/generated/version.js +1 -1
  38. package/dist/graph/model.js +37 -40
  39. package/dist/http/auth.d.ts +2 -2
  40. package/dist/http/auth.js +9 -0
  41. package/dist/http/client.js +5 -5
  42. package/dist/http/extension.d.ts +37 -10
  43. package/dist/http/extension.js +249 -57
  44. package/dist/http/index.d.ts +3 -2
  45. package/dist/http/index.js +1 -1
  46. package/dist/http/openapi.d.ts +3 -4
  47. package/dist/http/openapi.js +45 -26
  48. package/dist/http/request-head.d.ts +6 -0
  49. package/dist/http/request-head.js +1 -0
  50. package/dist/http/route-validation.d.ts +9 -0
  51. package/dist/http/route-validation.js +18 -0
  52. package/dist/http/runtime/response.js +10 -10
  53. package/dist/message-port/extension.js +20 -4
  54. package/dist/runtime/di.d.ts +4 -0
  55. package/dist/runtime/di.js +42 -31
  56. package/dist/runtime/engine.d.ts +1 -1
  57. package/dist/runtime/engine.js +1 -2
  58. package/dist/runtime/kernel.d.ts +4 -2
  59. package/dist/runtime/kernel.js +96 -3
  60. package/dist/runtime/node-capabilities.d.ts +1 -1
  61. package/dist/runtime/node-capabilities.js +2 -1
  62. package/dist/tasks/extension.js +133 -118
  63. package/dist/websocket/driver.d.ts +30 -0
  64. package/dist/websocket/driver.js +96 -0
  65. package/dist/websocket/extension.d.ts +33 -12
  66. package/dist/websocket/extension.js +72 -47
  67. package/dist/websocket/index.d.ts +3 -1
  68. package/dist/websocket/index.js +1 -0
  69. package/package.json +7 -6
  70. package/dist/adapters/deno.d.ts +0 -35
  71. package/dist/adapters/deno.js +0 -231
@@ -0,0 +1,172 @@
1
+ import { match } from 'ts-pattern';
2
+ const defaultMaxValueBytes = 64 * 1024;
3
+ const defaultMaxDepth = 8;
4
+ export function previewDevtoolsValue(value, options = {}) {
5
+ const maxValueBytes = options.maxValueBytes ?? defaultMaxValueBytes;
6
+ const maxDepth = options.maxDepth ?? defaultMaxDepth;
7
+ const redactions = new Set((options.redact ?? []).map((entry) => entry.trim().toLowerCase()));
8
+ let redacted = false;
9
+ let truncated = false;
10
+ const seen = new WeakSet();
11
+ const encode = (current, depth, path) => {
12
+ if (depth > maxDepth) {
13
+ truncated = true;
14
+ return '[Truncated]';
15
+ }
16
+ if (current === null)
17
+ return null;
18
+ switch (typeof current) {
19
+ case 'boolean':
20
+ case 'number':
21
+ case 'string':
22
+ return current;
23
+ case 'undefined':
24
+ return { $type: 'undefined' };
25
+ case 'bigint':
26
+ return { $type: 'bigint', value: current.toString() };
27
+ case 'function':
28
+ case 'symbol':
29
+ truncated = true;
30
+ return `[${typeof current}]`;
31
+ case 'object':
32
+ break;
33
+ }
34
+ if (current instanceof Date) {
35
+ return { $type: 'date', value: current.toISOString() };
36
+ }
37
+ if (current instanceof Uint8Array) {
38
+ return { $type: 'bytes', base64: bytesToBase64(current) };
39
+ }
40
+ if (seen.has(current)) {
41
+ truncated = true;
42
+ return '[Circular]';
43
+ }
44
+ seen.add(current);
45
+ try {
46
+ if (Array.isArray(current)) {
47
+ const output = [];
48
+ const descriptors = Object.getOwnPropertyDescriptors(current);
49
+ for (let index = 0; index < current.length; index += 1) {
50
+ const descriptor = descriptors[String(index)];
51
+ if (!descriptor) {
52
+ output.length = index + 1;
53
+ continue;
54
+ }
55
+ if (!('value' in descriptor)) {
56
+ truncated = true;
57
+ output[index] = '[Accessor]';
58
+ continue;
59
+ }
60
+ output[index] = encode(descriptor.value, depth + 1, [
61
+ ...path,
62
+ String(index),
63
+ ]);
64
+ }
65
+ return output;
66
+ }
67
+ if (current instanceof Map) {
68
+ return {
69
+ $type: 'map',
70
+ entries: [...current.entries()].map(([key, item], index) => [
71
+ encode(key, depth + 1, [...path, String(index), 'key']),
72
+ encode(item, depth + 1, [...path, String(index), 'value']),
73
+ ]),
74
+ };
75
+ }
76
+ if (current instanceof Set) {
77
+ return {
78
+ $type: 'set',
79
+ values: [...current.values()].map((item, index) => encode(item, depth + 1, [...path, String(index)])),
80
+ };
81
+ }
82
+ const output = {};
83
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(current))) {
84
+ if (!descriptor.enumerable)
85
+ continue;
86
+ const nextPath = [...path, key];
87
+ if (shouldRedact(key, nextPath, redactions)) {
88
+ redacted = true;
89
+ output[key] = { $type: 'redacted' };
90
+ continue;
91
+ }
92
+ if (!('value' in descriptor)) {
93
+ truncated = true;
94
+ output[key] = '[Accessor]';
95
+ continue;
96
+ }
97
+ output[key] = encode(descriptor.value, depth + 1, nextPath);
98
+ }
99
+ return output;
100
+ }
101
+ finally {
102
+ seen.delete(current);
103
+ }
104
+ };
105
+ try {
106
+ const encoded = encode(value, 0, []);
107
+ const serialized = JSON.stringify(encoded);
108
+ const bytes = utf8ByteLength(serialized);
109
+ const preview = serialized.length > 512 ? `${serialized.slice(0, 509)}...` : serialized;
110
+ if (bytes > maxValueBytes) {
111
+ return {
112
+ preview,
113
+ truncated: true,
114
+ ...(redacted ? { redacted: true } : {}),
115
+ type: valueType(value),
116
+ };
117
+ }
118
+ return {
119
+ value: encoded,
120
+ preview,
121
+ ...(truncated ? { truncated: true } : {}),
122
+ ...(redacted ? { redacted: true } : {}),
123
+ type: valueType(value),
124
+ };
125
+ }
126
+ catch {
127
+ const type = safeValueType(value);
128
+ return {
129
+ preview: `[${type}]`,
130
+ truncated: true,
131
+ type,
132
+ };
133
+ }
134
+ }
135
+ function shouldRedact(key, path, redactions) {
136
+ if (redactions.size === 0)
137
+ return false;
138
+ const normalizedKey = key.toLowerCase();
139
+ const normalizedPath = path.join('.').toLowerCase();
140
+ return redactions.has(normalizedKey) || redactions.has(normalizedPath);
141
+ }
142
+ function valueType(value) {
143
+ return match(value)
144
+ .with(null, () => 'null')
145
+ .when(Array.isArray, () => 'array')
146
+ .when((candidate) => candidate instanceof Date, () => 'date')
147
+ .when((candidate) => candidate instanceof Uint8Array, () => 'bytes')
148
+ .when((candidate) => candidate instanceof Map, () => 'map')
149
+ .when((candidate) => candidate instanceof Set, () => 'set')
150
+ .when((candidate) => typeof candidate === 'object', () => 'object')
151
+ .otherwise((candidate) => typeof candidate);
152
+ }
153
+ function safeValueType(value) {
154
+ try {
155
+ return valueType(value);
156
+ }
157
+ catch {
158
+ return typeof value;
159
+ }
160
+ }
161
+ function utf8ByteLength(value) {
162
+ return new TextEncoder().encode(value).byteLength;
163
+ }
164
+ function bytesToBase64(value) {
165
+ let binary = '';
166
+ for (const byte of value)
167
+ binary += String.fromCharCode(byte);
168
+ const encoder = globalThis.btoa;
169
+ if (typeof encoder === 'function')
170
+ return encoder(binary);
171
+ return binary;
172
+ }
@@ -1 +1 @@
1
- export declare const LOUTRE_VERSION = "0.6.0";
1
+ export declare const LOUTRE_VERSION = "0.8.0";
@@ -1,2 +1,2 @@
1
1
  // package manifestとのずれを避けるため、scripts/generate-version.mjsがbuild前に更新する。
2
- export const LOUTRE_VERSION = '0.6.0';
2
+ export const LOUTRE_VERSION = '0.8.0';
@@ -1,4 +1,5 @@
1
1
  import { diagnostic, tokenName, } from '../core/index.js';
2
+ import { match } from 'ts-pattern';
2
3
  export function projectApplicationModel(model) {
3
4
  const diagnostics = [...model.diagnostics];
4
5
  const projectedExecutions = new Map();
@@ -21,46 +22,42 @@ export function projectApplicationModel(model) {
21
22
  });
22
23
  }
23
24
  function projectCoreNode(node) {
24
- switch (node.kind) {
25
- case 'module':
26
- return {
27
- id: node.id,
28
- kind: node.kind,
29
- ...(node.source === undefined ? {} : { source: node.source }),
30
- ...(node.name === undefined ? {} : { name: node.name }),
31
- ...(node.description === undefined
32
- ? {}
33
- : { attributes: { description: node.description } }),
34
- };
35
- case 'provider':
36
- return {
37
- id: node.id,
38
- kind: node.kind,
39
- name: tokenName(node.token),
40
- module: node.moduleId,
41
- ...(node.source === undefined ? {} : { source: node.source }),
42
- attributes: {
43
- providerKind: node.provider.kind,
44
- scope: node.provider.scope,
45
- },
46
- };
47
- case 'lifecycle':
48
- return {
49
- id: node.id,
50
- kind: node.kind,
51
- name: node.phase,
52
- module: node.moduleId,
53
- ...(node.source === undefined ? {} : { source: node.source }),
54
- };
55
- case 'framework':
56
- return {
57
- id: node.id,
58
- kind: node.kind,
59
- name: node.name,
60
- ...(node.source === undefined ? {} : { source: node.source }),
61
- attributes: { frameworkKind: node.frameworkKind },
62
- };
63
- }
25
+ return match(node)
26
+ .with({ kind: 'module' }, (candidate) => ({
27
+ id: candidate.id,
28
+ kind: candidate.kind,
29
+ ...(candidate.source === undefined ? {} : { source: candidate.source }),
30
+ ...(candidate.name === undefined ? {} : { name: candidate.name }),
31
+ ...(candidate.description === undefined
32
+ ? {}
33
+ : { attributes: { description: candidate.description } }),
34
+ }))
35
+ .with({ kind: 'provider' }, (candidate) => ({
36
+ id: candidate.id,
37
+ kind: candidate.kind,
38
+ name: tokenName(candidate.token),
39
+ module: candidate.moduleId,
40
+ ...(candidate.source === undefined ? {} : { source: candidate.source }),
41
+ attributes: {
42
+ providerKind: candidate.provider.kind,
43
+ scope: candidate.provider.scope,
44
+ },
45
+ }))
46
+ .with({ kind: 'lifecycle' }, (candidate) => ({
47
+ id: candidate.id,
48
+ kind: candidate.kind,
49
+ name: candidate.phase,
50
+ module: candidate.moduleId,
51
+ ...(candidate.source === undefined ? {} : { source: candidate.source }),
52
+ }))
53
+ .with({ kind: 'framework' }, (candidate) => ({
54
+ id: candidate.id,
55
+ kind: candidate.kind,
56
+ name: candidate.name,
57
+ ...(candidate.source === undefined ? {} : { source: candidate.source }),
58
+ attributes: { frameworkKind: candidate.frameworkKind },
59
+ }))
60
+ .exhaustive();
64
61
  }
65
62
  function projectExtensionGroup(group, diagnostics) {
66
63
  return group.executions.map((execution) => {
@@ -30,7 +30,7 @@ export interface BasicAuthDefinition<TContribution extends object, TResponse ext
30
30
  }
31
31
  export interface BasicAuthRuntime<TContribution extends object, TResponse extends string, TUnauthorizedBody> {
32
32
  authenticate(credentials: BasicAuthCredentials): TContribution | null | undefined | Promise<TContribution | null | undefined>;
33
- unauthorized(): HttpAuthenticationFailure<TResponse, TUnauthorizedBody>;
33
+ unauthorized(): HttpAuthenticationFailure<TResponse, TUnauthorizedBody> | Response;
34
34
  }
35
35
  export declare function basicAuth<const TContribution extends object, const TResponse extends string, TUnauthorizedBody>(definition: BasicAuthDefinition<TContribution, TResponse, TUnauthorizedBody>): HttpMiddleware<TContribution, HttpMiddlewareContext, AuthenticationShortCircuit<TResponse, TUnauthorizedBody>>;
36
36
  export interface BearerAuthDefinition<TContribution extends object, TResponse extends string, TUnauthorizedBody> {
@@ -40,7 +40,7 @@ export interface BearerAuthDefinition<TContribution extends object, TResponse ex
40
40
  }
41
41
  export interface BearerAuthRuntime<TContribution extends object, TResponse extends string, TUnauthorizedBody> {
42
42
  authenticate(token: string): TContribution | null | undefined | Promise<TContribution | null | undefined>;
43
- unauthorized(): HttpAuthenticationFailure<TResponse, TUnauthorizedBody>;
43
+ unauthorized(): HttpAuthenticationFailure<TResponse, TUnauthorizedBody> | Response;
44
44
  }
45
45
  export declare function bearerAuth<const TContribution extends object, const TResponse extends string, TUnauthorizedBody>(definition: BearerAuthDefinition<TContribution, TResponse, TUnauthorizedBody>): HttpMiddleware<TContribution, HttpMiddlewareContext, AuthenticationShortCircuit<TResponse, TUnauthorizedBody>>;
46
46
  export {};
package/dist/http/auth.js CHANGED
@@ -40,6 +40,15 @@ export function bearerAuth(definition) {
40
40
  });
41
41
  }
42
42
  function authenticationFailure(failure, challenge) {
43
+ if (failure instanceof Response) {
44
+ const headers = new Headers(failure.headers);
45
+ headers.set('www-authenticate', challenge);
46
+ return new Response(failure.body, {
47
+ status: failure.status,
48
+ statusText: failure.statusText,
49
+ headers,
50
+ });
51
+ }
43
52
  return {
44
53
  kind: 'http-result',
45
54
  response: failure.response,
@@ -1,5 +1,6 @@
1
1
  import { SchemaValidationError, validateSchema, } from '../core/index.js';
2
2
  import { parseHttpPath } from './path.js';
3
+ import { match } from 'ts-pattern';
3
4
  export class HttpClientResponseError extends Error {
4
5
  status;
5
6
  method;
@@ -84,11 +85,10 @@ async function decodeResponse(procedure, definition, response) {
84
85
  throw new HttpClientResponseError(response.status, definition.method, definition.path, procedure, `${target} returned a response that does not match its Contract`, lastValidationError ? { cause: lastValidationError } : undefined);
85
86
  }
86
87
  function responseHeadersSchema(headers) {
87
- if (isStandardSchema(headers))
88
- return headers;
89
- if (isResponseHeadersWithDefaults(headers))
90
- return headers.schema;
91
- return undefined;
88
+ return match(headers)
89
+ .when(isStandardSchema, (schema) => schema)
90
+ .when(isResponseHeadersWithDefaults, (definition) => definition.schema)
91
+ .otherwise(() => undefined);
92
92
  }
93
93
  function isStandardSchema(value) {
94
94
  return typeof value === 'object' && value !== null && '~standard' in value;
@@ -1,13 +1,11 @@
1
- import { type ExecutionDefinition, type ExecutionExtension, type ExecutionExtensionDrainContext, type GenericLayer, type RuntimeCapabilityBinding, type SchemaInput, type SchemaOutput, type StandardSchemaV1, type SourceLocation, type Type } from '../core/index.js';
1
+ import { type ExecutionDefinition, type ExecutionContextView, type ExecutionExtension, type ExecutionExtensionDrainContext, type GenericLayer, type RuntimeCapabilityBinding, type SchemaInput, type SchemaOutput, type StandardSchemaV1, type SourceLocation, type Type } from '../core/index.js';
2
2
  import { type HttpPathSegment, type PathParamNames } from './path.js';
3
+ import type { HttpRequestHeadDefinition } from './request-head.js';
3
4
  export interface HttpServerDriver {
4
5
  readonly runtime: string;
5
6
  }
6
7
  export declare const HTTP_SERVER: import("../core/extension.js").RuntimeCapability<HttpServerDriver>;
7
- export interface HttpExecutionRequestDefinition {
8
- readonly params?: Readonly<Record<string, StandardSchemaV1>>;
9
- readonly query?: StandardSchemaV1;
10
- readonly headers?: StandardSchemaV1;
8
+ export interface HttpExecutionRequestDefinition extends HttpRequestHeadDefinition {
11
9
  readonly body?: StandardSchemaV1;
12
10
  }
13
11
  export type HttpHeaderValue = string | readonly string[];
@@ -56,7 +54,8 @@ export interface HttpExecutionRouteDefinition {
56
54
  readonly middlewares?: readonly HttpRouteMiddleware[];
57
55
  readonly interaction?: 'unary' | 'server-stream';
58
56
  }
59
- type AnyHttpMiddleware = GenericLayer<any, any, HttpExecutionResult>;
57
+ type HttpMiddlewareOutcome = HttpExecutionResult | Response;
58
+ type AnyHttpMiddleware = GenericLayer<any, any, HttpMiddlewareOutcome>;
60
59
  type HttpRouteMiddleware = AnyHttpMiddleware | HttpValidationMiddleware;
61
60
  export interface HttpContractBranchDefinition {
62
61
  readonly path?: string;
@@ -67,7 +66,7 @@ export interface HttpContractBranchDefinition {
67
66
  export type HttpContractNodeDefinition = HttpExecutionRouteDefinition | HttpContractBranchDefinition;
68
67
  export type HttpContractRouteTree = Readonly<Record<string, HttpContractNodeDefinition>>;
69
68
  declare const httpMiddlewareShortCircuit: unique symbol;
70
- export type HttpMiddleware<TContribution extends object = object, TContext extends object = HttpMiddlewareContext, TShortCircuit extends HttpExecutionResult = never> = GenericLayer<TContext, TContribution, HttpExecutionResult> & {
69
+ export type HttpMiddleware<TContribution extends object = object, TContext extends object = HttpMiddlewareContext, TShortCircuit extends HttpExecutionResult = never> = GenericLayer<TContext, TContribution, HttpMiddlewareOutcome> & {
71
70
  readonly [httpMiddlewareShortCircuit]?: TShortCircuit;
72
71
  };
73
72
  export interface HttpMiddlewareContext {
@@ -123,10 +122,13 @@ type IsHttpContractTreeInheritanceValid<TTree extends HttpContractRouteTree, TRe
123
122
  type HttpMiddlewareState<TRoute extends HttpExecutionRouteDefinition> = TRoute extends {
124
123
  readonly middlewares: infer TMiddlewares extends readonly HttpRouteMiddleware[];
125
124
  } ? UnionToIntersection<MiddlewareContribution<TMiddlewares[number]>> : {};
125
+ declare const httpContractBrand: unique symbol;
126
126
  export interface HttpContract<TRoutes extends Readonly<Record<string, HttpExecutionRouteDefinition>> = Readonly<Record<string, HttpExecutionRouteDefinition>>> {
127
127
  readonly kind: 'http-contract';
128
128
  readonly routes: TRoutes;
129
+ readonly [httpContractBrand]: true;
129
130
  }
131
+ export declare function isHttpContract(value: unknown): value is HttpContract;
130
132
  type RequestValue<TRequest extends HttpExecutionRequestDefinition | undefined, TPart extends keyof HttpExecutionRequestDefinition, TFallback> = TRequest extends HttpExecutionRequestDefinition ? TRequest[TPart] extends StandardSchemaV1 ? SchemaOutput<TRequest[TPart]> : TFallback : TFallback;
131
133
  type RawHttpQuery = Readonly<Record<string, string | readonly string[] | undefined>>;
132
134
  type RawHttpRequestHeaders = Readonly<Record<string, string | undefined>>;
@@ -198,6 +200,28 @@ export interface HttpImplementationDefinition<TContract extends HttpContract = H
198
200
  readonly contract: TContract;
199
201
  readonly factory: () => HttpHandlers<TContract>;
200
202
  }
203
+ export interface HttpRawRouteDefinition {
204
+ readonly method: string;
205
+ readonly path: string;
206
+ readonly middlewares?: readonly AnyHttpMiddleware[];
207
+ readonly protocol?: string;
208
+ }
209
+ export interface HttpRawExecutionContext<TState = Readonly<Record<string, unknown>>> {
210
+ readonly request: Request;
211
+ readonly signal: AbortSignal;
212
+ readonly state: Readonly<TState>;
213
+ readonly execution: ExecutionContextView;
214
+ }
215
+ type RawMiddlewareState<TMiddlewares extends readonly AnyHttpMiddleware[]> = UnionToIntersection<MiddlewareContribution<TMiddlewares[number]>> & object;
216
+ export interface HttpRawDefinition<TMiddlewares extends readonly AnyHttpMiddleware[] = readonly AnyHttpMiddleware[]> {
217
+ readonly name?: string;
218
+ readonly route: HttpRawRouteDefinition & {
219
+ readonly middlewares?: TMiddlewares;
220
+ };
221
+ readonly factory: () => (context: HttpRawExecutionContext<RawMiddlewareState<TMiddlewares>>) => Response | Promise<Response>;
222
+ }
223
+ export type HttpRawExecutionDefinition = HttpRawDefinition & ExecutionDefinition<typeof httpExecutionExtension>;
224
+ export declare function defineHttpRaw<const TMiddlewares extends readonly AnyHttpMiddleware[] = readonly []>(definition: HttpRawDefinition<TMiddlewares>): HttpRawDefinition<TMiddlewares> & ExecutionDefinition<typeof httpExecutionExtension>;
201
225
  interface CompiledHttpRoute {
202
226
  readonly name: string;
203
227
  readonly method: string;
@@ -207,10 +231,12 @@ interface CompiledHttpRoute {
207
231
  readonly definition: HttpExecutionRouteDefinition;
208
232
  readonly middlewares: readonly AnyHttpMiddleware[];
209
233
  readonly source?: SourceLocation;
234
+ readonly raw?: boolean;
235
+ readonly protocol?: string;
210
236
  }
211
237
  interface CompiledHttpExecution {
212
238
  readonly routes: readonly CompiledHttpRoute[];
213
- readonly factory: () => Record<string, (context: HttpExecutionContext) => HttpExecutionResult | Promise<HttpExecutionResult>>;
239
+ readonly factory: () => Record<string, (context: HttpExecutionContext) => HttpMiddlewareOutcome | Promise<HttpMiddlewareOutcome>>;
214
240
  }
215
241
  export interface HttpExtensionRuntime {
216
242
  fetch(request: Request): Promise<Response>;
@@ -220,7 +246,7 @@ export interface HttpHostApi {
220
246
  fetch(request: Request): Promise<Response>;
221
247
  }
222
248
  declare const httpExecutionExtensionIdentity: unique symbol;
223
- export declare const httpExecutionExtension: ExecutionExtension<HttpImplementationDefinition & ExecutionDefinition, CompiledHttpExecution, 'http', HttpHostApi, HttpExtensionRuntime> & {
249
+ export declare const httpExecutionExtension: ExecutionExtension<(HttpImplementationDefinition | HttpRawDefinition) & ExecutionDefinition, CompiledHttpExecution, 'http', HttpHostApi, HttpExtensionRuntime> & {
224
250
  readonly [httpExecutionExtensionIdentity]: true;
225
251
  };
226
252
  export type HttpExecutionDefinition<TContract extends HttpContract = HttpContract> = HttpImplementationDefinition<TContract> & ExecutionDefinition<typeof httpExecutionExtension>;
@@ -328,6 +354,7 @@ export declare const validate: Readonly<{
328
354
  }>;
329
355
  }>;
330
356
  export declare const executionHttp: Readonly<{
357
+ raw: typeof defineHttpRaw;
331
358
  contract: typeof defineHttpContract;
332
359
  implementation: typeof defineHttpImplementation;
333
360
  middleware: typeof defineHttpMiddleware;
@@ -338,7 +365,7 @@ export declare const executionHttp: Readonly<{
338
365
  }>;
339
366
  }>;
340
367
  error: typeof httpError;
341
- extension: ExecutionExtension<HttpImplementationDefinition<HttpContract<Readonly<Record<string, HttpExecutionRouteDefinition>>>> & ExecutionDefinition<import("../core/extension.js").AnyExecutionExtension>, CompiledHttpExecution, "http", HttpHostApi, HttpExtensionRuntime> & {
368
+ extension: ExecutionExtension<(HttpImplementationDefinition<HttpContract<Readonly<Record<string, HttpExecutionRouteDefinition>>>> | HttpRawDefinition<readonly AnyHttpMiddleware[]>) & ExecutionDefinition<import("../core/extension.js").AnyExecutionExtension>, CompiledHttpExecution, "http", HttpHostApi, HttpExtensionRuntime> & {
342
369
  readonly [httpExecutionExtensionIdentity]: true;
343
370
  };
344
371
  serverCapability: import("../core/extension.js").RuntimeCapability<HttpServerDriver>;