@owlmeans/server-api 0.1.18-rc.2 → 0.1.18-rc.21
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 +32 -34
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-api/SKILL.md +27 -24
- 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 +26 -0
- package/build/protocol.d.ts.map +1 -0
- package/build/protocol.js +41 -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 +10 -10
- package/src/helper.ts +10 -1
- package/src/hold.ts +84 -0
- package/src/index.ts +2 -0
- package/src/protocol.ts +104 -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/build/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -1,70 +1,68 @@
|
|
|
1
1
|
# @owlmeans/server-api
|
|
2
2
|
|
|
3
|
-
Fastify-based HTTP/WebSocket server with handler
|
|
3
|
+
Fastify-based HTTP/WebSocket server with typed handler factories for the OwlMeans entrypoint system.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- Built on [Fastify](https://fastify.dev/) — registered
|
|
7
|
+
- `handlers<Context>()` creates protocol-bound `body()`, `params()`, `request()` and upload handlers
|
|
8
|
+
- Built on [Fastify](https://fastify.dev/) — registered entrypoints become Fastify routes automatically
|
|
9
9
|
- `createApiServer` / `appendApiServer` initialize the HTTP server in a context
|
|
10
10
|
- Not typically used directly — import handlers from `@owlmeans/server-app`
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/server-api
|
|
15
|
+
bun add @owlmeans/server-api@^0.1.18-rc.16
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Handlers are derived from the shared protocol and attached with `bind()`:
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
|
-
import {
|
|
23
|
+
import { handlers } from '@owlmeans/server-api'
|
|
24
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
25
|
+
import { projectEntrypoints } from 'project-common/entrypoints'
|
|
26
|
+
|
|
27
|
+
const api = handlers<Context>()
|
|
24
28
|
|
|
25
29
|
// Body handler: receives parsed + validated body as first arg
|
|
26
|
-
|
|
30
|
+
const create = api.body(projectEntrypoints.create, async (payload, context, req) => {
|
|
27
31
|
const ctx = context as Context
|
|
28
|
-
return await ctx.project().create({ ...payload, entityId: req.
|
|
32
|
+
return await ctx.project().create({ ...payload, entityId: req.entity!.id })
|
|
29
33
|
})
|
|
30
34
|
|
|
31
35
|
// Params handler: receives validated URL params as first arg
|
|
32
|
-
|
|
36
|
+
const get = api.params(projectEntrypoints.get, async (params, context, req) => {
|
|
33
37
|
return await (context as Context).project().get(params.id)
|
|
34
38
|
})
|
|
35
39
|
|
|
36
40
|
// Request handler: receives the full AbstractRequest
|
|
37
|
-
|
|
41
|
+
const health = api.request(projectEntrypoints.health, async (req, context) => {
|
|
38
42
|
return { status: 'ok' }
|
|
39
43
|
})
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## API
|
|
43
|
-
|
|
44
|
-
### `handleBody<T>(handler): RefedModuleHandler`
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
export const entrypoints = [
|
|
46
|
+
bind(projectEntrypoints.create, create),
|
|
47
|
+
bind(projectEntrypoints.get, get),
|
|
48
|
+
bind(projectEntrypoints.health, health),
|
|
49
|
+
]
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Wraps a handler that receives the validated URL params as the first argument.
|
|
54
|
-
```typescript
|
|
55
|
-
handler: (payload: T, ctx: Context, req: AbstractRequest) => Promise<any>
|
|
56
|
-
```
|
|
52
|
+
## API
|
|
57
53
|
|
|
58
|
-
### `
|
|
54
|
+
### `handlers<Context>()`
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
Creates factories whose first argument is the protocol declaration, coupling the callback to its
|
|
57
|
+
request and response contract.
|
|
61
58
|
```typescript
|
|
62
|
-
|
|
59
|
+
handlers<Context>().body(protocol, handler)
|
|
60
|
+
handlers<Context>().params(protocol, handler)
|
|
61
|
+
handlers<Context>().request(protocol, handler)
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Wraps middleware-layer handlers that do not return a final response.
|
|
64
|
+
Each callback returns the response value; thrown `ResilientError` subclasses are mapped by the
|
|
65
|
+
server. `uploadedFile(request)` remains the multipart boundary.
|
|
68
66
|
|
|
69
67
|
### `extractUploadedFile(req, fieldName): UploadedFile | null`
|
|
70
68
|
|
|
@@ -72,9 +70,9 @@ Extract a multipart-uploaded file from the request.
|
|
|
72
70
|
|
|
73
71
|
## Related Packages
|
|
74
72
|
|
|
75
|
-
- [`@owlmeans/server-app`](../server-app) —
|
|
76
|
-
- [`@owlmeans/server-
|
|
77
|
-
- [`@owlmeans/server-socket`](../server-socket) — WebSocket `
|
|
73
|
+
- [`@owlmeans/server-app`](../server-app) — application bootstrap and convenience re-exports
|
|
74
|
+
- [`@owlmeans/server-entrypoint`](../server-entrypoint) — `bind()` attaches handlers to protocols
|
|
75
|
+
- [`@owlmeans/server-socket`](../server-socket) — WebSocket `connection` counterpart
|
|
78
76
|
|
|
79
77
|
<!-- owlmeans:agent-guidance:start -->
|
|
80
78
|
## Agent guidance
|
|
@@ -84,7 +82,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
84
82
|
your project's skill store (`.agents/skills/`):
|
|
85
83
|
|
|
86
84
|
```sh
|
|
87
|
-
npx @owlmeans/agent-skills
|
|
85
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.16
|
|
88
86
|
```
|
|
89
87
|
|
|
90
88
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/server-api",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.21",
|
|
5
|
+
"generatedAt": "2026-09-12T12:32:46.363Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,40 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: server-api
|
|
3
|
-
description:
|
|
3
|
+
description: Implement HTTP entrypoint protocols with @owlmeans/server-api handlers<Context>().body(), params(), request(), and uploadedFile(). Load before writing an API handler.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
7
|
|
|
8
8
|
# @owlmeans/server-api
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Make handlers from the protocol declaration so input and output types stay coupled to the shared
|
|
11
|
+
contract:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```ts
|
|
14
|
+
const api = handlers<AppContext>()
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| `Server`, `ServerRequest`, `ServerResponse` types | Runtime shapes |
|
|
19
|
-
| Errors | Typed transport errors |
|
|
20
|
-
| Constants | Default ports, paths |
|
|
21
|
-
| Helpers | Middleware composition |
|
|
16
|
+
const create = api.body(projectEntrypoints.create, async (body, context, request) =>
|
|
17
|
+
context.projects.create(body, request.auth)
|
|
18
|
+
)
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
const get = api.params(projectEntrypoints.get, async ({ id }, context) =>
|
|
21
|
+
context.projects.get(id)
|
|
22
|
+
)
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
const search = api.request(projectEntrypoints.search, async (request, context) =>
|
|
25
|
+
context.projects.search(request.query)
|
|
26
|
+
)
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
import { makeServer } from '@owlmeans/server-api'
|
|
33
|
-
const server = makeServer({ port: 8080 })
|
|
34
|
-
context.registerService(server)
|
|
28
|
+
export const entrypoints = [
|
|
29
|
+
bind(projectEntrypoints.create, create),
|
|
30
|
+
bind(projectEntrypoints.get, get),
|
|
31
|
+
bind(projectEntrypoints.search, search),
|
|
32
|
+
]
|
|
35
33
|
```
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
`body` and `params` are available only for a protocol declaring that section. `request` works for
|
|
36
|
+
any protocol and receives all its typed sections plus request metadata. A successful callback
|
|
37
|
+
return resolves the entrypoint with `EntrypointOutcome.Ok`; a thrown error rejects it.
|
|
38
|
+
|
|
39
|
+
`uploadedFile(request)` is the Fastify multipart boundary. Keep raw Fastify access there rather
|
|
40
|
+
than reaching through `request.original` in application code.
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
- `
|
|
42
|
+
Do not use unbound compatibility handler wrappers. For a WebSocket route use
|
|
43
|
+
`@owlmeans/server-socket`'s `connection(protocol, callback)`.
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACzE,OAAO,KAAK,EAAU,OAAO,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAevD,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,EACzB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,KACxF,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAahD,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,CAAC,CAAC,EAC3B,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,KAExF,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAahD,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,CAC1B,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,KAC7G,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAWhD,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,CAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAC7G,sBAAsB,CAAC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,CAc3D,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAU,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,eAAe,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAItH,CAAA;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;CAAI"}
|
package/build/helper.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { assertContext } from '@owlmeans/context';
|
|
2
2
|
import { EntrypointOutcome } from '@owlmeans/entrypoint';
|
|
3
|
+
/**
|
|
4
|
+
* The context a handler runs against.
|
|
5
|
+
*
|
|
6
|
+
* The HTTP boundary hangs the request-scoped context on the raw Fastify request, so a handler
|
|
7
|
+
* reached that way gets it from there. A request that did not come from Fastify has no `original`
|
|
8
|
+
* at all — a queued call is rebuilt from an envelope, and a socket frame carries its own — so this
|
|
9
|
+
* has to fall back rather than dereference: these handlers are the same functions on every
|
|
10
|
+
* transport, and only the way they were reached differs.
|
|
11
|
+
*/
|
|
3
12
|
const _castContextFromOriginal = (req, def) => {
|
|
4
|
-
return req.original
|
|
13
|
+
return req.original?._ctx ?? def;
|
|
5
14
|
};
|
|
6
15
|
export const handleBody = handler => ref => async (req, res) => {
|
|
7
16
|
const ctx = assertContext(ref.ref?.ctx);
|
package/build/helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAOxD,MAAM,wBAAwB,GAAG,CAAqE,GAAoB,EAAE,GAAM,EAAK,EAAE;IACvI,OAAO,GAAG,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAOxD;;;;;;;;GAQG;AACH,MAAM,wBAAwB,GAAG,CAAqE,GAAoB,EAAE,GAAM,EAAK,EAAE;IACvI,OAAO,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,GAAG,CAAA;AAClC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAE8B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACxF,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAY,CAAA;IAClD,IAAI,CAAC;QACH,GAAG,CAAC,OAAO,CAAC,MAAM,OAAO,CACvB,GAAG,CAAC,IAAW,EACf,wBAAwB,CAAkB,GAAG,EAAE,GAAG,CAA8B,EAChF,GAAG,CACJ,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;IACxB,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAG4B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACxF,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAY,CAAA;IAClD,IAAI,CAAC;QACH,GAAG,CAAC,OAAO,CAAC,MAAM,OAAO,CACvB,GAAG,CAAC,MAAa,EACjB,wBAAwB,CAAkB,GAAG,EAAE,GAAG,CAA8B,EAChF,GAAG,CACJ,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;IACxB,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAE2B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACxF,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAY,CAAA;IAClD,IAAI,CAAC;QACH,GAAG,CAAC,OAAO,CAAC,MAAM,OAAO,CACvB,GAAG,EAAE,wBAAwB,CAAkB,GAAG,EAAE,GAAG,CAA8B,EAAE,GAAG,CAC3F,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;IACxB,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAEiC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACnG,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAY,CAAA;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,GAAG,EAAE,wBAAwB,CAAkB,GAAG,EAAE,GAAG,CAA8B,CACtF,CAAA;QACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACrB,CAAC;QAED,OAAO,GAAG,CAAC,KAAK,CAAA;IAClB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;IACxB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAqB,GAAuB,EAAqC,EAAE;IACzH,MAAM,OAAO,GAAG,GAAG,CAAC,QAA0B,CAAA;IAE9C,OAAO,OAAO,CAAC,IAAI,EAAE,CAAA;AACvB,CAAC,CAAA"}
|
package/build/hold.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ServerConfig } from '@owlmeans/server-context';
|
|
2
|
+
export interface ApiPortHoldOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The one path answered 200 while the hold is in place — the app's health endpoint, so
|
|
5
|
+
* whatever supervises the process keeps a conventional liveness answer through the boot.
|
|
6
|
+
* Everything else answers 503 with the same body. Absent, everything is 503.
|
|
7
|
+
*/
|
|
8
|
+
okPath?: string;
|
|
9
|
+
/** Body of every answer, evaluated per request so a changing boot phase is reported live. */
|
|
10
|
+
payload?: () => unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface ApiPortHold {
|
|
13
|
+
/**
|
|
14
|
+
* Free the port for the real server. Awaits the actual close — `listen()` follows immediately,
|
|
15
|
+
* and a predecessor still bound makes it throw — and force-closes keep-alive sockets, so a
|
|
16
|
+
* supervisor's own poller cannot hold the release open.
|
|
17
|
+
*/
|
|
18
|
+
release: () => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Own the app's port while the context initializes, and answer for the app until `listen()`
|
|
22
|
+
* takes over.
|
|
23
|
+
*
|
|
24
|
+
* The API server itself cannot do this: it builds its route table from the entrypoints the
|
|
25
|
+
* context knows about, so it can only bind AFTER `init()` resolves — and Fastify refuses new
|
|
26
|
+
* routes once it is listening. Without a hold, the whole boot window, and every way a boot can
|
|
27
|
+
* fail, leaves nothing on the port; the edge then answers a bare upstream connect error that
|
|
28
|
+
* names neither the app nor the reason, which is indistinguishable from a crashed pod or an app
|
|
29
|
+
* that was never installed.
|
|
30
|
+
*
|
|
31
|
+
* So the boot sequence an app wants is:
|
|
32
|
+
*
|
|
33
|
+
* const hold = await holdApiPort(cfg, { okPath, payload }) // bind FIRST
|
|
34
|
+
* try { ...initialize... } catch { record the failure; return } // hold keeps answering
|
|
35
|
+
* await hold.release()
|
|
36
|
+
* await context.getApiServer().listen()
|
|
37
|
+
*
|
|
38
|
+
* Everything that is not the health path answers **503, not 404**: the routes the app really
|
|
39
|
+
* serves do not exist yet, and "no such route" would be a lie that outlives the boot.
|
|
40
|
+
*
|
|
41
|
+
* The port and host are resolved exactly as `listen()` resolves them — from the service's own
|
|
42
|
+
* declaration in `cfg.services[cfg.service]` — so the hold and the server can never disagree
|
|
43
|
+
* about which socket they are trading.
|
|
44
|
+
*
|
|
45
|
+
* A bind failure here (EADDRINUSE above all) throws to the caller and must be treated as fatal:
|
|
46
|
+
* a process that continues past it ends the boot with nothing listening and nothing holding the
|
|
47
|
+
* event loop, i.e. a clean exit 0 while a predecessor keeps serving stale code. Name the error
|
|
48
|
+
* and exit non-zero — that is what makes a supervisor reclaim the port instead of respawning
|
|
49
|
+
* into it.
|
|
50
|
+
*/
|
|
51
|
+
export declare const holdApiPort: (cfg: ServerConfig, opts?: ApiPortHoldOptions) => Promise<ApiPortHold>;
|
|
52
|
+
//# sourceMappingURL=hold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hold.d.ts","sourceRoot":"","sources":["../src/hold.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG5D,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,OAAO,CAAA;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,WAAW,QACjB,YAAY,SAAQ,kBAAkB,KAC1C,OAAO,CAAC,WAAW,CA0BrB,CAAA"}
|
package/build/hold.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import { CLOSED_HOST, OPENED_HOST, PORT } from './consts.js';
|
|
3
|
+
/**
|
|
4
|
+
* Own the app's port while the context initializes, and answer for the app until `listen()`
|
|
5
|
+
* takes over.
|
|
6
|
+
*
|
|
7
|
+
* The API server itself cannot do this: it builds its route table from the entrypoints the
|
|
8
|
+
* context knows about, so it can only bind AFTER `init()` resolves — and Fastify refuses new
|
|
9
|
+
* routes once it is listening. Without a hold, the whole boot window, and every way a boot can
|
|
10
|
+
* fail, leaves nothing on the port; the edge then answers a bare upstream connect error that
|
|
11
|
+
* names neither the app nor the reason, which is indistinguishable from a crashed pod or an app
|
|
12
|
+
* that was never installed.
|
|
13
|
+
*
|
|
14
|
+
* So the boot sequence an app wants is:
|
|
15
|
+
*
|
|
16
|
+
* const hold = await holdApiPort(cfg, { okPath, payload }) // bind FIRST
|
|
17
|
+
* try { ...initialize... } catch { record the failure; return } // hold keeps answering
|
|
18
|
+
* await hold.release()
|
|
19
|
+
* await context.getApiServer().listen()
|
|
20
|
+
*
|
|
21
|
+
* Everything that is not the health path answers **503, not 404**: the routes the app really
|
|
22
|
+
* serves do not exist yet, and "no such route" would be a lie that outlives the boot.
|
|
23
|
+
*
|
|
24
|
+
* The port and host are resolved exactly as `listen()` resolves them — from the service's own
|
|
25
|
+
* declaration in `cfg.services[cfg.service]` — so the hold and the server can never disagree
|
|
26
|
+
* about which socket they are trading.
|
|
27
|
+
*
|
|
28
|
+
* A bind failure here (EADDRINUSE above all) throws to the caller and must be treated as fatal:
|
|
29
|
+
* a process that continues past it ends the boot with nothing listening and nothing holding the
|
|
30
|
+
* event loop, i.e. a clean exit 0 while a predecessor keeps serving stale code. Name the error
|
|
31
|
+
* and exit non-zero — that is what makes a supervisor reclaim the port instead of respawning
|
|
32
|
+
* into it.
|
|
33
|
+
*/
|
|
34
|
+
export const holdApiPort = async (cfg, opts = {}) => {
|
|
35
|
+
const config = cfg.services[cfg.service];
|
|
36
|
+
const port = config?.internalPort ?? config?.port ?? PORT;
|
|
37
|
+
const host = config?.opened === true ? OPENED_HOST : CLOSED_HOST;
|
|
38
|
+
const payload = opts.payload ?? (() => ({ status: 'OK' }));
|
|
39
|
+
// Quiet and disposable: no logger, no plugins, and connections are force-closed on release so
|
|
40
|
+
// the handover to the real server is bounded rather than waiting out a keep-alive.
|
|
41
|
+
const server = Fastify({ logger: false, forceCloseConnections: true });
|
|
42
|
+
if (opts.okPath != null) {
|
|
43
|
+
server.all(opts.okPath, async (_request, reply) => {
|
|
44
|
+
return await reply.code(200).send(payload());
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
server.setNotFoundHandler(async (_request, reply) => {
|
|
48
|
+
return await reply.code(503).send(payload());
|
|
49
|
+
});
|
|
50
|
+
await server.listen({ port, host });
|
|
51
|
+
console.log(`api-server: holding ${host}:${port} for the boot${opts.okPath != null ? ` (${opts.okPath})` : ''}`);
|
|
52
|
+
return {
|
|
53
|
+
release: async () => { await server.close(); },
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=hold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hold.js","sourceRoot":"","sources":["../src/hold.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAsB5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAiB,EAAE,IAAI,GAAuB,EAAE,EAC1B,EAAE;IACxB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,YAAY,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAA;IACzD,MAAM,IAAI,GAAG,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAA;IAEhE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAE1D,8FAA8F;IAC9F,mFAAmF;IACnF,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAA;IAEtE,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAChD,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAClD,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACnC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,IAAI,gBAAgB,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEhH,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA,CAAC,CAAC;KAC9C,CAAA;AACH,CAAC,CAAA"}
|
package/build/index.d.ts
CHANGED
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
package/build/index.js
CHANGED
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
type HandlerResponse<Response> = [Response] extends [undefined] ? void | undefined : Response;
|
|
5
|
+
type MaybePromise<Value> = Value | Promise<Value>;
|
|
6
|
+
type BodyProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
|
|
7
|
+
body: OpenValue;
|
|
8
|
+
} ? Protocol : never;
|
|
9
|
+
type ParamsProtocol<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends {
|
|
10
|
+
params: object;
|
|
11
|
+
} ? Protocol : never;
|
|
12
|
+
/**
|
|
13
|
+
* Make server handlers that infer request sections and response values from their protocol.
|
|
14
|
+
* The protocol is passed once; application callbacks never name request or reply generics.
|
|
15
|
+
*/
|
|
16
|
+
export declare const handlers: <Context extends BasicContext<BasicConfig>>() => {
|
|
17
|
+
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>;
|
|
18
|
+
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>;
|
|
19
|
+
request: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, handler: (request: HandlerRequest<RequestOf<Protocol>>, context: Context) => MaybePromise<HandlerResponse<ResponseOf<Protocol>>>) => BoundEntrypointHandler<Protocol>;
|
|
20
|
+
};
|
|
21
|
+
/** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
|
|
22
|
+
export declare const uploadedFile: (request: HandlerRequest<{
|
|
23
|
+
body: object;
|
|
24
|
+
}>) => Promise<import('@fastify/multipart').MultipartFile | undefined>;
|
|
25
|
+
export {};
|
|
26
|
+
//# 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;AAEzE,KAAK,eAAe,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAAA;AAC7F,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;AAyCpB;;;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,41 @@
|
|
|
1
|
+
import { assertContext } from '@owlmeans/context';
|
|
2
|
+
import { EntrypointOutcome } from '@owlmeans/entrypoint';
|
|
3
|
+
const contextFor = (request, fallback) => {
|
|
4
|
+
const original = request.original;
|
|
5
|
+
if (original != null && typeof original === 'object' && '_ctx' in original) {
|
|
6
|
+
return original._ctx ?? fallback;
|
|
7
|
+
}
|
|
8
|
+
return fallback;
|
|
9
|
+
};
|
|
10
|
+
const bind = (protocol, execute) => ({
|
|
11
|
+
protocol,
|
|
12
|
+
bind: ref => async (request, response) => {
|
|
13
|
+
const fallback = assertContext(ref.ref?.ctx, protocol.alias);
|
|
14
|
+
try {
|
|
15
|
+
const typedRequest = request;
|
|
16
|
+
const value = await execute(typedRequest, contextFor(request, fallback));
|
|
17
|
+
response.resolve(value, EntrypointOutcome.Ok);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
response.reject(error);
|
|
21
|
+
}
|
|
22
|
+
return response.value;
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Make server handlers that infer request sections and response values from their protocol.
|
|
27
|
+
* The protocol is passed once; application callbacks never name request or reply generics.
|
|
28
|
+
*/
|
|
29
|
+
export const handlers = () => ({
|
|
30
|
+
body: (protocol, handler) => bind(protocol, (request, context) => handler(request.body, context, request)),
|
|
31
|
+
params: (protocol, handler) => bind(protocol, (request, context) => handler(request.params, context, request)),
|
|
32
|
+
request: (protocol, handler) => bind(protocol, handler),
|
|
33
|
+
});
|
|
34
|
+
/** Access a Fastify-specific upload through an explicit boundary helper, never `request.original`. */
|
|
35
|
+
export const uploadedFile = async (request) => {
|
|
36
|
+
const original = request.original;
|
|
37
|
+
if (original == null || typeof original !== 'object' || !('file' in original))
|
|
38
|
+
return undefined;
|
|
39
|
+
return original.file();
|
|
40
|
+
};
|
|
41
|
+
//# 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;AAkBxD,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;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAA8C,EAAE,CAAC,CAAC;IACxE,IAAI,EAAE,CACJ,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC3F,OAEwD,CAAC,OAAO,CAAC,IAAwB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhH,MAAM,EAAE,CACN,QAAkB,EAClB,OAKS,EACyB,EAAE,CAAC,IAAI,CAAoB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC3F,OAEwD,CAAC,OAAO,CAAC,MAA4B,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEpH,OAAO,EAAE,CACP,QAAkB,EAClB,OAGwD,EACtB,EAAE,CAAC,IAAI,CAAoB,QAAQ,EAAE,OAAO,CAAC;CAClF,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":"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"}
|
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"}
|