@owlmeans/server-api 0.1.18-rc.3 → 0.1.18-rc.30
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 +179 -47
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-api/SKILL.md +45 -22
- package/build/errors.d.ts +12 -0
- package/build/errors.d.ts.map +1 -1
- package/build/errors.js +16 -0
- package/build/errors.js.map +1 -1
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +10 -1
- package/build/helper.js.map +1 -1
- package/build/hold.d.ts +52 -0
- package/build/hold.d.ts.map +1 -0
- package/build/hold.js +56 -0
- package/build/hold.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/protocol.d.ts +45 -0
- package/build/protocol.d.ts.map +1 -0
- package/build/protocol.js +86 -0
- package/build/protocol.js.map +1 -0
- package/build/server.d.ts.map +1 -1
- package/build/server.js +7 -12
- package/build/server.js.map +1 -1
- package/build/types.d.ts +1 -2
- package/build/types.d.ts.map +1 -1
- package/build/utils/error.d.ts +13 -0
- package/build/utils/error.d.ts.map +1 -1
- package/build/utils/error.js +21 -4
- package/build/utils/error.js.map +1 -1
- package/build/utils/guards.d.ts.map +1 -1
- package/build/utils/guards.js +11 -15
- package/build/utils/guards.js.map +1 -1
- package/build/utils/payload.d.ts.map +1 -1
- package/build/utils/payload.js +3 -0
- package/build/utils/payload.js.map +1 -1
- package/build/utils/server.d.ts.map +1 -1
- package/build/utils/server.js +4 -1
- package/build/utils/server.js.map +1 -1
- package/package.json +13 -11
- package/src/errors.ts +18 -0
- package/src/helper.ts +10 -1
- package/src/hold.ts +84 -0
- package/src/index.ts +2 -0
- package/src/protocol.ts +185 -0
- package/src/server.ts +34 -43
- package/src/types.ts +1 -3
- package/src/utils/error.ts +20 -3
- package/src/utils/guards.ts +10 -17
- package/src/utils/payload.ts +3 -0
- package/src/utils/server.ts +4 -1
- package/tests/handlers.spec.ts +83 -0
- package/tests/tsconfig.json +12 -0
- package/tsconfig.json +1 -0
- package/build/.gitkeep +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context';
|
|
2
|
+
import type { BodyOf, EntrypointProtocolDeclaration, HandlerRequest, OpenValue, ParamsOf, RequestOf, ResponseOf } from '@owlmeans/entrypoint';
|
|
3
|
+
import type { BoundEntrypointHandler } from '@owlmeans/server-entrypoint';
|
|
4
|
+
/**
|
|
5
|
+
* True for a response the declaration left with no compile-time contract: `typed<any>()` (an
|
|
6
|
+
* `[any] extends [X]` conditional does not produce `any`'s usual both-branches union once the
|
|
7
|
+
* checked type is wrapped in a tuple, so it resolves to a single branch like any other type) and
|
|
8
|
+
* a response inferred as bare `typed()` with nothing to infer from, which resolves to `undefined`
|
|
9
|
+
* with no shape to validate a handler's return against — the same signal a zero-argument
|
|
10
|
+
* `contract()` produces for a genuinely response-less route. Neither means "this handler must
|
|
11
|
+
* return void": it means the declaration did not constrain the response, so the handler is free to
|
|
12
|
+
* return whatever its route actually sends.
|
|
13
|
+
*/
|
|
14
|
+
type IsUntypedResponse<T> = 0 extends (1 & T) ? true : [T] extends [undefined] ? true : false;
|
|
15
|
+
/**
|
|
16
|
+
* The type a bound handler is allowed to return for a given protocol response.
|
|
17
|
+
*
|
|
18
|
+
* A concretely typed or schema-backed `Response` is returned unchanged — the handler must produce
|
|
19
|
+
* exactly that shape. An untyped one (see `IsUntypedResponse` above) relaxes to `any`: the
|
|
20
|
+
* declaration made no promise about the response, so nothing here should force a handler bound to
|
|
21
|
+
* it into returning `void`.
|
|
22
|
+
*/
|
|
23
|
+
type HandlerResponse<Response> = IsUntypedResponse<Response> extends true ? any : Response;
|
|
24
|
+
type MaybePromise<Value> = Value | Promise<Value>;
|
|
25
|
+
type BodyProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
|
|
26
|
+
body: OpenValue;
|
|
27
|
+
} ? Protocol : never;
|
|
28
|
+
type ParamsProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
|
|
29
|
+
params: object;
|
|
30
|
+
} ? Protocol : never;
|
|
31
|
+
/**
|
|
32
|
+
* Make server handlers that infer request sections and response values from their protocol.
|
|
33
|
+
* The protocol is passed once; application callbacks never name request or reply generics.
|
|
34
|
+
*/
|
|
35
|
+
export declare const handlers: <Context extends BasicContext<BasicConfig>>() => {
|
|
36
|
+
body: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: Protocol extends BodyProtocol<Protocol> ? (payload: BodyOf<Protocol>, context: Context, request: HandlerRequest<RequestOf<Protocol>>) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>> : never) => BoundEntrypointHandler<Protocol>;
|
|
37
|
+
params: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: Protocol extends ParamsProtocol<Protocol> ? (payload: ParamsOf<Protocol>, context: Context, request: HandlerRequest<RequestOf<Protocol>>) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>> : never) => BoundEntrypointHandler<Protocol>;
|
|
38
|
+
request: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: (request: HandlerRequest<RequestOf<Protocol>>, context: Context) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>>) => BoundEntrypointHandler<Protocol>;
|
|
39
|
+
};
|
|
40
|
+
/** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
|
|
41
|
+
export declare const uploadedFile: (request: HandlerRequest<{
|
|
42
|
+
body: object;
|
|
43
|
+
}>) => Promise<import('@fastify/multipart').MultipartFile | undefined>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,KAAK,EACV,MAAM,EAAE,6BAA6B,EAAE,cAAc,EAAe,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAC/G,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAGzE;;;;;;;;;GASG;AACH,KAAK,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK,CAAA;AAE7F;;;;;;;GAOG;AACH,KAAK,eAAe,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,SAAS,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAA;AAC1F,KAAK,YAAY,CAAC,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;AACjD,KAAK,YAAY,CAAC,QAAQ,SAAS,6BAA6B,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAC/G,QAAQ,GAAG,KAAK,CAAA;AACpB,KAAK,cAAc,CAAC,QAAQ,SAAS,6BAA6B,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAChH,QAAQ,GAAG,KAAK,CAAA;AAqGpB;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,SAAS,YAAY,CAAC,WAAW,CAAC;IAChE,IAAI,GAAG,QAAQ,SAAS,6BAA6B,YACzC,QAAQ,WACT,QAAQ,SAAS,YAAY,CAAC,QAAQ,CAAC,GAAG,CAC/C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,EACzB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,KACzC,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GACtD,KAAK,KACR,sBAAsB,CAAC,QAAQ,CAAC;IAKnC,MAAM,GAAG,QAAQ,SAAS,6BAA6B,YAC3C,QAAQ,WACT,QAAQ,SAAS,cAAc,CAAC,QAAQ,CAAC,GAAG,CACjD,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,KACzC,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,GACtD,KAAK,KACR,sBAAsB,CAAC,QAAQ,CAAC;IAKnC,OAAO,GAAG,QAAQ,SAAS,6BAA6B,YAC5C,QAAQ,WACT,CACP,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAC5C,OAAO,EAAE,OAAO,KACb,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,KACvD,sBAAsB,CAAC,QAAQ,CAAC;CACnC,CAAA;AAEF,sGAAsG;AACtG,eAAO,MAAM,YAAY,YACd,cAAc,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,KACxC,OAAO,CAAC,OAAO,oBAAoB,EAAE,aAAa,GAAG,SAAS,CAKhE,CAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { assertContext } from '@owlmeans/context';
|
|
2
|
+
import { EntrypointOutcome } from '@owlmeans/entrypoint';
|
|
3
|
+
import { HandlerMisconfiguredError } from './errors.js';
|
|
4
|
+
const contextFor = (request, fallback) => {
|
|
5
|
+
const original = request.original;
|
|
6
|
+
if (original != null && typeof original === 'object' && '_ctx' in original) {
|
|
7
|
+
return original._ctx ?? fallback;
|
|
8
|
+
}
|
|
9
|
+
return fallback;
|
|
10
|
+
};
|
|
11
|
+
const bind = (protocol, execute) => ({
|
|
12
|
+
protocol,
|
|
13
|
+
bind: ref => async (request, response) => {
|
|
14
|
+
const fallback = assertContext(ref.ref?.ctx, protocol.alias);
|
|
15
|
+
try {
|
|
16
|
+
const typedRequest = request;
|
|
17
|
+
const value = await execute(typedRequest, contextFor(request, fallback));
|
|
18
|
+
response.resolve(value, EntrypointOutcome.Ok);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
response.reject(error);
|
|
22
|
+
}
|
|
23
|
+
return response.value;
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* `value` is shaped like a `BoundEntrypointHandler` — never a plain function, which also carries
|
|
28
|
+
* its own `.bind` and would otherwise pass a `typeof value.bind === 'function'` check alone.
|
|
29
|
+
*/
|
|
30
|
+
const isBoundHandler = (value) => typeof value === 'object' && value != null
|
|
31
|
+
&& typeof value.bind === 'function'
|
|
32
|
+
&& value.protocol != null;
|
|
33
|
+
const warnedAliases = new Set();
|
|
34
|
+
/**
|
|
35
|
+
* What `body`/`params`/`request` do with something that is not the plain callback they declare —
|
|
36
|
+
* the shape a handler module wraps its own export in when it is bound TWICE. `null` means the
|
|
37
|
+
* second argument really is a callback and the caller should wrap it as usual.
|
|
38
|
+
*
|
|
39
|
+
* A handler bound to THIS protocol is returned unchanged, with a one-time warning: the module
|
|
40
|
+
* already produced a working `BoundEntrypointHandler`, and re-wrapping it here would only wrap it
|
|
41
|
+
* again — returning it as-is is what makes `bind(protocol, api.body(protocol, alreadyBound))`
|
|
42
|
+
* behave exactly like `bind(protocol, alreadyBound)`, which is what a wrap-once file looks like at
|
|
43
|
+
* this call site. Anything else — a handler bound to a DIFFERENT protocol, or a value that is
|
|
44
|
+
* neither a function nor a bound handler at all — answers every request on this route with
|
|
45
|
+
* {@link HandlerMisconfiguredError} instead of throwing `TypeError: handler is not a function`
|
|
46
|
+
* out of the request pipeline's own `try`, where the type name and the alias it happened on are
|
|
47
|
+
* both lost.
|
|
48
|
+
*/
|
|
49
|
+
const toleratedHandler = (protocol, handler) => {
|
|
50
|
+
if (typeof handler === 'function')
|
|
51
|
+
return null;
|
|
52
|
+
if (isBoundHandler(handler)) {
|
|
53
|
+
if (handler.protocol.alias === protocol.alias) {
|
|
54
|
+
if (!warnedAliases.has(protocol.alias)) {
|
|
55
|
+
warnedAliases.add(protocol.alias);
|
|
56
|
+
console.warn(`[server-api] ${protocol.alias}: handler is already bound — pass it to bind() directly; `
|
|
57
|
+
+ 'wrapping it again here is a type error (TS2345 "BoundEntrypointHandler<…> is not '
|
|
58
|
+
+ 'assignable"), tolerated at runtime for a project generated before the wrap-once rule.');
|
|
59
|
+
}
|
|
60
|
+
return handler;
|
|
61
|
+
}
|
|
62
|
+
return bind(protocol, () => {
|
|
63
|
+
throw new HandlerMisconfiguredError(`${protocol.alias}: handler is bound to a different protocol ('${handler.protocol.alias}')`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return bind(protocol, () => {
|
|
67
|
+
throw new HandlerMisconfiguredError(`${protocol.alias}: handler is not a function`);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Make server handlers that infer request sections and response values from their protocol.
|
|
72
|
+
* The protocol is passed once; application callbacks never name request or reply generics.
|
|
73
|
+
*/
|
|
74
|
+
export const handlers = () => ({
|
|
75
|
+
body: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, (request, context) => handler(request.body, context, request)),
|
|
76
|
+
params: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, (request, context) => handler(request.params, context, request)),
|
|
77
|
+
request: (protocol, handler) => toleratedHandler(protocol, handler) ?? bind(protocol, handler),
|
|
78
|
+
});
|
|
79
|
+
/** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
|
|
80
|
+
export const uploadedFile = async (request) => {
|
|
81
|
+
const original = request.original;
|
|
82
|
+
if (original == null || typeof original !== 'object' || !('file' in original))
|
|
83
|
+
return undefined;
|
|
84
|
+
return original.file();
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAMxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAiCvD,MAAM,UAAU,GAAG,CACjB,OAAwB,EACxB,QAAiB,EACR,EAAE;IACX,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC3E,OAAQ,QAAoC,CAAC,IAAI,IAAI,QAAQ,CAAA;IAC/D,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CACX,QAAkB,EAClB,OAAgI,EAC9F,EAAE,CAAC,CAAC;IACtC,QAAQ;IACR,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACvC,MAAM,QAAQ,GAAG,aAAa,CAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;QAElF,IAAI,CAAC;YACH,MAAM,YAAY,GAAI,OAA8E,CAAA;YACpG,MAAM,KAAK,GAAG,MAAM,OAAO,CACzB,YAAY,EACZ,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAC9B,CAAA;YACD,QAAQ,CAAC,OAAO,CAAC,KAA6B,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAA;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,MAAM,CAAC,KAAc,CAAC,CAAA;QACjC,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAA;IACvB,CAAC;CACF,CAAC,CAAA;AAKF;;;GAGG;AACH,MAAM,cAAc,GAAG,CAAC,KAAc,EAA4B,EAAE,CAClE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,IAAI;OACvC,OAAQ,KAA4B,CAAC,IAAI,KAAK,UAAU;OACvD,KAAgC,CAAC,QAAQ,IAAI,IAAI,CAAA;AAEvD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,gBAAgB,GAAG,CACvB,QAAkB,EAAE,OAAgB,EACK,EAAE;IAC3C,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,IAAI,CAAA;IAE9C,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACjC,OAAO,CAAC,IAAI,CACV,gBAAgB,QAAQ,CAAC,KAAK,2DAA2D;sBACvF,mFAAmF;sBACnF,uFAAuF,CAC1F,CAAA;YACH,CAAC;YAED,OAAO,OAAsD,CAAA;QAC/D,CAAC;QAED,OAAO,IAAI,CAAsC,QAAQ,EAAE,GAAG,EAAE;YAC9D,MAAM,IAAI,yBAAyB,CACjC,GAAG,QAAQ,CAAC,KAAK,gDAAgD,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAC5F,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,IAAI,CAAsC,QAAQ,EAAE,GAAG,EAAE;QAC9D,MAAM,IAAI,yBAAyB,CAAC,GAAG,QAAQ,CAAC,KAAK,6BAA6B,CAAC,CAAA;IACrF,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA8C,EAAE,CAAC,CAAC;IACxE,IAAI,EAAE,CACJ,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAClI,OAEwD,CAAC,OAAO,CAAC,IAAwB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhH,MAAM,EAAE,CACN,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAClI,OAEwD,CAAC,OAAO,CAAC,MAA4B,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEpH,OAAO,EAAE,CACP,QAAkB,EAClB,OAGwD,EACtB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAoB,QAAQ,EAAE,OAAO,CAAC;CACzH,CAAC,CAAA;AAEF,sGAAsG;AACtG,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,OAAyC,EACwB,EAAE;IACnE,MAAM,QAAQ,GAAI,OAA2B,CAAC,QAAQ,CAAA;IACtD,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAE/F,OAAQ,QAA6C,CAAC,IAAI,EAAE,CAAA;AAC9D,CAAC,CAAA"}
|
package/build/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiC5D,KAAK,MAAM,GAAG,YAAY,CAAA;AAK1B,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAiC5D,KAAK,MAAM,GAAG,YAAY,CAAA;AAK1B,eAAO,MAAM,eAAe,UAAW,MAAM,KAAG,SAkJ/C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OACrE,CAAC,UAAS,MAAM,KACpB,CAAC,GAAG,eAWN,CAAA"}
|
package/build/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertContext, createService } from '@owlmeans/context';
|
|
2
2
|
import { canServeModule, executeResponse, provideRequest } from './utils/index.js';
|
|
3
3
|
import { DEFAULT_ALIAS, CLOSED_HOST, PORT, OPENED_HOST } from './consts.js';
|
|
4
4
|
import { RouteMethod } from '@owlmeans/route';
|
|
@@ -42,7 +42,6 @@ export const createApiServer = (alias) => {
|
|
|
42
42
|
},
|
|
43
43
|
}*/
|
|
44
44
|
}),
|
|
45
|
-
layers: [Layer.System],
|
|
46
45
|
listen: async () => {
|
|
47
46
|
const context = _assertContext(service.ctx);
|
|
48
47
|
const config = context.cfg.services[context.cfg.service];
|
|
@@ -107,10 +106,8 @@ export const createApiServer = (alias) => {
|
|
|
107
106
|
if (responded || reply.sent) {
|
|
108
107
|
return context;
|
|
109
108
|
}
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
// Actually intermediate module can be created without handler by elevate function
|
|
113
|
-
if (module.route.match(request) && module.handle != null) {
|
|
109
|
+
// An intermediate route can be created without a handler by the binding layer.
|
|
110
|
+
if (module.route.match(request, module.mount()) && module.handle != null) {
|
|
114
111
|
const response = provideResponse(reply);
|
|
115
112
|
const currentRequest = provideRequest(module.alias, request, true);
|
|
116
113
|
currentRequest.original._ctx = context;
|
|
@@ -123,17 +120,15 @@ export const createApiServer = (alias) => {
|
|
|
123
120
|
return context;
|
|
124
121
|
}, Promise.resolve(context));
|
|
125
122
|
});
|
|
126
|
-
|
|
123
|
+
context.entrypoints()
|
|
127
124
|
.filter(module => canServeModule(context, module) && !module.route.isIntermediate())
|
|
128
|
-
.
|
|
129
|
-
// await module.route.resolve(context as any)
|
|
130
|
-
await module.resolve();
|
|
125
|
+
.forEach(module => {
|
|
131
126
|
const method = module.route.route.method ?? RouteMethod.GET;
|
|
132
127
|
if (module.handle == null) {
|
|
133
128
|
return;
|
|
134
129
|
}
|
|
135
130
|
server.route({
|
|
136
|
-
url: module.
|
|
131
|
+
url: module.mount(), method,
|
|
137
132
|
schema: {
|
|
138
133
|
consumes: [
|
|
139
134
|
'application/json',
|
|
@@ -154,7 +149,7 @@ export const createApiServer = (alias) => {
|
|
|
154
149
|
},
|
|
155
150
|
handler: createServerHandler(module, location)
|
|
156
151
|
});
|
|
157
|
-
})
|
|
152
|
+
});
|
|
158
153
|
service.initialized = true;
|
|
159
154
|
});
|
|
160
155
|
return service;
|
package/build/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,IAAI,MAAM,eAAe,CAAA;AAChC,OAAO,OAAO,MAAM,kBAAkB,CAAA;AACtC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,MAAM,MAAM,iBAAiB,CAAA;AACpC,OAAO,SAAS,MAAM,oBAAoB,CAAA;AAE1C,OAAO,aAAa,MAAM,aAAa,CAAA;AACvC,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,SAAS,MAAM,YAAY,CAAA;AAGlC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC;IAClB,gBAAgB,EAAE,IAAI;IACtB,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,KAAK;CACd,CAAC,CAAA;AACF,aAAa,CAAC,GAAG,CAAC,CAAA;AAClB,SAAS,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;AAKrC,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE,CAAA;AAElC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAa,EAAE;IAC1D,MAAM,QAAQ,GAAG,WAAW,KAAK,EAAE,CAAA;IACnC,MAAM,cAAc,GAAG,CAAC,OAA4B,EAAW,EAAE,CAAC,aAAa,CAAkB,OAAO,EAAE,QAAQ,CAAC,CAAA;IAEnH,MAAM,OAAO,GAAG,aAAa,CAAY,KAAK,EAAE;QAC9C,MAAM,EAAE,OAAO,CAAC;YACd,MAAM,EAAE,IAAI;YACZ,SAAS;YACT;;;;;;;;;cASE;SACH,CAAC;QAEF,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAc,CAAC,CAAA;YAEtD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAExD,MAAM,IAAI,GAAG,MAAM,EAAE,YAAY,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA;YACzD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;YAC/D,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3C,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,yBAAyB,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YAEzF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;gBACzB,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;oBAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACjB,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE;QACvB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACpC,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;YAC5B,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAA;QACvD,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAc,CAAC,CAAA;QAEtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC7B,oFAAoF;QACpF,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7D,4DAA4D;QAC5D,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC1B,MAAM,EAAE,GAAG;YACX,wEAAwE;YACxE,0EAA0E;YAC1E,mEAAmE;YACnE,wEAAwE;YACxE,6DAA6D;YAC7D,wEAAwE;YACxE,yEAAyE;YACzE,8EAA8E;YAC9E,OAAO,EAAE;gBACP,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACjE,MAAM,EAAE,SAAS;aAClB;YACD,cAAc,EAAE,CAAC,YAAY,CAAC;SAC/B,CAAC,CAAA;QAEF,MAAM,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE;YAC/B,kBAAkB,EAAE,IAAI;YACxB,sEAAsE;YACtE,kBAAkB,EAAE,WAAW;YAC/B,MAAM,EAAE;gBACN,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;gBACzB,KAAK,EAAE,CAAC;aACT;SACF,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC7B,MAAM,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAClF,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAE7B,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACpD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAc,CAAC,CAAA;YACtD,uEAAuE;YACvE,oEAAoE;YACpE,qEAAqE;YACrE,wEAAwE;YACxE,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,uDAAuD;YACtD,OAAe,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,EAAoC,CAAC,MAAM,CAC1F,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAC3E,CAAC,MAAM,CAAmB,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnD,IAAI,OAAO,GAAG,MAAM,OAAO,CAAA;gBAC3B,IAAI,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBAC5B,OAAO,OAAO,CAAA;gBAChB,CAAC;gBAED,+EAA+E;gBAC/E,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;oBACzE,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;oBACvC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;oBAClE,cAAc,CAAC,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAA;oBACtC,MAAM,MAAM,GAAY,MAAM,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;oBACrE,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;wBACnB,OAAO,GAAG,MAAM,CAAA;oBAClB,CAAC;oBACD,SAAS,GAAG,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,SAAS,CAAA;gBACjE,CAAC;gBACD,OAAO,OAAO,CAAA;YAChB,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;QAC9B,CAAC,CAAC,CAAA;QAEF,OAAO,CAAC,WAAW,EAAoC;aACpD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;aACnF,OAAO,CAAC,MAAM,CAAC,EAAE;YAChB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC,GAAG,CAAA;YAC3D,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;gBAC1B,OAAM;YACR,CAAC;YACD,MAAM,CAAC,KAAK,CAAC;gBACX,GAAG,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM;gBAC3B,MAAM,EAAE;oBACN,QAAQ,EAAE;wBACR,kBAAkB;wBAClB,mCAAmC;wBACnC,qBAAqB;qBACtB;oBACD,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;oBACvD,GAAG,CACD;wBACE,WAAW,CAAC,IAAI;wBAChB,WAAW,CAAC,KAAK;wBACjB,WAAW,CAAC,GAAG;qBAChB,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAChB,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE;wBACrD,CAAC,CAAC,EAAE,CACP;oBACD,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;oBACnD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ;oBACjC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;iBACtD;gBACD,OAAO,EAAE,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC;aAC/C,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEJ,OAAO,CAAC,WAAW,GAAG,IAAI,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,GAAM,EAAE,KAAK,GAAW,aAAa,EAChB,EAAE;IACvB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,GAA0B,CAAA;IAE1C,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAEhC,IAAI,OAAO,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;QACjC,OAAO,CAAC,YAAY,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { InitializedService
|
|
1
|
+
import type { InitializedService } from '@owlmeans/context';
|
|
2
2
|
import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
|
|
3
3
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
|
4
4
|
import '@fastify/middie/types/index.d.ts';
|
|
5
5
|
export interface ApiServer extends InitializedService {
|
|
6
6
|
server: FastifyInstance;
|
|
7
|
-
layers: [Layer.System];
|
|
8
7
|
listen: () => Promise<void>;
|
|
9
8
|
}
|
|
10
9
|
export interface Request extends FastifyRequest {
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,kCAAkC,CAAA;AAEzC,MAAM,WAAW,SAAU,SAAQ,kBAAkB;IACnD,MAAM,EAAE,eAAe,CAAA;IAEvB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,cAAc;CAAI;AAEnD,MAAM,WAAW,QAAS,SAAQ,YAAY;CAAI;AAElD,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,SAAS,CAAA;CAC9B;AAED,MAAM,WAAW,MAAO,SAAQ,YAAY;CAAI;AAEhD,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAC1E,eAAe;CAAI"}
|
package/build/utils/error.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
import type { FastifyReply } from 'fastify';
|
|
2
|
+
/**
|
|
3
|
+
* Map a thrown error onto an HTTP status.
|
|
4
|
+
*
|
|
5
|
+
* Two families reach here and both must be recognised. `AuthFailedError` / `AccessError` are this
|
|
6
|
+
* package's own, raised by the request pipeline itself. `AuthorizationError` / `AuthForbidden`
|
|
7
|
+
* come from `@owlmeans/auth` and are what the guards and gates actually throw — an unrecognised
|
|
8
|
+
* one answers 500, which reports a refused request as a crashed server: the client cannot tell
|
|
9
|
+
* "sign in again" from "the service is broken", and a consumer watching statuses concludes the
|
|
10
|
+
* application fell over.
|
|
11
|
+
*
|
|
12
|
+
* **Order matters.** `AuthForbidden extends AuthorizationError`, so the 403 branch has to be
|
|
13
|
+
* tested first or every refusal of a permission is reported as a failure to authenticate.
|
|
14
|
+
*/
|
|
2
15
|
export declare const handleError: (error: Error, reply: FastifyReply) => void;
|
|
3
16
|
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAK3C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,UAAW,KAAK,SAAS,YAAY,SAe5D,CAAA"}
|
package/build/utils/error.js
CHANGED
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import { FORBIDDEN_ERROR, SERVER_ERROR, UNAUTHORIZED_ERROR } from '@owlmeans/api';
|
|
2
2
|
import { AccessError, AuthFailedError } from '../errors.js';
|
|
3
|
+
import { AuthForbidden, AuthorizationError } from '@owlmeans/auth';
|
|
3
4
|
import { ResilientError } from '@owlmeans/error';
|
|
5
|
+
/**
|
|
6
|
+
* Map a thrown error onto an HTTP status.
|
|
7
|
+
*
|
|
8
|
+
* Two families reach here and both must be recognised. `AuthFailedError` / `AccessError` are this
|
|
9
|
+
* package's own, raised by the request pipeline itself. `AuthorizationError` / `AuthForbidden`
|
|
10
|
+
* come from `@owlmeans/auth` and are what the guards and gates actually throw — an unrecognised
|
|
11
|
+
* one answers 500, which reports a refused request as a crashed server: the client cannot tell
|
|
12
|
+
* "sign in again" from "the service is broken", and a consumer watching statuses concludes the
|
|
13
|
+
* application fell over.
|
|
14
|
+
*
|
|
15
|
+
* **Order matters.** `AuthForbidden extends AuthorizationError`, so the 403 branch has to be
|
|
16
|
+
* tested first or every refusal of a permission is reported as a failure to authenticate.
|
|
17
|
+
*/
|
|
4
18
|
export const handleError = (error, reply) => {
|
|
5
19
|
let code = SERVER_ERROR;
|
|
6
|
-
if (error instanceof
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
else if (error instanceof AccessError) {
|
|
20
|
+
if (error instanceof AuthForbidden || error instanceof AccessError) {
|
|
21
|
+
// An established identity that lacks the permission. Re-authenticating changes nothing.
|
|
10
22
|
code = FORBIDDEN_ERROR;
|
|
11
23
|
}
|
|
24
|
+
else if (error instanceof AuthorizationError || error instanceof AuthFailedError) {
|
|
25
|
+
// No usable credential — absent, expired, revoked, or naming a session this server no longer
|
|
26
|
+
// holds. The caller is told to sign in, not that signing in would not help.
|
|
27
|
+
code = UNAUTHORIZED_ERROR;
|
|
28
|
+
}
|
|
12
29
|
if (!reply.sent) {
|
|
13
30
|
reply.code(code).send(ResilientError.marshal(ResilientError.ensure(error)).message);
|
|
14
31
|
}
|
package/build/utils/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,KAAmB,EAAE,EAAE;IAC/D,IAAI,IAAI,GAAW,YAAY,CAAA;IAC/B,IAAI,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,KAAmB,EAAE,EAAE;IAC/D,IAAI,IAAI,GAAW,YAAY,CAAA;IAC/B,IAAI,KAAK,YAAY,aAAa,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACnE,wFAAwF;QACxF,IAAI,GAAG,eAAe,CAAA;IACxB,CAAC;SAAM,IAAI,KAAK,YAAY,kBAAkB,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;QACnF,6FAA6F;QAC7F,4EAA4E;QAC5E,IAAI,GAAG,kBAAkB,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CACnB,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,KAAc,CAAC,CAAC,CAAC,OAAO,CACtE,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAGnE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAM3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI;AAEzE,eAAO,MAAM,SAAS,GAAU,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAC3D,CAAC,UAAU,gBAAgB,CAAC,cAAc,CAAC,OAC/C,cAAc,SAAS,YAAY,KACvC,OAAO,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAmD/C,CAAA"}
|
package/build/utils/guards.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isContextWithoutIds, Layer } from '@owlmeans/context';
|
|
2
1
|
import { provideResponse } from '@owlmeans/entrypoint';
|
|
3
2
|
import { executeResponse, provideRequest } from './payload.js';
|
|
4
3
|
import { AuthFailedError } from '../errors.js';
|
|
4
|
+
import { attachEntity } from '@owlmeans/auth-common';
|
|
5
5
|
export const authorize = async (context, module, req, reply) => {
|
|
6
6
|
const guards = module.getGuards();
|
|
7
7
|
if (guards.length > 0) {
|
|
@@ -34,20 +34,16 @@ export const authorize = async (context, module, req, reply) => {
|
|
|
34
34
|
if (request.auth != null) {
|
|
35
35
|
req._auth = request.auth;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await context.waitForInitialized();
|
|
48
|
-
// We elevate module to the context level if it was changed
|
|
49
|
-
module = context.entrypoint(module.alias);
|
|
50
|
-
await module.resolve();
|
|
37
|
+
// The token names the organization by slug; everything downstream — grants, records, minted
|
|
38
|
+
// infrastructure names — keys on the entity's stable id. Resolving here, once, is what keeps a
|
|
39
|
+
// rename from being a sweep of every handler: the id arrives on the request, and a slug that
|
|
40
|
+
// has since been retired still resolves to the entity that retired it.
|
|
41
|
+
const entity = await attachEntity(context, request);
|
|
42
|
+
if (entity != null) {
|
|
43
|
+
// Carried on the raw request the same way `_auth` is, so the request the handler is given
|
|
44
|
+
// later — a different object, built after this runs — sees the same resolution.
|
|
45
|
+
;
|
|
46
|
+
req._entity = entity;
|
|
51
47
|
}
|
|
52
48
|
}
|
|
53
49
|
// Update context in request object
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/utils/guards.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAKpD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAU,EAAE,MAAwC,EACpD,GAAmB,EAAE,KAAmB,EACQ,EAAE;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAA;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAEjD,IAAI,KAAK,GAA6B,SAAS,CAAA;QAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAiB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACnD,IAAI,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC1C,KAAK,GAAG,MAAM,CAAA;YAChB,CAAC;YACD,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;YACtC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,MAAK;YACP,CAAC;QACH,CAAC;QAED,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,eAAe,EAAE,CAAA;QAC7B,CAAC;QAED,MAAM,YAAY,GAAG,eAAe,CAAO,KAAK,CAAC,CAAA;QACjD,IAAI,CAAC,MAAM,KAAK,CAAC,MAAM,CAAU,OAAO,EAAE,YAAY,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;QACD,eAAe,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QAC1C,6EAA6E;QAC7E,oCAAoC;QACpC,6GAA6G;QAC7G,IAAI;QACJ,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC;QAClC,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,GAAW,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAA;QACnC,CAAC;QAED,4FAA4F;QAC5F,+FAA+F;QAC/F,6FAA6F;QAC7F,uEAAuE;QACvE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACnD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,0FAA0F;YAC1F,gFAAgF;YAChF,CAAC;YAAC,GAAW,CAAC,OAAO,GAAG,MAAM,CAAA;QAChC,CAAC;IACH,CAAC;IACD,mCAAmC;IAClC,GAAW,CAAC,IAAI,GAAG,OAAO,CAAA;IAE3B,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC1B,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAE1C,eAAO,MAAM,cAAc,UAAW,MAAM,OAAO,OAAO,cAAc,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAE1C,eAAO,MAAM,cAAc,UAAW,MAAM,OAAO,OAAO,cAAc,OAAO,KAAG,eAejF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,YAAY,gBAAgB,CAAC,CAAC,CAAC,SAAS,QAAQ,iBAAiB,OAAO,KAAG,OAuB3G,CAAA;AAGD,eAAO,MAAM,cAAc,WAAY,eAAe,oBAgBrD,CAAA"}
|
package/build/utils/payload.js
CHANGED
|
@@ -5,6 +5,9 @@ export const provideRequest = (alias, req, provision) => {
|
|
|
5
5
|
return {
|
|
6
6
|
alias,
|
|
7
7
|
auth: req._auth ?? undefined,
|
|
8
|
+
// Resolved once by `authorize` and carried by reference, exactly like `_auth`, so a handler
|
|
9
|
+
// reached through any path sees the same entity the guard admitted.
|
|
10
|
+
entity: req._entity ?? undefined,
|
|
8
11
|
params: req.params,
|
|
9
12
|
body: req.body,
|
|
10
13
|
headers: req.headers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAGxD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGnE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,GAAY,EAAE,SAAmB,EAAmB,EAAE;IAClG,SAAS,GAAG,SAAS,IAAI,KAAK,CAAA;IAC9B,OAAO;QACL,KAAK;QACL,IAAI,EAAG,GAAW,CAAC,KAAK,IAAI,SAAS;QACrC,MAAM,EAAE,GAAG,CAAC,MAA4D;QACxE,IAAI,EAAE,GAAG,CAAC,IAA2B;QACrC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAA2D;QACtE,IAAI,EAAE,GAAG,CAAC,GAAG;QACb,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;KACtC,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,QAA6B,EAAE,KAAe,EAAE,YAAsB,EAAW,EAAE;IACpH,IAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,QAAQ,CAAC,KAAK,CAAA;QACtB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrD,OAAO,IAAI,CAAA;IACb,CAAC;SAAM,IAAI,QAAQ,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QACpC,QAAQ,QAAQ,CAAC,OAAO,EAAE,CAAC;YACzB,KAAK,iBAAiB,CAAC,QAAQ;gBAC7B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACzC,MAAK;YACP,KAAK,iBAAiB,CAAC,OAAO;gBAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,iBAAiB,CAAC,EAAE,CAAC;YAC1B;gBACE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAGD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAuB,EAAE,EAAE;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAA;YACtB,MAAM,CAAC,MAAM,GAAG,WAAW,CAAA;YAC3B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAC5B,OAAO,MAAM,CAAC,QAAQ,CAAA;YACxB,CAAC;QACH,CAAC;aAAM,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YACrC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,KAAwB,CAAC,CAAC,CAAC,CACzG,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/utils/payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/utils/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE3D,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQ3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,KAAK,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AAEpC,eAAO,MAAM,cAAc,YAAa,OAAO,UAAU,gBAAgB,KAAG,MAAM,IAAI,gBAAgB,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/utils/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE3D,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAG5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQ3E,KAAK,MAAM,GAAG,YAAY,CAAA;AAC1B,KAAK,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;AAEpC,eAAO,MAAM,cAAc,YAAa,OAAO,UAAU,gBAAgB,KAAG,MAAM,IAAI,gBAAgB,CAAC,OAAO,CAe7G,CAAA;AAED,eAAO,MAAM,mBAAmB,WAAY,gBAAgB,CAAC,cAAc,CAAC,YAAY,MAAM,WAChF,cAAc,SAAS,YAAY,kBA0C9C,CAAA"}
|
package/build/utils/server.js
CHANGED
|
@@ -14,7 +14,10 @@ export const canServeModule = (context, module) => {
|
|
|
14
14
|
if (module.route.route.service != null && module.route.route.service !== context.cfg.service) {
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
// Only the protocols HTTP actually carries. A socket is upgraded elsewhere and a queued job is
|
|
18
|
+
// taken off the broker by the worker — mounting either on the HTTP server would answer it twice.
|
|
19
|
+
if (module.route.route.protocol === RouteProtocols.SOCKET
|
|
20
|
+
|| module.route.route.protocol === RouteProtocols.QUEUE) {
|
|
18
21
|
return false;
|
|
19
22
|
}
|
|
20
23
|
return 'isIntermediate' in module.route;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/utils/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAIjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAKhD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAgB,EAAE,MAAwB,EAAuC,EAAE;IAChH,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;QAChD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7F,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,cAAc,CAAC,MAAM,EAAE,CAAC;QAC1D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,gBAAgB,IAAI,MAAM,CAAC,KAAK,CAAA;AACzC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAwC,EAAE,QAAgB,EAAE,EAAE,CAChG,KAAK,EAAE,GAAmB,EAAE,KAAmB,EAAE,EAAE;IACjD,iDAAiD;IACjD,IAAI,OAAO,GAAG,aAAa,CAAmB,GAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACzE,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;QAC/D,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;QACvB,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;QAEtB,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;QAEvD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,GAAgB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC9C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;YAC5C,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QACxC,CAAC;QAED,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAEtC,iEAAiE;QACjE,mEAAmE;QACnE,+DAA+D;QAC/D,oEAAoE;QACpE,oEAAoE;QACpE,qEAAqE;QACrE,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QACxD,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,2BAA2B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,KAAK,KAAK,QAAQ,GAAG,CAAC,CAAA;QACvD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC7C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACpB,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,KAAK,GAAiB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACzD,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAc,CAAC,CAAC,CAAA;YAC1D,OAAM;QACR,CAAC;QACD,WAAW,CAAC,KAAc,EAAE,KAAK,CAAC,CAAA;IACpC,CAAC;AACH,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/utils/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-api",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsc -b",
|
|
8
8
|
"dev": "sleep 264 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
9
|
-
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
9
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty",
|
|
10
|
+
"test": "bun test ./tests"
|
|
10
11
|
},
|
|
11
12
|
"main": "build/index.js",
|
|
12
13
|
"module": "build/index.js",
|
|
@@ -32,15 +33,15 @@
|
|
|
32
33
|
"@fastify/helmet": "^13.1.0",
|
|
33
34
|
"@fastify/middie": "^9.0.2",
|
|
34
35
|
"@fastify/multipart": "^9.0.1",
|
|
35
|
-
"@owlmeans/api": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/server-entrypoint": "^0.1.18-rc.
|
|
36
|
+
"@owlmeans/api": "^0.1.18-rc.26",
|
|
37
|
+
"@owlmeans/auth": "^0.1.18-rc.22",
|
|
38
|
+
"@owlmeans/auth-common": "^0.1.18-rc.26",
|
|
39
|
+
"@owlmeans/context": "^0.1.18-rc.21",
|
|
40
|
+
"@owlmeans/error": "^0.1.18-rc.21",
|
|
41
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.24",
|
|
42
|
+
"@owlmeans/route": "^0.1.18-rc.22",
|
|
43
|
+
"@owlmeans/server-context": "^0.1.18-rc.25",
|
|
44
|
+
"@owlmeans/server-entrypoint": "^0.1.18-rc.24",
|
|
44
45
|
"ajv-errors": "^3.0.0",
|
|
45
46
|
"fastify": "^5.0.0",
|
|
46
47
|
"fastify-raw-body": "^5.0.0",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@owlmeans/dep-config": "workspace:*",
|
|
56
|
+
"@types/bun": "^1.4.0",
|
|
55
57
|
"@types/node": "^26.1.0",
|
|
56
58
|
"nodemon": "^3.1.14",
|
|
57
59
|
"typescript": "^7.0.2"
|
package/src/errors.ts
CHANGED
|
@@ -29,7 +29,25 @@ export class NoFileError extends ApiError {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* `handlers().body/params/request` was handed something it cannot serve — not a plain callback,
|
|
34
|
+
* and not a `BoundEntrypointHandler` bound to the SAME protocol it is being wrapped for. Thrown
|
|
35
|
+
* from inside the bound handler's own request path, so the module still loads and every OTHER
|
|
36
|
+
* route on it still answers; only the misconfigured one reports why, as a 500 rather than the
|
|
37
|
+
* opaque `TypeError: handler is not a function` a double wrap used to fail with. See
|
|
38
|
+
* `handlers()` in `protocol.ts` for what does and does not reach here.
|
|
39
|
+
*/
|
|
40
|
+
export class HandlerMisconfiguredError extends ApiError {
|
|
41
|
+
public static override typeName = 'HandlerMisconfiguredError'
|
|
42
|
+
|
|
43
|
+
constructor(message: string = 'error') {
|
|
44
|
+
super(`handler:misconfigured:${message}`)
|
|
45
|
+
this.type = HandlerMisconfiguredError.typeName
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
32
49
|
ResilientError.registerErrorClass(AuthFailedError)
|
|
33
50
|
ResilientError.registerErrorClass(AccessError)
|
|
34
51
|
ResilientError.registerErrorClass(NoFileError)
|
|
52
|
+
ResilientError.registerErrorClass(HandlerMisconfiguredError)
|
|
35
53
|
|
package/src/helper.ts
CHANGED
|
@@ -8,8 +8,17 @@ import type { Config, Context } from './types.js'
|
|
|
8
8
|
import type { FastifyRequest } from 'fastify'
|
|
9
9
|
import type { MultipartFile } from '@fastify/multipart'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* The context a handler runs against.
|
|
13
|
+
*
|
|
14
|
+
* The HTTP boundary hangs the request-scoped context on the raw Fastify request, so a handler
|
|
15
|
+
* reached that way gets it from there. A request that did not come from Fastify has no `original`
|
|
16
|
+
* at all — a queued call is rebuilt from an envelope, and a socket frame carries its own — so this
|
|
17
|
+
* has to fall back rather than dereference: these handlers are the same functions on every
|
|
18
|
+
* transport, and only the way they were reached differs.
|
|
19
|
+
*/
|
|
11
20
|
const _castContextFromOriginal = <C extends BasicConfig, T extends BasicContext<C> = BasicContext<C>>(req: AbstractRequest, def: T): T => {
|
|
12
|
-
return req.original
|
|
21
|
+
return req.original?._ctx ?? def
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
export const handleBody: <T>(
|