@owlmeans/entrypoint 0.1.18-rc.13 → 0.1.18-rc.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -40
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/entrypoint/SKILL.md +69 -207
- package/build/index.d.ts +1 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -3
- package/build/index.js.map +1 -1
- package/build/materialize.js +9 -9
- package/build/materialize.js.map +1 -1
- package/build/protocol.d.ts +16 -2
- package/build/protocol.d.ts.map +1 -1
- package/build/protocol.js +18 -1
- package/build/protocol.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +1 -3
- package/src/materialize.ts +8 -8
- package/src/protocol.ts +38 -2
package/README.md
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# @owlmeans/entrypoint
|
|
2
2
|
|
|
3
|
-
Entrypoint system — the
|
|
3
|
+
Entrypoint protocol system — the typed route contract shared between server and client in OwlMeans apps.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- On the server,
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Most commonly used via re-exports in `@owlmeans/server-app` or `@owlmeans/client-entrypoint`
|
|
7
|
+
- A **protocol** is one immutable URL unit: an alias + route + typed contract + access options
|
|
8
|
+
- On the server and client, corresponding bindings add handlers, screens or calls to that protocol
|
|
9
|
+
- All AJV validation schemas live at protocol level, keeping data contracts consistent fullstack
|
|
10
|
+
- Most commonly used with `@owlmeans/server-entrypoint` and `@owlmeans/client-entrypoint`
|
|
12
11
|
|
|
13
12
|
The route declaration an entrypoint carries is immutable: its `path` always stays the segment this
|
|
14
13
|
entrypoint contributes under its parent. Addresses are computed on demand against the context the
|
|
@@ -23,64 +22,58 @@ bun add @owlmeans/entrypoint@^0.1.18-rc.10
|
|
|
23
22
|
|
|
24
23
|
## Usage
|
|
25
24
|
|
|
26
|
-
Define
|
|
25
|
+
Define a protocol with a typed request and guard:
|
|
27
26
|
|
|
28
27
|
```typescript
|
|
29
|
-
import {
|
|
28
|
+
import { contract, protocol, typed } from '@owlmeans/entrypoint'
|
|
30
29
|
import { route } from '@owlmeans/route'
|
|
31
30
|
|
|
32
|
-
const
|
|
31
|
+
const createStoryProtocol = protocol(
|
|
33
32
|
route('story-create', '/stories', { method: 'POST', parent: 'api' }),
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
properties: { story: { type: 'string' }, projectId: { type: 'string' } },
|
|
37
|
-
required: ['story', 'projectId']
|
|
38
|
-
}), guard('authenticated'))
|
|
33
|
+
contract.request({ body: typed<CreateStory>(CreateStorySchema) }, typed<Story>()),
|
|
34
|
+
{ guards: ['authenticated'] },
|
|
39
35
|
)
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
Bind the protocol to a typed server handler:
|
|
43
39
|
|
|
44
40
|
```typescript
|
|
45
|
-
import
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
41
|
+
import { handlers } from '@owlmeans/server-api'
|
|
42
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
43
|
+
import type { Context } from 'my-app-backend'
|
|
44
|
+
|
|
45
|
+
const api = handlers<Context>()
|
|
46
|
+
const create = api.params(createStoryProtocol, async ({ id }, context) =>
|
|
47
|
+
context.project().get(id))
|
|
48
|
+
export const entrypoints = [bind(createStoryProtocol, create)]
|
|
51
49
|
```
|
|
52
50
|
|
|
53
51
|
## API
|
|
54
52
|
|
|
55
|
-
### `
|
|
56
|
-
|
|
57
|
-
Creates an entrypoint. `opts` is typically produced by `filter()`, `guard()`, or `gate()`.
|
|
58
|
-
|
|
59
|
-
### `guard(guard, opts?): CommonEntrypointOptions`
|
|
60
|
-
|
|
61
|
-
Adds an authentication guard requirement.
|
|
53
|
+
### `protocol(route, contract, options?): EntrypointProtocol`
|
|
62
54
|
|
|
63
|
-
|
|
55
|
+
Creates an immutable typed protocol declaration.
|
|
64
56
|
|
|
65
|
-
|
|
57
|
+
### `openProtocol(route, options?): EntrypointProtocol`
|
|
66
58
|
|
|
67
|
-
|
|
59
|
+
Creates an intentionally untyped protocol, used only for framework escape hatches.
|
|
68
60
|
|
|
69
|
-
|
|
61
|
+
### `contract(...)`, `contract.request(...)`, `typed<T>(schema?)`
|
|
70
62
|
|
|
71
|
-
|
|
63
|
+
Describe typed body, params, query, headers and response sections.
|
|
72
64
|
|
|
73
|
-
|
|
65
|
+
Access is declared directly in `EntrypointOptions` as `guards`, `gate` and `sticky`; runtime
|
|
66
|
+
behaviour is added by `bind()`/`bindAll()`/`bindScreen()` in the side-specific package.
|
|
74
67
|
|
|
75
68
|
### Parentship
|
|
76
69
|
|
|
77
70
|
A child names its parent in the route declaration (`route('story-create', '/stories', { parent: 'api' })`).
|
|
78
|
-
`path()` prefixes the parent's segments, and
|
|
79
|
-
|
|
71
|
+
`path()` prefixes the parent's segments, and inherited guards/gates are collected when a runtime
|
|
72
|
+
binds the protocol.
|
|
80
73
|
|
|
81
74
|
### `provideResponse<T>(): AbstractResponse<T>`
|
|
82
75
|
|
|
83
|
-
Creates a response object for use in
|
|
76
|
+
Creates a response object for use in unbound handlers.
|
|
84
77
|
|
|
85
78
|
### Transport
|
|
86
79
|
|
|
@@ -107,8 +100,8 @@ enum EntrypointOutcome { Ok, Accepted, Created, Finished }
|
|
|
107
100
|
|
|
108
101
|
## Related Packages
|
|
109
102
|
|
|
110
|
-
- [`@owlmeans/route`](../route) — `route()` factory used in `
|
|
111
|
-
- [`@owlmeans/server-entrypoint`](../server-entrypoint) — server-side `
|
|
103
|
+
- [`@owlmeans/route`](../route) — `route()` factory used in `protocol(route(...), ... )`
|
|
104
|
+
- [`@owlmeans/server-entrypoint`](../server-entrypoint) — server-side `bind()`/`bindAll()` to attach handlers
|
|
112
105
|
- [`@owlmeans/client-entrypoint`](../client-entrypoint) — client-side entrypoint with API call support
|
|
113
106
|
- [`@owlmeans/server-app`](../server-app) — re-exports everything from this package
|
|
114
107
|
|
|
@@ -120,7 +113,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
120
113
|
your project's skill store (`.agents/skills/`):
|
|
121
114
|
|
|
122
115
|
```sh
|
|
123
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
116
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.16
|
|
124
117
|
```
|
|
125
118
|
|
|
126
119
|
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/entrypoint",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.15",
|
|
5
|
+
"generatedAt": "2026-09-12T12:32:46.381Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: entrypoint
|
|
3
|
-
description: How to
|
|
3
|
+
description: How to declare immutable, typed @owlmeans/entrypoint protocols with protocol(), contract(), typed(), protocol trees, guards, gates, and route transports. Load before defining a shared API, socket, queue, or screen contract.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,220 +8,82 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/entrypoint
|
|
9
9
|
|
|
10
10
|
**Layer:** Core
|
|
11
|
-
**Install:** `"@owlmeans/entrypoint": "^0.1.18-rc.13"` in `dependencies`
|
|
12
|
-
|
|
13
|
-
An entrypoint is an **addressable unit**. New code declares an immutable typed `protocol` once in a
|
|
14
|
-
shared package, then binds that declaration on the client or server. The older mutable
|
|
15
|
-
`entrypoint(...)` + `elevate(...)` form remains supported while applications migrate.
|
|
16
|
-
|
|
17
|
-
## Key Exports
|
|
18
|
-
|
|
19
|
-
| Export | Description |
|
|
20
|
-
|--------|-------------|
|
|
21
|
-
| `protocol(route, contract, opts?)` / `openProtocol(route, opts?)` | Declare an immutable shared protocol |
|
|
22
|
-
| `contract(...)` / `contract.request(...)` | Declare the request sections and response together |
|
|
23
|
-
| `schema<T>(value)` / `typed<T>()` | Carry runtime validation plus type inference, or type information only |
|
|
24
|
-
| `protocols(tree)` | Flatten a named protocol tree for a layer binding |
|
|
25
|
-
| `entrypointRef<Request, Response>(alias)` | Typed adapter reference for dynamic registries |
|
|
26
|
-
| `decorateEntrypoint(protocol, opts)` | Return an immutable protocol with added access/options |
|
|
27
|
-
| `entrypoint(route, opts?)` | Declare an entrypoint on a route model |
|
|
28
|
-
| `guard(alias, opts?)` | Require a guard; returns options, so it wraps rather than takes them |
|
|
29
|
-
| `gate(alias, params, opts?)` | Require a gate; passed as the `opts` of `guard(...)` |
|
|
30
|
-
| `filter(filter, opts?)` | Attach request validators |
|
|
31
|
-
| `body(Schema)` / `params(Schema)` / `query(Schema)` / `headers(Schema)` / `response(Schema, code?)` | AJV validators composed into a `Filter` |
|
|
32
|
-
| `CommonEntrypoint` | The entrypoint interface — declaration, guards/gates, address accessors |
|
|
33
|
-
| `AbstractRequest` / `AbstractResponse` | The request and reply shapes every handler sees |
|
|
34
|
-
| `ResolvedEntity` | `req.entity` — the organization entity's `{ id, slug, iamKey }` |
|
|
35
|
-
| `provideResponse(original?)` | Build a reply object a handler resolves or rejects |
|
|
36
|
-
| `EntrypointHandler` | What a handler implements: `(req, res) => value` |
|
|
37
|
-
| `Filter` | The composed validator set: `{ body, params, query, headers, response }` |
|
|
38
|
-
| `GuardService` / `GateService` | What a guard and a gate implement |
|
|
39
|
-
| `EntrypointOutcome` | Enum: Ok, Accepted, Created, Finished |
|
|
40
|
-
| `EntrypointTransport` | `{ protocol, handle }` — a carrier bound to a route protocol |
|
|
41
|
-
| `transportAlias(protocol?)` | The service alias a transport registers under (`transport:<protocol>`) |
|
|
42
|
-
|
|
43
|
-
## Typed protocol form
|
|
44
|
-
|
|
45
|
-
Application contracts export protocol objects, not alias strings or already context-bound
|
|
46
|
-
entrypoints. A protocol owns the route, request/response contract, guards, gate and sticky flag; it
|
|
47
|
-
is frozen and never mutated by either runtime.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { contract, openProtocol, protocol, protocols, schema, typed } from '@owlmeans/entrypoint'
|
|
51
|
-
import { frontend, route, RouteMethod } from '@owlmeans/route'
|
|
52
|
-
|
|
53
|
-
const ItemParamsSchema = schema<{ id: string }>({
|
|
54
|
-
type: 'object', properties: { id: { type: 'string' } }, required: ['id'], additionalProperties: false,
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const apiBase = protocol(route('api:item', '/items'), contract())
|
|
58
|
-
export const item = {
|
|
59
|
-
base: apiBase,
|
|
60
|
-
get: protocol(
|
|
61
|
-
route('api:item:get', '/:id', { parent: apiBase, method: RouteMethod.GET }),
|
|
62
|
-
contract.request({ params: ItemParamsSchema }, typed<Item>()),
|
|
63
|
-
),
|
|
64
|
-
}
|
|
65
|
-
export const web = {
|
|
66
|
-
items: openProtocol(route('web:items', '/items', frontend())),
|
|
67
|
-
}
|
|
68
|
-
export const itemEntrypoints = protocols(item)
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
`contract()` means no payload and an `undefined` reply. With one source it declares only the
|
|
72
|
-
response; with two it declares body then response. Use `contract.request` when params, query,
|
|
73
|
-
headers or several request sections participate. `schema<T>` is the preferred source when runtime
|
|
74
|
-
validation exists; `typed<T>()` is only the compile-time half.
|
|
75
|
-
|
|
76
|
-
`context.entrypoint(protocolOrRef)` infers the exact registered `call`/`invoke`/`url` signature.
|
|
77
|
-
Use the protocol object inside an application. Use `entrypointRef` only in an adapter package that
|
|
78
|
-
must address a dynamically registered surface without importing its declaration tree.
|
|
79
|
-
|
|
80
|
-
`guard`, `gate` and `filter` are **options-object combinators, not variadic composers**. Each
|
|
81
|
-
returns a `CommonEntrypointOptions` and takes the next one as its final argument, so they nest:
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
entrypoint(
|
|
85
|
-
route(app.api.item.remove, '/:id', { parent: app.api.item, method: RouteMethod.DELETE }),
|
|
86
|
-
guard(DEFAULT_GUARD, gate(OIDC_GATE, ['item--delete@id']))
|
|
87
|
-
)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
Guards and gates are **inherited by child entrypoints** and enforced by the framework before a
|
|
91
|
-
handler runs — a handler that re-checks them is duplicating an enforced rule, and is wrong even
|
|
92
|
-
when it agrees.
|
|
93
|
-
|
|
94
|
-
`sticky: true` in the options exempts a frontend entrypoint from the **service** filter the client
|
|
95
|
-
router applies while building its entrypoint tree: without it, only entrypoints that name no service
|
|
96
|
-
or name the context's own service are attached, so a route belonging to another service (an
|
|
97
|
-
authentication dispatcher, say) needs it to reach the router at all. It changes nothing else — not
|
|
98
|
-
the frontend-only restriction, not route matching — and defaults to `false`.
|
|
99
|
-
|
|
100
|
-
## Subpath Exports
|
|
101
|
-
|
|
102
|
-
- `./utils` — entrypoint construction helpers (`isEntrypoint`, `CreateEntrypointSignature`)
|
|
103
|
-
|
|
104
|
-
## Declaration and model
|
|
105
|
-
|
|
106
|
-
The `RouteDeclaration` an entrypoint carries is plain, immutable data: its `path` is the **segment**
|
|
107
|
-
this entrypoint contributes under its parent, and nothing rewrites it. `RouteModel` only wraps that
|
|
108
|
-
declaration. Every address question is therefore a question about the declaration asked **against
|
|
109
|
-
the context that asks it** — computed on demand, never stored — so the same declaration answers one
|
|
110
|
-
way in a server and another in a client without being touched.
|
|
111
|
-
|
|
112
|
-
| Accessor | Answers |
|
|
113
|
-
|----------|---------|
|
|
114
|
-
| `segment()` | The segment declared under the parent |
|
|
115
|
-
| `path()` | Every ancestor's segment, then this one |
|
|
116
|
-
| `mount()` | `base` + `path()` — what a server registers and a client requests |
|
|
117
|
-
| `service()` | The resolved service route this entrypoint answers on |
|
|
118
|
-
| `address()` | `{ host, port, base, secure, protocol }` — where it actually answers |
|
|
119
|
-
| `isLocal()` | Does it belong to the service the asking context IS? |
|
|
120
|
-
| `parent()` | The parent entrypoint, or `null` |
|
|
121
|
-
| `getGuards()` | Own guards plus every ancestor's, deduped |
|
|
122
|
-
| `getGates()` | Own gate plus every ancestor's, as `[gate, params]` |
|
|
123
|
-
|
|
124
|
-
`getGuards()` and `getGates()` walk the chain afresh on every call and are never memoised: a guard
|
|
125
|
-
attached to an ancestor after this entrypoint was first asked still has to count.
|
|
126
|
-
|
|
127
|
-
## What a handler receives
|
|
128
11
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
`entity.slug` is the renameable name a person reads, and `entity.iamKey` is the frozen identifier
|
|
133
|
-
external systems already know the organization under. It is absent when no resolver is registered,
|
|
134
|
-
so read it defensively rather than assuming it.
|
|
12
|
+
An entrypoint protocol is the immutable shared contract for one addressable route. It owns the
|
|
13
|
+
route, typed request sections, response type, schemas, guards, gate, and sticky flag. Server and
|
|
14
|
+
client behaviour is added only by the corresponding binding package.
|
|
135
15
|
|
|
136
|
-
|
|
137
|
-
single round trip.
|
|
16
|
+
## Declare a named tree
|
|
138
17
|
|
|
139
|
-
|
|
18
|
+
```ts
|
|
19
|
+
import { contract, protocol, typed } from '@owlmeans/entrypoint'
|
|
20
|
+
import { backend, route, RouteMethod } from '@owlmeans/route'
|
|
140
21
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
22
|
+
export const projectEntrypoints = {
|
|
23
|
+
base: protocol(route('project', '/projects', backend()), contract(typed<void>())),
|
|
24
|
+
create: protocol(
|
|
25
|
+
route('project:create', '/', backend('project', RouteMethod.POST)),
|
|
26
|
+
contract.request({ body: typed<CreateProject>(CreateProjectSchema) }, typed<Project>()),
|
|
27
|
+
{ guards: DEFAULT_GUARD }
|
|
28
|
+
),
|
|
29
|
+
get: protocol(
|
|
30
|
+
route('project:get', '/:id', backend('project')),
|
|
31
|
+
contract.request({ params: typed<{ id: string }>() }, typed<Project>())
|
|
32
|
+
),
|
|
33
|
+
}
|
|
147
34
|
```
|
|
148
35
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
`
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
36
|
+
- Export an object whose property names describe the contract. Its protocol values are the only
|
|
37
|
+
cross-layer references. Flatten it with `protocols(projectEntrypoints)` only at registration.
|
|
38
|
+
- Use `protocol(route, contract, options?)` for every typed boundary.
|
|
39
|
+
- `openProtocol(route, options?)` is an intentional untyped escape hatch; do not use it merely to
|
|
40
|
+
avoid declaring an input or output type.
|
|
41
|
+
- Use `decorateEntrypoint(protocol, options)` only when deriving an immutable decoration; never
|
|
42
|
+
mutate guards, gates, schemas, or a declaration collection.
|
|
43
|
+
|
|
44
|
+
## Contract sources
|
|
45
|
+
|
|
46
|
+
| Source | Use |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `typed<Model>(schema)` | A type paired with its AJV runtime validator. Prefer at declaration boundaries. |
|
|
49
|
+
| `typed<Model>()` | A type-only request section or response. |
|
|
50
|
+
| `schema<Model>(schema)` | A reusable named typed AJV schema. |
|
|
51
|
+
| `contract(body, response)` | A body-only contract. |
|
|
52
|
+
| `contract.request({ body, params, query, headers }, response)` | Independently typed request sections. |
|
|
53
|
+
|
|
54
|
+
Use `typed<Model>(schema)` rather than a bare `JSONSchemaType<Model>` when the model must remain
|
|
55
|
+
exact. A bare AJV generic can widen a protocol section to `OpenValue`.
|
|
56
|
+
|
|
57
|
+
`RequestOf<Protocol>`, `ResponseOf<Protocol>`, `BodyOf<Protocol>`, `ParamsOf<Protocol>`,
|
|
58
|
+
`QueryOf<Protocol>`, and `HeadersOf<Protocol>` derive the contract types. A handler receives
|
|
59
|
+
`HandlerRequest<RequestOf<Protocol>>`, which includes the transport metadata as well as the typed
|
|
60
|
+
sections. Use `entrypointRef<Request, Response>(alias)` only for a dynamic remote address whose
|
|
61
|
+
declaration is unavailable to import.
|
|
62
|
+
|
|
63
|
+
## Authorization and addressing
|
|
64
|
+
|
|
65
|
+
Add `guards`, `gate`, and `sticky` directly in `EntrypointOptions`:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
protocol(route(...), contract(...), {
|
|
69
|
+
guards: [DEFAULT_GUARD, AUDIT_GUARD],
|
|
70
|
+
gate: { alias: PROJECT_GATE, params: ['project--read@id'] },
|
|
71
|
+
sticky: true,
|
|
72
|
+
})
|
|
183
73
|
```
|
|
184
74
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
the route rather than at the call.
|
|
189
|
-
|
|
190
|
-
## Legacy declaration form
|
|
191
|
-
|
|
192
|
-
Existing applications may define entrypoints in a shared `common` package, then `elevate()` them
|
|
193
|
-
with handlers in server/web packages. Do not introduce this form into a protocol-based surface.
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
import { entrypoint, guard, gate, filter, body } from '@owlmeans/entrypoint'
|
|
197
|
-
import { route, RouteMethod } from '@owlmeans/route'
|
|
198
|
-
import { DEFAULT_GUARD } from '@owlmeans/auth-common'
|
|
199
|
-
import { OIDC_GATE } from '@owlmeans/oidc'
|
|
200
|
-
import { CreateProjectSchema } from './schemas.js'
|
|
201
|
-
|
|
202
|
-
export const managerEntrypoints = [
|
|
203
|
-
entrypoint(
|
|
204
|
-
route(manager.back.account.base, '/account'),
|
|
205
|
-
guard(DEFAULT_GUARD, gate(OIDC_GATE, [`my-service-account-{entity}`]))
|
|
206
|
-
),
|
|
207
|
-
entrypoint(
|
|
208
|
-
route(manager.back.project.create, '/create', {
|
|
209
|
-
parent: manager.back.project.base,
|
|
210
|
-
method: RouteMethod.POST,
|
|
211
|
-
}),
|
|
212
|
-
filter(body(CreateProjectSchema))
|
|
213
|
-
),
|
|
214
|
-
]
|
|
215
|
-
```
|
|
75
|
+
Guards and gates are inherited through the parent route by the bound runtime entrypoint. A route's
|
|
76
|
+
protocol chooses the carrier (HTTP, socket, or queue); callers only use `call`, `invoke`, or `url`
|
|
77
|
+
on the client-bound protocol and do not branch on a transport.
|
|
216
78
|
|
|
217
|
-
##
|
|
79
|
+
## Bind, never replace
|
|
218
80
|
|
|
219
|
-
-
|
|
220
|
-
|
|
221
|
-
-
|
|
222
|
-
-
|
|
81
|
+
- Server: `bind(protocol, handlers<Context>().body|params|request(...))` from
|
|
82
|
+
`@owlmeans/server-entrypoint` / `@owlmeans/server-api`.
|
|
83
|
+
- Socket: `bind(protocol, connection(protocol, handler))`.
|
|
84
|
+
- Client API route: `bind(protocol)` or `bindAll(tree)` from `@owlmeans/client-entrypoint`.
|
|
85
|
+
- Client screen: `bindScreen(protocol, componentHandler)`.
|
|
223
86
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
any dependency on the auth stack.
|
|
87
|
+
Do not construct contextual compatibility entrypoints, look a protocol up by alias with a generic,
|
|
88
|
+
or replace an item in an entrypoint array. Import the declaration and bind that exact object. This
|
|
89
|
+
keeps declarations immutable and lets TypeScript infer requests and replies end to end.
|
package/build/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export type * from './types.js';
|
|
2
|
-
export * from './entrypoint.js';
|
|
3
|
-
export * from './filter.js';
|
|
4
|
-
export * from './helper.js';
|
|
5
2
|
export * from './consts.js';
|
|
6
3
|
export * from './protocol.js';
|
|
7
4
|
export * from './materialize.js';
|
|
5
|
+
export { provideResponse } from './helper.js';
|
|
8
6
|
//# sourceMappingURL=index.d.ts.map
|
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,
|
|
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,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
export * from './entrypoint.js';
|
|
2
|
-
export * from './filter.js';
|
|
3
|
-
export * from './helper.js';
|
|
4
1
|
export * from './consts.js';
|
|
5
2
|
export * from './protocol.js';
|
|
6
3
|
export * from './materialize.js';
|
|
4
|
+
export { provideResponse } from './helper.js';
|
|
7
5
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA"}
|
package/build/materialize.js
CHANGED
|
@@ -9,14 +9,14 @@ const filterOf = (protocol) => {
|
|
|
9
9
|
params: request?.params == null ? undefined : structuredClone(request.params),
|
|
10
10
|
query: request?.query == null ? undefined : structuredClone(request.query),
|
|
11
11
|
headers: request?.headers == null ? undefined : structuredClone(request.headers),
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
// Fastify requires response serializers to be keyed by a status code. A protocol's
|
|
13
|
+
// ordinary response has no explicit outcome, so it is the normal successful 200 reply.
|
|
14
|
+
response: response == null ? undefined : {
|
|
15
|
+
...(response.default == null ? {} : { 200: structuredClone(response.default) }),
|
|
16
|
+
...Object.fromEntries(Object.entries(response.byStatus ?? {}).map(([status, schema]) => [
|
|
17
|
+
status, structuredClone(schema),
|
|
18
|
+
])),
|
|
19
|
+
},
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
const optionsOf = (protocol) => ({
|
|
@@ -30,5 +30,5 @@ const optionsOf = (protocol) => ({
|
|
|
30
30
|
* Make a local, mutable registration from a shared declaration. The protocol is never mutated;
|
|
31
31
|
* guards, route resolution and handlers belong exclusively to this materialized entrypoint.
|
|
32
32
|
*/
|
|
33
|
-
export const materializeEntrypoint = (protocol) => Object.assign(entrypoint(protocol.route, optionsOf(protocol)), { protocol });
|
|
33
|
+
export const materializeEntrypoint = (protocol) => Object.assign(entrypoint({ route: { ...protocol.route.route } }, optionsOf(protocol)), { protocol });
|
|
34
34
|
//# sourceMappingURL=materialize.js.map
|
package/build/materialize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialize.js","sourceRoot":"","sources":["../src/materialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAS5C,MAAM,QAAQ,GAAG,CAAC,QAAuC,EAAsB,EAAE;IAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAEnD,IAAI,OAAO,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IAEzD,OAAO;QACL,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;QACvE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC;QAC7E,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1E,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;QAChF,
|
|
1
|
+
{"version":3,"file":"materialize.js","sourceRoot":"","sources":["../src/materialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAS5C,MAAM,QAAQ,GAAG,CAAC,QAAuC,EAAsB,EAAE;IAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAEnD,IAAI,OAAO,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IAEzD,OAAO;QACL,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;QACvE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC;QAC7E,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1E,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC;QAChF,mFAAmF;QACnF,uFAAuF;QACvF,QAAQ,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACvC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/E,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;gBACtF,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC;aAChC,CAAC,CAAC;SACJ;KACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,QAAuC,EAA2B,EAAE,CAAC,CAAC;IACvF,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,MAAM,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK;IAC1B,UAAU,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IACzE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAC3B,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,QAAkB,EACgB,EAAE,CAAC,MAAM,CAAC,MAAM,CAClD,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,EACvE,EAAE,QAAQ,EAAE,CACb,CAAA"}
|
package/build/protocol.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { JSONSchemaType, AnySchemaObject } from 'ajv';
|
|
|
4
4
|
import type { RouteModel } from '@owlmeans/route';
|
|
5
5
|
import type { EntrypointOutcome } from './consts.js';
|
|
6
6
|
import type { ResolvedEntity } from './types.js';
|
|
7
|
+
import type { AbstractRequest } from './types.js';
|
|
7
8
|
/** A deliberately broad value used only by declarations without an I/O contract. */
|
|
8
9
|
export type OpenValue = object | string | number | boolean | bigint | null | undefined;
|
|
9
10
|
/** The request accepted by a declaration that intentionally supplies no contract. */
|
|
@@ -92,6 +93,11 @@ export interface EntrypointProtocolDeclaration {
|
|
|
92
93
|
readonly params: readonly string[];
|
|
93
94
|
};
|
|
94
95
|
}
|
|
96
|
+
/** An access gate declared by a protocol, including inherited parent declarations. */
|
|
97
|
+
export interface EntrypointGate {
|
|
98
|
+
readonly alias: string;
|
|
99
|
+
readonly params: readonly string[];
|
|
100
|
+
}
|
|
95
101
|
type SourceValue<Source> = Source extends Typed<infer Value> ? Value : Source extends EntrypointSchema<infer Value> ? Value : Source extends JSONSchemaType<infer Value> ? Value extends OpenValue ? Value : OpenValue : OpenValue;
|
|
96
102
|
type RequestFromSources<Sources extends RequestSources> = (Sources extends {
|
|
97
103
|
body: infer Source;
|
|
@@ -161,7 +167,13 @@ export interface EntrypointRequestMeta {
|
|
|
161
167
|
canceled?: boolean;
|
|
162
168
|
cancel?: () => void;
|
|
163
169
|
}
|
|
164
|
-
|
|
170
|
+
/**
|
|
171
|
+
* A protocol request at an implementation boundary.
|
|
172
|
+
*
|
|
173
|
+
* Transport metadata and empty request sections remain available to handlers; a declared section
|
|
174
|
+
* then refines that base shape to its protocol contract.
|
|
175
|
+
*/
|
|
176
|
+
export type HandlerRequest<Request extends RequestShape> = AbstractRequest & Request & EntrypointRequestMeta;
|
|
165
177
|
/** The context-bound counterpart of an immutable protocol declaration. */
|
|
166
178
|
export interface RegisteredEntrypoint<Request extends RequestShape, Response> extends BasicEntrypoint {
|
|
167
179
|
readonly protocol: EntrypointProtocol<Request, Response>;
|
|
@@ -192,7 +204,7 @@ export type HeadersOf<Protocol extends EntrypointProtocolDeclaration> = RequestO
|
|
|
192
204
|
headers: infer Headers;
|
|
193
205
|
} ? Headers : object;
|
|
194
206
|
export type CallRequestOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> & CallOptions;
|
|
195
|
-
/** Create
|
|
207
|
+
/** Create an immutable protocol declaration from a route and its contract. */
|
|
196
208
|
export declare const protocol: <Request extends RequestShape, Response>(route: RouteModel, entrypointContract: EntrypointContract<Request, Response>, options?: EntrypointOptions) => EntrypointProtocol<Request, Response>;
|
|
197
209
|
export declare const openProtocol: (route: RouteModel, options?: EntrypointOptions) => EntrypointProtocol<OpenRequest, OpenValue>;
|
|
198
210
|
export declare const entrypointRef: <Request extends RequestShape = OpenRequest, Response = OpenValue>(alias: string) => EntrypointReference<RegisteredEntrypoint<Request, Response>>;
|
|
@@ -203,6 +215,8 @@ export interface EntrypointTree {
|
|
|
203
215
|
}
|
|
204
216
|
/** Flatten an exported protocol tree for a layer-specific materializer. */
|
|
205
217
|
export declare const protocols: (tree: EntrypointTree) => EntrypointProtocolDeclaration[];
|
|
218
|
+
/** Resolve the gates a protocol inherits through its route parents without materializing it. */
|
|
219
|
+
export declare const gatesOf: (protocol: EntrypointProtocolDeclaration, tree: EntrypointTree) => readonly EntrypointGate[];
|
|
206
220
|
/** Clone an immutable protocol while preserving its request/response pair. */
|
|
207
221
|
export declare const decorateEntrypoint: <Protocol extends EntrypointProtocolDeclaration>(protocol: Protocol, options: EntrypointOptions) => Protocol;
|
|
208
222
|
export {};
|
package/build/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
|
package/build/protocol.js
CHANGED
|
@@ -49,7 +49,7 @@ const gateOf = (gate) => gate == null
|
|
|
49
49
|
alias: gate.alias,
|
|
50
50
|
params: gate.params == null ? [] : typeof gate.params === 'string' ? [gate.params] : [...gate.params],
|
|
51
51
|
};
|
|
52
|
-
/** Create
|
|
52
|
+
/** Create an immutable protocol declaration from a route and its contract. */
|
|
53
53
|
export const protocol = (route, entrypointContract, options) => Object.freeze({
|
|
54
54
|
kind: 'entrypoint-protocol',
|
|
55
55
|
alias: route.route.alias,
|
|
@@ -86,6 +86,23 @@ export const protocols = (tree) => {
|
|
|
86
86
|
visit(tree);
|
|
87
87
|
return result;
|
|
88
88
|
};
|
|
89
|
+
/** Resolve the gates a protocol inherits through its route parents without materializing it. */
|
|
90
|
+
export const gatesOf = (protocol, tree) => {
|
|
91
|
+
const byAlias = new Map(protocols(tree).map(candidate => [candidate.alias, candidate]));
|
|
92
|
+
const result = [];
|
|
93
|
+
const visited = new Set();
|
|
94
|
+
let current = protocol;
|
|
95
|
+
while (current != null && !visited.has(current.alias)) {
|
|
96
|
+
visited.add(current.alias);
|
|
97
|
+
if (current.gate != null && !result.some(gate => gate.alias === current.gate.alias)) {
|
|
98
|
+
result.push(current.gate);
|
|
99
|
+
}
|
|
100
|
+
current = current.route.route.parent == null
|
|
101
|
+
? undefined
|
|
102
|
+
: byAlias.get(current.route.route.parent);
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
};
|
|
89
106
|
/** Clone an immutable protocol while preserving its request/response pair. */
|
|
90
107
|
export const decorateEntrypoint = (protocol, options) => Object.freeze({
|
|
91
108
|
...protocol,
|
package/build/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAuDA,MAAM,CAAC,MAAM,MAAM,GAAG,CAAI,KAAwB,EAAuB,EAAE,CACzE,KAA4B,CAAA;AAa9B,MAAM,UAAU,KAAK,CAAI,MAA0B;IACjD,OAAO,MAAM,IAAI,IAAI;QACnB,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE;QAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAA;AACzC,CAAC;AAgED,MAAM,QAAQ,GAAG,CAAC,MAAkC,EAA+B,EAAE;IACnF,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,MAAM,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAClE,CAAC,CAAC,MAAM,CAAC,MAAM;QACf,CAAC,CAAC,MAAM,CAAA;IAEV,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;AAC7D,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CAAC,MAAkC,EAAsC,EAAE;IACnG,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC/B,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;AACzD,CAAC,CAAA;AAWD,MAAM,UAAU,QAAQ,CACtB,KAAsB,EAAE,MAAuB;IAE/C,MAAM,IAAI,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA;IAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,KAAK,CAAA;IAEhC,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE;QACxC,eAAe,EAAE,iBAAiB,CAAC,QAAQ,CAAC;KAC7C,CAAA;AACH,CAAC;AAED,WAAiB,QAAQ;IACvB,SAAgB,OAAO,CACrB,OAAgB,EAChB,QAA+B;QAE/B,OAAO;YACL,IAAI,EAAE,qBAAqB;YAC3B,cAAc,EAAE;gBACd,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;gBAC5B,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;gBAChC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;gBAC9B,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;aACnC;YACD,eAAe,EAAE,iBAAiB,CAAC,QAAQ,CAAC;SAC7C,CAAA;IACH,CAAC;IAde,SAAA,OAAO,UActB,CAAA;AACH,CAAC,EAhBgB,QAAQ,KAAR,QAAQ,QAgBxB;AA6FD,MAAM,QAAQ,GAAG,CAAC,MAAmC,EAAqB,EAAE,CAAC,MAAM,IAAI,IAAI;IACzF,CAAC,CAAC,EAAE;IACJ,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;AAEvD,MAAM,MAAM,GAAG,CAAC,IAA+B,EAA8B,EAAE,CAAC,IAAI,IAAI,IAAI;IAC1F,CAAC,CAAC,SAAS;IACX,CAAC,CAAC;QACE,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;KACtG,CAAA;AAEL,8EAA8E;AAC9E,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,KAAiB,EACjB,kBAAyD,EACzD,OAA2B,EACY,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IACxD,IAAI,EAAE,qBAA8B;IACpC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;IAClE,QAAQ,EAAE,kBAAkB;IAC5B,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;CAC5B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAiB,EACjB,OAA2B,EACiB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IAC7D,IAAI,EAAE,qBAA8B;IACpC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;IAClE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;CAC5B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,KAAa,EACiD,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AAE9E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,SAAuC,EAAU,EAAE,CACzE,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAA;AAE7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAA0C,EAAE,CAC5F,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,CAAA;AAMzD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAoB,EAAmC,EAAE;IACjF,MAAM,MAAM,GAAoC,EAAE,CAAA;IAElD,MAAM,KAAK,GAAG,CAAC,IAAoB,EAAQ,EAAE;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACpB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,CAAA;YACd,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,KAAK,CAAC,IAAI,CAAC,CAAA;IACX,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,gGAAgG;AAChG,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,QAAuC,EACvC,IAAoB,EACO,EAAE;IAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvF,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,IAAI,OAAO,GAA8C,QAAQ,CAAA;IAEjE,OAAO,OAAO,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,OAAQ,CAAC,IAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtF,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI;YAC1C,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,QAAkB,EAClB,OAA0B,EAChB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3B,GAAG,QAAQ;IACX,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;IACzC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;IAC3E,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;CAClE,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/entrypoint",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.15",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
32
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
33
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
31
|
+
"@owlmeans/auth": "^0.1.18-rc.13",
|
|
32
|
+
"@owlmeans/context": "^0.1.18-rc.12",
|
|
33
|
+
"@owlmeans/route": "^0.1.18-rc.13",
|
|
34
34
|
"ajv": "^8.17.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
export type * from './types.js'
|
|
3
|
-
export * from './entrypoint.js'
|
|
4
|
-
export * from './filter.js'
|
|
5
|
-
export * from './helper.js'
|
|
6
3
|
export * from './consts.js'
|
|
7
4
|
export * from './protocol.js'
|
|
8
5
|
export * from './materialize.js'
|
|
6
|
+
export { provideResponse } from './helper.js'
|
package/src/materialize.ts
CHANGED
|
@@ -18,13 +18,13 @@ const filterOf = (protocol: EntrypointProtocolDeclaration): Filter | undefined =
|
|
|
18
18
|
params: request?.params == null ? undefined : structuredClone(request.params),
|
|
19
19
|
query: request?.query == null ? undefined : structuredClone(request.query),
|
|
20
20
|
headers: request?.headers == null ? undefined : structuredClone(request.headers),
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
// Fastify requires response serializers to be keyed by a status code. A protocol's
|
|
22
|
+
// ordinary response has no explicit outcome, so it is the normal successful 200 reply.
|
|
23
|
+
response: response == null ? undefined : {
|
|
24
|
+
...(response.default == null ? {} : { 200: structuredClone(response.default) }),
|
|
25
|
+
...Object.fromEntries(Object.entries(response.byStatus ?? {}).map(([status, schema]) => [
|
|
26
|
+
status, structuredClone(schema),
|
|
27
|
+
])),
|
|
28
28
|
},
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -44,6 +44,6 @@ const optionsOf = (protocol: EntrypointProtocolDeclaration): CommonEntrypointOpt
|
|
|
44
44
|
export const materializeEntrypoint = <Protocol extends EntrypointProtocolDeclaration>(
|
|
45
45
|
protocol: Protocol,
|
|
46
46
|
): MaterializedEntrypoint<Protocol> => Object.assign(
|
|
47
|
-
entrypoint(protocol.route, optionsOf(protocol)),
|
|
47
|
+
entrypoint({ route: { ...protocol.route.route } }, optionsOf(protocol)),
|
|
48
48
|
{ protocol },
|
|
49
49
|
)
|
package/src/protocol.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { JSONSchemaType, AnySchemaObject } from 'ajv'
|
|
|
4
4
|
import type { RouteModel } from '@owlmeans/route'
|
|
5
5
|
import type { EntrypointOutcome } from './consts.js'
|
|
6
6
|
import type { ResolvedEntity } from './types.js'
|
|
7
|
+
import type { AbstractRequest } from './types.js'
|
|
7
8
|
|
|
8
9
|
/** A deliberately broad value used only by declarations without an I/O contract. */
|
|
9
10
|
export type OpenValue = object | string | number | boolean | bigint | null | undefined
|
|
@@ -115,6 +116,12 @@ export interface EntrypointProtocolDeclaration {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
/** An access gate declared by a protocol, including inherited parent declarations. */
|
|
120
|
+
export interface EntrypointGate {
|
|
121
|
+
readonly alias: string
|
|
122
|
+
readonly params: readonly string[]
|
|
123
|
+
}
|
|
124
|
+
|
|
118
125
|
type SourceValue<Source> =
|
|
119
126
|
Source extends Typed<infer Value> ? Value
|
|
120
127
|
: Source extends EntrypointSchema<infer Value> ? Value
|
|
@@ -219,7 +226,13 @@ export interface EntrypointRequestMeta {
|
|
|
219
226
|
cancel?: () => void
|
|
220
227
|
}
|
|
221
228
|
|
|
222
|
-
|
|
229
|
+
/**
|
|
230
|
+
* A protocol request at an implementation boundary.
|
|
231
|
+
*
|
|
232
|
+
* Transport metadata and empty request sections remain available to handlers; a declared section
|
|
233
|
+
* then refines that base shape to its protocol contract.
|
|
234
|
+
*/
|
|
235
|
+
export type HandlerRequest<Request extends RequestShape> = AbstractRequest & Request & EntrypointRequestMeta
|
|
223
236
|
|
|
224
237
|
/** The context-bound counterpart of an immutable protocol declaration. */
|
|
225
238
|
export interface RegisteredEntrypoint<Request extends RequestShape, Response> extends BasicEntrypoint {
|
|
@@ -278,7 +291,7 @@ const gateOf = (gate: EntrypointOptions['gate']): EntrypointProtocol['gate'] =>
|
|
|
278
291
|
params: gate.params == null ? [] : typeof gate.params === 'string' ? [gate.params] : [...gate.params],
|
|
279
292
|
}
|
|
280
293
|
|
|
281
|
-
/** Create
|
|
294
|
+
/** Create an immutable protocol declaration from a route and its contract. */
|
|
282
295
|
export const protocol = <Request extends RequestShape, Response>(
|
|
283
296
|
route: RouteModel,
|
|
284
297
|
entrypointContract: EntrypointContract<Request, Response>,
|
|
@@ -337,6 +350,29 @@ export const protocols = (tree: EntrypointTree): EntrypointProtocolDeclaration[]
|
|
|
337
350
|
return result
|
|
338
351
|
}
|
|
339
352
|
|
|
353
|
+
/** Resolve the gates a protocol inherits through its route parents without materializing it. */
|
|
354
|
+
export const gatesOf = (
|
|
355
|
+
protocol: EntrypointProtocolDeclaration,
|
|
356
|
+
tree: EntrypointTree,
|
|
357
|
+
): readonly EntrypointGate[] => {
|
|
358
|
+
const byAlias = new Map(protocols(tree).map(candidate => [candidate.alias, candidate]))
|
|
359
|
+
const result: EntrypointGate[] = []
|
|
360
|
+
const visited = new Set<string>()
|
|
361
|
+
let current: EntrypointProtocolDeclaration | undefined = protocol
|
|
362
|
+
|
|
363
|
+
while (current != null && !visited.has(current.alias)) {
|
|
364
|
+
visited.add(current.alias)
|
|
365
|
+
if (current.gate != null && !result.some(gate => gate.alias === current!.gate!.alias)) {
|
|
366
|
+
result.push(current.gate)
|
|
367
|
+
}
|
|
368
|
+
current = current.route.route.parent == null
|
|
369
|
+
? undefined
|
|
370
|
+
: byAlias.get(current.route.route.parent)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return result
|
|
374
|
+
}
|
|
375
|
+
|
|
340
376
|
/** Clone an immutable protocol while preserving its request/response pair. */
|
|
341
377
|
export const decorateEntrypoint = <Protocol extends EntrypointProtocolDeclaration>(
|
|
342
378
|
protocol: Protocol,
|