@znight/http 0.3.0 → 0.4.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.
- package/README.md +44 -2
- package/dist/{adapter-J0UXFnNM.d.mts → adapter-DmhQGqAR.d.mts} +18 -5
- package/dist/compiler.d.mts +23 -1
- package/dist/compiler.mjs +126 -9
- package/dist/compiler.mjs.map +1 -1
- package/dist/express.d.mts +1 -1
- package/dist/fastify.d.mts +1 -1
- package/dist/hono.d.mts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +26 -7
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/package.json +4 -4
- package/src/compiler/analyze.ts +43 -0
- package/src/compiler/generate.ts +122 -13
- package/src/compiler/model.ts +21 -0
- package/src/context.ts +7 -0
- package/src/metadata.ts +13 -4
- package/src/pipeline.ts +12 -7
- package/src/plugin.ts +33 -0
package/dist/express.d.mts
CHANGED
package/dist/fastify.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as HttpAdapter } from "./adapter-
|
|
1
|
+
import { s as HttpAdapter } from "./adapter-DmhQGqAR.mjs";
|
|
2
2
|
import { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
3
3
|
/** Options of {@link fastifyAdapter}. */
|
|
4
4
|
export interface FastifyAdapterOptions {
|
package/dist/hono.d.mts
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as PayloadTooLargeException, A as UploadedFileOptions, B as BadRequestException, C as HttpUploadDefinition, Ct as CookieOptions, D as RequestAbortedError, Dt as parseSetCookie, E as RequestAbortKind, Et as parseCookieHeader, F as formatByteSize, G as HeaderValue, H as ForbiddenException, I as parseByteSize, J as HttpExceptionOptions, K as HttpErrorBody, L as QueryRecord, M as Uploads, N as uploads, O as RequestId, Ot as serializeClearCookie, P as ByteSize, Q as NotImplementedException, R as parseQuery, S as HttpSseDefinition, St as CookieDefaults, T as HttpRouteInfo, Tt as SetCookieInfo, U as GatewayTimeoutException, V as ConflictException, W as GoneException, X as MethodNotAllowedException, Y as InternalServerErrorException, Z as NotFoundException, _ as HttpMethod, _t as StandardSchemaV1Result, a as AdapterRoute, at as ValidationException, b as HttpRouteDefinition, bt as isStandardSchema, c as HttpServerAddress, ct as toIssueDetail, d as InjectStreamOptions, dt as StandardSchemaV1, et as ServiceUnavailableException, f as InjectStreamRequest, ft as StandardSchemaV1FailureResult, g as HttpMetadata, gt as StandardSchemaV1Props, h as HttpControllerDefinition, ht as StandardSchemaV1PathSegment, i as AdapterRequest, it as UnsupportedMediaTypeException, j as UploadedFilesOptions, k as UploadLimits, kt as serializeCookie, l as InjectRequest, lt as InferSchemaInput, m as ReplyBody, mt as StandardSchemaV1Options, n as AdapterHandler, nt as UnauthorizedException, o as FallbackHandler, ot as ValidationIssueDetail, p as InjectStreamResponse, pt as StandardSchemaV1Issue, q as HttpException, r as AdapterReply, rt as UnprocessableEntityException, s as HttpAdapter, st as isHttpException, t as AdapterCloseOptions, tt as TooManyRequestsException, u as InjectResponse, ut as InferSchemaOutput, v as HttpParamDefinition, vt as StandardSchemaV1SuccessResult, w as HttpContext, wt as ResponseCookie, x as HttpRouteGroupDefinition, xt as ClearCookieOptions, y as HttpParamSource, yt as StandardSchemaV1Types, z as BadGatewayException } from "./adapter-
|
|
1
|
+
import { $ as PayloadTooLargeException, A as UploadedFileOptions, B as BadRequestException, C as HttpUploadDefinition, Ct as CookieOptions, D as RequestAbortedError, Dt as parseSetCookie, E as RequestAbortKind, Et as parseCookieHeader, F as formatByteSize, G as HeaderValue, H as ForbiddenException, I as parseByteSize, J as HttpExceptionOptions, K as HttpErrorBody, L as QueryRecord, M as Uploads, N as uploads, O as RequestId, Ot as serializeClearCookie, P as ByteSize, Q as NotImplementedException, R as parseQuery, S as HttpSseDefinition, St as CookieDefaults, T as HttpRouteInfo, Tt as SetCookieInfo, U as GatewayTimeoutException, V as ConflictException, W as GoneException, X as MethodNotAllowedException, Y as InternalServerErrorException, Z as NotFoundException, _ as HttpMethod, _t as StandardSchemaV1Result, a as AdapterRoute, at as ValidationException, b as HttpRouteDefinition, bt as isStandardSchema, c as HttpServerAddress, ct as toIssueDetail, d as InjectStreamOptions, dt as StandardSchemaV1, et as ServiceUnavailableException, f as InjectStreamRequest, ft as StandardSchemaV1FailureResult, g as HttpMetadata, gt as StandardSchemaV1Props, h as HttpControllerDefinition, ht as StandardSchemaV1PathSegment, i as AdapterRequest, it as UnsupportedMediaTypeException, j as UploadedFilesOptions, k as UploadLimits, kt as serializeCookie, l as InjectRequest, lt as InferSchemaInput, m as ReplyBody, mt as StandardSchemaV1Options, n as AdapterHandler, nt as UnauthorizedException, o as FallbackHandler, ot as ValidationIssueDetail, p as InjectStreamResponse, pt as StandardSchemaV1Issue, q as HttpException, r as AdapterReply, rt as UnprocessableEntityException, s as HttpAdapter, st as isHttpException, t as AdapterCloseOptions, tt as TooManyRequestsException, u as InjectResponse, ut as InferSchemaOutput, v as HttpParamDefinition, vt as StandardSchemaV1SuccessResult, w as HttpContext, wt as ResponseCookie, x as HttpRouteGroupDefinition, xt as ClearCookieOptions, y as HttpParamSource, yt as StandardSchemaV1Types, z as BadGatewayException } from "./adapter-DmhQGqAR.mjs";
|
|
2
2
|
import { NodeAdapter, NodeAdapterOptions, nodeAdapter } from "./node.mjs";
|
|
3
3
|
import { ClassMarker, Container, MethodMarker, ParameterMarker, Plugin, PluginContext, PluginOptions, ProviderKey, Scope, TypedToken } from "@znight/core";
|
|
4
4
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -3967,7 +3967,7 @@ var Pipeline = class {
|
|
|
3967
3967
|
let result;
|
|
3968
3968
|
let reply;
|
|
3969
3969
|
try {
|
|
3970
|
-
result = plan.
|
|
3970
|
+
result = plan.invoke(this.#resolve(plan.controller), ctx);
|
|
3971
3971
|
if (isThenable(result)) return this.#fastLater(route, request, ctx, result, startTime);
|
|
3972
3972
|
reply = this.#fastReply(route, ctx, result);
|
|
3973
3973
|
} catch (error) {
|
|
@@ -4003,7 +4003,7 @@ var Pipeline = class {
|
|
|
4003
4003
|
if (result === NO_RESULT) {
|
|
4004
4004
|
const controller = this.#resolve(plan.controller);
|
|
4005
4005
|
await ctx.parseBody();
|
|
4006
|
-
result = plan.
|
|
4006
|
+
result = plan.invoke(controller, ctx);
|
|
4007
4007
|
}
|
|
4008
4008
|
if (isThenable(result)) result = await result;
|
|
4009
4009
|
reply = this.#fastReply(route, ctx, result);
|
|
@@ -4091,7 +4091,7 @@ var Pipeline = class {
|
|
|
4091
4091
|
if (plan.parseBody) return this.#fastOperationLater(x, route, NO_RESULT);
|
|
4092
4092
|
let result;
|
|
4093
4093
|
try {
|
|
4094
|
-
result = plan.
|
|
4094
|
+
result = plan.invoke(this.#resolve(plan.controller), ctx);
|
|
4095
4095
|
} catch (error) {
|
|
4096
4096
|
return this.#fastChecked(x, this.#failed(error, ctx, x.event));
|
|
4097
4097
|
}
|
|
@@ -4107,7 +4107,7 @@ var Pipeline = class {
|
|
|
4107
4107
|
if (result === NO_RESULT) {
|
|
4108
4108
|
const controller = this.#resolve(plan.controller);
|
|
4109
4109
|
await ctx.parseBody();
|
|
4110
|
-
result = plan.
|
|
4110
|
+
result = plan.invoke(controller, ctx);
|
|
4111
4111
|
}
|
|
4112
4112
|
if (isThenable(result)) result = await result;
|
|
4113
4113
|
} catch (error) {
|
|
@@ -4634,12 +4634,11 @@ var Pipeline = class {
|
|
|
4634
4634
|
const controller = this.#resolve(plan.controller);
|
|
4635
4635
|
for (const guard of plan.guards) if (await this.#resolve(guard).canActivate(ctx) !== true) throw new ForbiddenException("Forbidden resource");
|
|
4636
4636
|
if (plan.parseBody) await ctx.parseBody();
|
|
4637
|
-
const definition = plan.definition;
|
|
4638
4637
|
const interceptors = plan.interceptors;
|
|
4639
|
-
if (interceptors.length === 0) result =
|
|
4638
|
+
if (interceptors.length === 0) result = plan.invoke(controller, ctx);
|
|
4640
4639
|
else {
|
|
4641
4640
|
const chain = async (index) => {
|
|
4642
|
-
if (index === interceptors.length) return await
|
|
4641
|
+
if (index === interceptors.length) return await plan.invoke(controller, ctx);
|
|
4643
4642
|
return await this.#resolve(interceptors[index]).intercept(ctx, () => chain(index + 1));
|
|
4644
4643
|
};
|
|
4645
4644
|
result = chain(0);
|
|
@@ -6129,6 +6128,7 @@ function buildRegistrations(ctx, options, raw, pluginRoutes) {
|
|
|
6129
6128
|
const body = bodyPlan(route, options.bodyLimit, options.uploads);
|
|
6130
6129
|
const parseBody = body.upload || route.params.some((param) => param.source === "body");
|
|
6131
6130
|
const chain = guards.map((guard) => guard.resolvable);
|
|
6131
|
+
const invoke = routeInvoke(container, route, lookup, where);
|
|
6132
6132
|
let meta;
|
|
6133
6133
|
const effective = () => {
|
|
6134
6134
|
meta ??= effectiveMeta(controllerMeta, routeMeta, groupOf);
|
|
@@ -6140,6 +6140,7 @@ function buildRegistrations(ctx, options, raw, pluginRoutes) {
|
|
|
6140
6140
|
path,
|
|
6141
6141
|
plan: (method) => ({
|
|
6142
6142
|
definition: route,
|
|
6143
|
+
invoke,
|
|
6143
6144
|
path,
|
|
6144
6145
|
info: Object.freeze({
|
|
6145
6146
|
method,
|
|
@@ -6193,6 +6194,7 @@ function buildRegistrations(ctx, options, raw, pluginRoutes) {
|
|
|
6193
6194
|
path,
|
|
6194
6195
|
plan: (method) => ({
|
|
6195
6196
|
definition,
|
|
6197
|
+
invoke: definition.invoke,
|
|
6196
6198
|
path,
|
|
6197
6199
|
info: Object.freeze({
|
|
6198
6200
|
method,
|
|
@@ -6347,6 +6349,7 @@ function assertRoute(route, where) {
|
|
|
6347
6349
|
if (route.bodyLimit !== void 0 && !isSize(route.bodyLimit)) throw new ZnightError(ErrorCode.InvalidRoute, `Invalid route ${where}: bodyLimit must be a number of bytes (or Infinity), got ${describeValue(route.bodyLimit)}`);
|
|
6348
6350
|
if (route.uploads !== void 0) assertUploads(route, where);
|
|
6349
6351
|
if (route.sse !== void 0) assertSse(route, where);
|
|
6352
|
+
if (route.paramResolvers !== void 0 && !Array.isArray(route.paramResolvers)) throw new ZnightError(ErrorCode.InvalidRoute, `Invalid route ${where}: paramResolvers must be an array of tokens`);
|
|
6350
6353
|
}
|
|
6351
6354
|
function assertSse(route, where) {
|
|
6352
6355
|
const sse = route.sse;
|
|
@@ -6386,6 +6389,22 @@ function describeValue(value) {
|
|
|
6386
6389
|
}
|
|
6387
6390
|
}
|
|
6388
6391
|
/**
|
|
6392
|
+
* The `invoke` of a route plan: the generated `invoke` itself, unless the route has parameter
|
|
6393
|
+
* resolvers (RFC 0010), whose instances are passed as its third argument: one frozen array resolved
|
|
6394
|
+
* at bootstrap when they are all singletons, otherwise an array resolved in the request scope.
|
|
6395
|
+
*/
|
|
6396
|
+
function routeInvoke(container, route, lookup, where) {
|
|
6397
|
+
const invoke = route.invoke;
|
|
6398
|
+
const tokens = route.paramResolvers;
|
|
6399
|
+
if (tokens === void 0 || tokens.length === 0) return invoke;
|
|
6400
|
+
const resolvers = tokens.map((token) => lookup(token, `parameter resolver of ${where}`));
|
|
6401
|
+
if (resolvers.every((resolver) => "instance" in resolver)) {
|
|
6402
|
+
const instances = Object.freeze(resolvers.map((resolver) => resolver.instance));
|
|
6403
|
+
return (controller, ctx) => invoke(controller, ctx, instances);
|
|
6404
|
+
}
|
|
6405
|
+
return (controller, ctx) => invoke(controller, ctx, resolvers.map((resolver) => "instance" in resolver ? resolver.instance : container.get(resolver.token)));
|
|
6406
|
+
}
|
|
6407
|
+
/**
|
|
6389
6408
|
* Singletons (and registered values) are resolved once at bootstrap; request-scoped and transient
|
|
6390
6409
|
* providers on every request.
|
|
6391
6410
|
*/
|