@owlmeans/client-entrypoint 0.1.18-rc.15 → 0.1.18-rc.16
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 +30 -25
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/client-entrypoint/SKILL.md +21 -130
- package/build/entrypoint.d.ts +2 -3
- package/build/entrypoint.d.ts.map +1 -1
- package/build/entrypoint.js +14 -29
- package/build/entrypoint.js.map +1 -1
- package/build/helper.d.ts +2 -10
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +0 -18
- package/build/helper.js.map +1 -1
- package/build/index.d.ts +1 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -2
- package/build/index.js.map +1 -1
- package/build/protocol.d.ts.map +1 -1
- package/build/protocol.js +3 -3
- package/build/protocol.js.map +1 -1
- package/build/utils/entrypoint.d.ts +2 -4
- package/build/utils/entrypoint.d.ts.map +1 -1
- package/build/utils/entrypoint.js +0 -9
- package/build/utils/entrypoint.js.map +1 -1
- package/package.json +10 -10
- package/src/entrypoint.ts +18 -34
- package/src/helper.ts +2 -29
- package/src/index.ts +1 -2
- package/src/protocol.ts +4 -3
- package/src/utils/entrypoint.ts +2 -17
package/README.md
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# @owlmeans/client-entrypoint
|
|
2
2
|
|
|
3
|
-
Client-side entrypoint system:
|
|
3
|
+
Client-side entrypoint system: binds shared protocol declarations into API-calling client views.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
|
|
7
|
+
- `bind(protocol, opts?)` — binds one shared protocol declaration
|
|
8
|
+
- `bindAll(protocolTree)` — binds every protocol in a shared declaration tree
|
|
9
|
+
- `bindScreen(protocol, handler, opts?)` — binds a screen renderer to a shared frontend protocol
|
|
10
|
+
- `ClientProtocolEntrypoint<Protocol>` exposes three explicit verbs: `call()` for the value,
|
|
11
|
+
`invoke()` for the value plus its outcome, and `url()` for the address
|
|
10
12
|
- `stab` — no-op handler for entrypoints that only need a URL (no logic)
|
|
11
13
|
- `provideRequest(alias, path)` — creates an `AbstractRequest` for programmatic entrypoint calls
|
|
12
14
|
- `pickPerSchema(schema, obj)` — extracts fields from an object matching an AJV schema
|
|
13
|
-
- Re-exported as `celevate` from `@owlmeans/server-app`
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -20,28 +21,25 @@ bun add @owlmeans/client-entrypoint@^0.1.18-rc.12
|
|
|
20
21
|
|
|
21
22
|
## Usage
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Bind shared protocols for browser API calls and screens:
|
|
24
25
|
|
|
25
26
|
```typescript
|
|
26
|
-
import {
|
|
27
|
-
import
|
|
27
|
+
import { bindAll, bindScreen, stab } from '@owlmeans/client-entrypoint'
|
|
28
|
+
import { appEntrypoints as protocols } from 'my-app-common'
|
|
29
|
+
import { handler } from '@owlmeans/client'
|
|
30
|
+
import { ProjectListScreen } from './screens/project-list.js'
|
|
28
31
|
|
|
29
32
|
const appEntrypoints = [
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
...bindAll(protocols.api),
|
|
34
|
+
bindScreen(protocols.web.projectList, handler(ProjectListScreen)),
|
|
35
|
+
bindScreen(protocols.web.project, stab),
|
|
32
36
|
]
|
|
33
|
-
|
|
34
|
-
// Frontend navigation — a screen, addressed with url(); call()/invoke() throw on it
|
|
35
|
-
elevate(appEntrypoints, 'project-list', stab)
|
|
36
|
-
|
|
37
|
-
// Backend API call — call() makes a POST request
|
|
38
|
-
elevate(appEntrypoints, 'project-create')
|
|
39
37
|
```
|
|
40
38
|
|
|
41
39
|
Call an entrypoint from a service:
|
|
42
40
|
|
|
43
41
|
```typescript
|
|
44
|
-
const agentEntrypoint = ctx.entrypoint
|
|
42
|
+
const agentEntrypoint = ctx.entrypoint(agent.project.create)
|
|
45
43
|
const result = await agentEntrypoint.call({
|
|
46
44
|
body: { prompt: payload.prompt, entity: req.auth?.entitySlug }
|
|
47
45
|
})
|
|
@@ -52,21 +50,29 @@ Take the outcome when it decides what happens next, and build a link with `url()
|
|
|
52
50
|
```typescript
|
|
53
51
|
const { value, outcome } = await agentEntrypoint.invoke({ body: payload })
|
|
54
52
|
|
|
55
|
-
const href = await ctx.entrypoint
|
|
53
|
+
const href = await ctx.entrypoint(protocols.web.projectList)
|
|
56
54
|
.url({ params: { id: value.id } }, { absolute: true })
|
|
57
55
|
```
|
|
58
56
|
|
|
59
57
|
## API
|
|
60
58
|
|
|
61
|
-
### `
|
|
59
|
+
### `bind<Protocol>(protocol, opts?): ClientProtocolEntrypoint<Protocol>`
|
|
60
|
+
|
|
61
|
+
Materializes one immutable protocol declaration for a browser context. The declaration is never mutated.
|
|
62
|
+
|
|
63
|
+
### `bindAll(protocolTree): ClientProtocolEntrypoint[]`
|
|
64
|
+
|
|
65
|
+
Materializes every protocol in a shared declaration tree, preserving each protocol reference for typed context lookup.
|
|
66
|
+
|
|
67
|
+
### `bindScreen<Protocol>(protocol, handler, opts?): ClientProtocolEntrypoint<Protocol>`
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
Materializes a frontend protocol and attaches its renderer.
|
|
64
70
|
|
|
65
71
|
### `stab: RefedEntrypointHandler`
|
|
66
72
|
|
|
67
73
|
No-op handler for frontend-only entrypoints that are addressed by URL rather than called.
|
|
68
74
|
|
|
69
|
-
### `
|
|
75
|
+
### `ClientProtocolEntrypoint<Protocol>` (type)
|
|
70
76
|
|
|
71
77
|
- `call(request?)` — addresses the entrypoint over the wire and resolves to the value, throwing
|
|
72
78
|
whatever error the reply carried
|
|
@@ -98,9 +104,8 @@ The low-level pair the verbs are built on, for code that holds an entrypoint ref
|
|
|
98
104
|
|
|
99
105
|
## Related Packages
|
|
100
106
|
|
|
101
|
-
- [`@owlmeans/entrypoint`](../entrypoint) — `CommonEntrypoint` base that gets
|
|
102
|
-
- [`@owlmeans/client`](../client) — `useNavigate` navigates by `
|
|
103
|
-
- [`@owlmeans/server-app`](../server-app) — re-exports `elevate` as `celevate`
|
|
107
|
+
- [`@owlmeans/entrypoint`](../entrypoint) — `CommonEntrypoint` base that gets materialized
|
|
108
|
+
- [`@owlmeans/client`](../client) — `useNavigate` navigates by a bound protocol's `url()`
|
|
104
109
|
|
|
105
110
|
<!-- owlmeans:agent-guidance:start -->
|
|
106
111
|
## Agent guidance
|
|
@@ -110,7 +115,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
110
115
|
your project's skill store (`.agents/skills/`):
|
|
111
116
|
|
|
112
117
|
```sh
|
|
113
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
118
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.15
|
|
114
119
|
```
|
|
115
120
|
|
|
116
121
|
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/client-entrypoint",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
4
|
+
"version": "0.1.18-rc.16",
|
|
5
|
+
"generatedAt": "2026-09-12T08:39:52.720Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,145 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: client-entrypoint
|
|
3
|
-
description:
|
|
3
|
+
description: Bind shared entrypoint protocols in a client context with typed call(), invoke(), url(), bindAll(), and bindScreen(). Load when wiring client API routes or screens.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
7
|
|
|
8
8
|
# @owlmeans/client-entrypoint
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Bind a declaration from `@owlmeans/entrypoint`; never construct or replace a contextual
|
|
11
|
+
entrypoint by alias.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```ts
|
|
14
|
+
import { bind, bindAll, bindScreen } from '@owlmeans/client-entrypoint'
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| `bindAll(tree)` | Flatten and bind a protocol tree |
|
|
19
|
-
| `bindScreen(protocol, handler, opts?)` | Bind a frontend protocol to its renderer |
|
|
20
|
-
| `ClientProtocolEntrypoint<P>` | The client module whose request/reply types come from `P` |
|
|
21
|
-
| `ClientEntrypoint<T, R>` | Client entrypoint interface — `call`, `invoke`, `url`, `validate`, `request` |
|
|
22
|
-
| `entrypoint(arg, handler?, opts?)` | Build a client entrypoint from a route model or an existing declaration |
|
|
23
|
-
| `elevate(entrypoints, alias, handler?, opts?)` | Make a declared entrypoint client-callable, optionally attaching a screen |
|
|
24
|
-
| `EntrypointCall` / `EntrypointInvoke` / `EntrypointUrl` | The typed signatures of the three verbs |
|
|
25
|
-
| `EntrypointReply<T>` | `{ value, outcome }` — what `invoke` resolves to |
|
|
26
|
-
| `EntrypointRef` / `RefedEntrypointHandler` | Handler reference pattern |
|
|
27
|
-
| `ClientEntrypointOptions` | What `entrypoint`/`elevate` accept — `guards`, `filter`, `gate`, `gateParams`, `routeOptions`, `validateOnCall` |
|
|
28
|
-
| `ClientRequest<T>` / `EntrypointFilter` / `EntrypointUrlOptions` | The request shape, the validator signature, and `{ absolute }` |
|
|
29
|
-
| `provideRequest(alias, path)` / `pickPerSchema(obj, schema)` | Request construction helpers |
|
|
30
|
-
| `stab` | A handler that renders nothing — for an entrypoint that exists only to be addressed |
|
|
31
|
-
| `ClientEntrypointError` / `ClientValidationError` | Typed client-side failures |
|
|
16
|
+
context.registerEntrypoints(bindAll(projectEntrypoints))
|
|
17
|
+
context.registerEntrypoint(bind(projectEntrypoints.health))
|
|
18
|
+
context.registerEntrypoint(bindScreen(projectEntrypoints.home, handler(Home)))
|
|
32
19
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
`validate(ref)`, `normalizeHelperParams(handler?, opts?)`, and the re-exported
|
|
37
|
-
`makeBasicEntrypoint` / `isEntrypoint`
|
|
38
|
-
|
|
39
|
-
## Usage
|
|
40
|
-
|
|
41
|
-
New protocol-based applications bind their shared declarations and let lookup infer the contract:
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
import { bindAll, bindScreen, handler } from '@owlmeans/client-entrypoint'
|
|
45
|
-
import { item, web } from 'project-common'
|
|
46
|
-
|
|
47
|
-
const entrypoints = bindAll(item)
|
|
48
|
-
entrypoints.push(bindScreen(web.items, handler(ItemsScreen)))
|
|
49
|
-
|
|
50
|
-
const result = await context.entrypoint(item.get).call({ params: { id } })
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
`bind`/`bindAll` make backend protocols callable; `bindScreen` is only for frontend protocols.
|
|
54
|
-
The protocol stays immutable and the local module receives its own context and handler state.
|
|
55
|
-
|
|
56
|
-
Most legacy app code uses `elevate()` from `@owlmeans/web-client` (which builds on this). Use the
|
|
57
|
-
legacy generic only while working on a surface that has not migrated:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Client-side callability is an **explicit opt-in**: a declaration only becomes callable from a client
|
|
64
|
-
once `bind`/`bindAll`, or a bare legacy client `elevate` (or `celevate` on the server side), has been
|
|
65
|
-
applied to it. Elevating is
|
|
66
|
-
idempotent, and guards passed at elevation are added to the ones the declaration already carries;
|
|
67
|
-
`filter`, `gate` and `gateParams` passed at elevation replace what was declared. An alias no
|
|
68
|
-
entrypoint in the list carries throws `SyntaxError`.
|
|
69
|
-
|
|
70
|
-
Both `entrypoint()` and `elevate()` accept the options in the handler slot when there is no handler,
|
|
71
|
-
and a bare boolean where the options go means `{ validateOnCall }`. With `validateOnCall`, every call is
|
|
72
|
-
checked against the declaration's `filter` (ajv, with formats) before it leaves, and a mismatch
|
|
73
|
-
throws `ClientValidationError` naming the offending path. A **backend** entrypoint given a handler
|
|
74
|
-
throws `SyntaxError` — a backend alias is opted in by elevating it with nothing.
|
|
75
|
-
|
|
76
|
-
## The three verbs
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
const ep = context.entrypoint<ClientEntrypoint<Project>>(manager.back.project.create)
|
|
80
|
-
|
|
81
|
-
const project = await ep.call({ body }) // the VALUE; the reply error is thrown
|
|
82
|
-
const { value, outcome } = await ep.invoke({ body }) // value AND outcome
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
`call` is the default — it resolves to the value and throws whatever the reply carried, so a caller
|
|
86
|
-
that only needs the result never inspects an outcome. Reach for `invoke` only where the outcome
|
|
87
|
-
(`Ok`, `Accepted`, `Created`, `Finished`) decides what happens next.
|
|
88
|
-
|
|
89
|
-
An entrypoint that carries a **renderer IS a screen**: it is addressed by URL, never called over the
|
|
90
|
-
wire, and it throws from `call()`/`invoke()` saying so.
|
|
91
|
-
|
|
92
|
-
## URL generation
|
|
93
|
-
|
|
94
|
-
`url()` fills in `:params`, appends the query, and returns a **relative** path when the route belongs
|
|
95
|
-
to the asking service — addressing an in-app target absolutely would turn navigation into a full page
|
|
96
|
-
load. Ask for `{ absolute: true }` when the URL leaves the app (redirect URIs, webhook callbacks,
|
|
97
|
-
anything pasted into another system), and a cross-service route is absolute regardless.
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
101
|
-
import { HOME } from '@owlmeans/context'
|
|
102
|
-
|
|
103
|
-
const url = await context.entrypoint<ClientEntrypoint<string>>(HOME).url({}, { absolute: true })
|
|
104
|
-
// Returns e.g. "https://app.example.com/"
|
|
20
|
+
const value = await context.entrypoint(projectEntrypoints.create).call({ body })
|
|
21
|
+
const { value, outcome } = await context.entrypoint(projectEntrypoints.create).invoke({ body })
|
|
22
|
+
const href = await context.entrypoint(projectEntrypoints.edit).url({ params: { id } })
|
|
105
23
|
```
|
|
106
24
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
Two cases are absolute whatever the caller asks for. A route that resolves to **another service** is
|
|
112
|
-
one — an in-app target addressed absolutely would turn navigation into a full page load, and a
|
|
113
|
-
foreign one addressed relatively would hit this app. A **socket** route is the other: `new
|
|
114
|
-
WebSocket(path)` resolves a relative value against the page's origin, which in a split deployment is
|
|
115
|
-
the web host rather than the service that answers the upgrade.
|
|
116
|
-
|
|
117
|
-
## Which carrier takes the call
|
|
118
|
-
|
|
119
|
-
`apiHandler` checks `cfg.webService` **before** it looks at anything else and throws
|
|
120
|
-
`SyntaxError('No webService provided')` when the field is absent. That check is unconditional, so
|
|
121
|
-
every client entrypoint needs an API client configured — including one that is carried by a queue
|
|
122
|
-
and never touches an API client at all.
|
|
123
|
-
|
|
124
|
-
Past that check the route's protocol decides. When a service is registered under that protocol's
|
|
125
|
-
transport alias, it takes the call, so a queue-carried entrypoint and an HTTP-carried one are the
|
|
126
|
-
same `call(...)` at the call site.
|
|
127
|
-
|
|
128
|
-
Otherwise the carrier is the API client `cfg.webService` names. A string names one for everything; a
|
|
129
|
-
record is looked up by the alias of the service the route resolves to, then by `DEFAULT_KEY`, and a
|
|
130
|
-
record carrying neither throws ``SyntaxError("Can't cast web service alias for <alias> entrypoint")``
|
|
131
|
-
— read that as "this config names API clients, but none of them for this target service". See
|
|
132
|
-
[[client-config]] for the field itself.
|
|
133
|
-
|
|
134
|
-
## Depends On
|
|
135
|
-
|
|
136
|
-
- `@owlmeans/entrypoint`, `@owlmeans/client-route`, `@owlmeans/client-context`,
|
|
137
|
-
`@owlmeans/client-config` (`webService` resolution), `@owlmeans/route`, `@owlmeans/context`,
|
|
138
|
-
`@owlmeans/error`
|
|
139
|
-
- `@owlmeans/api` (the HTTP carrier), `@owlmeans/config` (`makeSecurityHelper` for absolute URLs)
|
|
140
|
-
- `qs` (query serialization), `ajv-formats`; `ajv` is a peer dependency
|
|
25
|
+
`bindAll(tree)` flattens a nested named declaration tree while preserving the union of its protocol
|
|
26
|
+
types. `bind(protocol)` is appropriate where one protocol must use a distinct client option.
|
|
27
|
+
`bindScreen` is for a frontend route and renderer; screens are addressed by `url` and reject
|
|
28
|
+
`call`/`invoke`.
|
|
141
29
|
|
|
142
|
-
|
|
30
|
+
`context.entrypoint(protocol)` derives `ClientProtocolEntrypoint<Protocol>` from the protocol. Do
|
|
31
|
+
not add an explicit result generic. `entrypointRef<Request, Response>(alias)` is reserved for a
|
|
32
|
+
dynamic remote declaration that cannot be imported.
|
|
143
33
|
|
|
144
|
-
|
|
145
|
-
|
|
34
|
+
Client calls include only contract request sections plus `CallOptions` (`auth`, host/port/base,
|
|
35
|
+
timeout, signal). `url` accepts params/query plus the same address options. The route transport is
|
|
36
|
+
chosen by the declaration; callers do not branch for HTTP, socket, or queue.
|
package/build/entrypoint.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { ClientRouteModel } from '@owlmeans/client-route';
|
|
2
1
|
import type { ClientEntrypoint, ClientEntrypointOptions, RefedEntrypointHandler } from './types.js';
|
|
3
2
|
import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint';
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
3
|
+
/** Attach client behaviour to an entrypoint already materialized from a protocol. */
|
|
4
|
+
export declare const bindMaterializedEntrypoint: <T, R extends AbstractRequest = AbstractRequest>(arg: CommonEntrypoint, handler?: RefedEntrypointHandler<T, R>, opts?: ClientEntrypointOptions) => ClientEntrypoint<T, R>;
|
|
6
5
|
//# sourceMappingURL=entrypoint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAiB,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAO7E,qFAAqF;AACrF,eAAO,MAAM,0BAA0B,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,OAClF,gBAAgB,YACX,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,SAC/B,uBAAuB,KAC7B,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAqDvB,CAAA"}
|
package/build/entrypoint.js
CHANGED
|
@@ -1,37 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { validate } from './utils/entrypoint.js';
|
|
2
|
+
import { route } from '@owlmeans/client-route';
|
|
3
3
|
import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js';
|
|
4
4
|
import { AppType } from '@owlmeans/context';
|
|
5
5
|
import { provideRequest } from './helper.js';
|
|
6
|
-
|
|
6
|
+
/** Attach client behaviour to an entrypoint already materialized from a protocol. */
|
|
7
|
+
export const bindMaterializedEntrypoint = (arg, handler, opts) => {
|
|
7
8
|
const entrypointHandle = { ref: undefined };
|
|
8
9
|
let _entrypoint;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
_entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])];
|
|
20
|
-
_entrypoint.filter = opts?.filter ?? arg.filter;
|
|
21
|
-
_entrypoint.gate = opts?.gate ?? arg.gate;
|
|
22
|
-
_entrypoint.gateParams = opts?.gateParams ?? arg.gateParams;
|
|
23
|
-
}
|
|
24
|
-
else if (isClientRouteModel(arg)) {
|
|
25
|
-
assertExplicitHandler(arg.route.type, handler);
|
|
26
|
-
_entrypoint = makeBasicEntrypoint(arg, { ...opts });
|
|
27
|
-
_entrypoint.route = arg;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
assertExplicitHandler(arg.route.type, handler);
|
|
31
|
-
const _route = route(arg, opts?.routeOptions);
|
|
32
|
-
_entrypoint = makeBasicEntrypoint(_route, { ...opts });
|
|
33
|
-
_entrypoint.route = _route;
|
|
34
|
-
}
|
|
10
|
+
const _handler = handler ?? (arg.route.route.type === AppType.Backend ? apiHandler : undefined);
|
|
11
|
+
assertExplicitHandler(arg.route.route.type, handler);
|
|
12
|
+
const routeModel = route(arg.route, opts?.routeOptions);
|
|
13
|
+
_entrypoint = arg;
|
|
14
|
+
_entrypoint.route = routeModel;
|
|
15
|
+
// Binding adds guards, it never swaps them: what the declaration carries still applies.
|
|
16
|
+
_entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])];
|
|
17
|
+
_entrypoint.filter = opts?.filter ?? arg.filter;
|
|
18
|
+
_entrypoint.gate = opts?.gate ?? arg.gate;
|
|
19
|
+
_entrypoint.gateParams = opts?.gateParams ?? arg.gateParams;
|
|
35
20
|
_entrypoint.url = ((req, urlOpts) => entrypointUrl(entrypointHandle, req, urlOpts));
|
|
36
21
|
// An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
|
|
37
22
|
// wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
|
package/build/entrypoint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"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"}
|
package/build/helper.d.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AbstractRequest
|
|
1
|
+
import type { RefedEntrypointHandler } from './types.js';
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
3
3
|
import type { JSONSchemaType } from "ajv";
|
|
4
|
-
/**
|
|
5
|
-
* Replace the entrypoint declared under `alias` with its elevated counterpart. Elevating is
|
|
6
|
-
* idempotent — calling it again simply replaces the element once more, and the guards it brings
|
|
7
|
-
* are added to the ones already declared.
|
|
8
|
-
*
|
|
9
|
-
* @throws {SyntaxError} when no entrypoint carries the alias
|
|
10
|
-
*/
|
|
11
|
-
export declare const elevate: <T = {}, R extends AbstractRequest = AbstractRequest>(entrypoints: (CommonEntrypoint | ClientEntrypoint<T, R>)[], alias: string, handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean, opts?: ClientEntrypointOptions | boolean) => ClientEntrypoint<T, R>[];
|
|
12
4
|
export declare const stab: RefedEntrypointHandler<{}>;
|
|
13
5
|
export declare const provideRequest: <T extends {} = {}>(alias: string, path: string) => AbstractRequest<T>;
|
|
14
6
|
export declare const pickPerSchema: <T, R>(object: T, schema: JSONSchemaType<R>) => Partial<R>;
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC,eAAO,MAAM,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAE3C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,MAAM,QAAQ,MAAM,KAAG,eAAe,CAAC,CAAC,CAYhG,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAQjF,CAAA"}
|
package/build/helper.js
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import { entrypoint } from './entrypoint.js';
|
|
2
|
-
import { normalizeHelperParams } from './utils/entrypoint.js';
|
|
3
|
-
/**
|
|
4
|
-
* Replace the entrypoint declared under `alias` with its elevated counterpart. Elevating is
|
|
5
|
-
* idempotent — calling it again simply replaces the element once more, and the guards it brings
|
|
6
|
-
* are added to the ones already declared.
|
|
7
|
-
*
|
|
8
|
-
* @throws {SyntaxError} when no entrypoint carries the alias
|
|
9
|
-
*/
|
|
10
|
-
export const elevate = (entrypoints, alias, handler, opts) => {
|
|
11
|
-
[handler, opts] = normalizeHelperParams(handler, opts);
|
|
12
|
-
const idx = entrypoints.findIndex(({ route }) => route.route.alias === alias);
|
|
13
|
-
if (idx === -1) {
|
|
14
|
-
throw new SyntaxError(`Entrypoint with alias ${alias} not present`);
|
|
15
|
-
}
|
|
16
|
-
entrypoints[idx] = entrypoint(entrypoints[idx], handler, opts);
|
|
17
|
-
return entrypoints;
|
|
18
|
-
};
|
|
19
1
|
export const stab = () => () => {
|
|
20
2
|
return void 0;
|
|
21
3
|
};
|
package/build/helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,IAAI,GAA+B,GAAG,EAAE,CAAC,GAAG,EAAE;IACzD,OAAO,KAAK,CAAQ,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAoB,KAAa,EAAE,IAAY,EAAsB,EAAE;IACnG,MAAM,OAAO,GAAG;QACd,KAAK;QACL,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,EAAE;QACT,IAAI;QACJ,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI;KACtC,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,MAAS,EAAE,MAAyB,EAAc,EAAE,CACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACX,IAAI,MAAM,CAAC,GAAc,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,GAAc,CAAC,GAAG,MAAM,CAAC,GAAc,CAA0B,CAAA;IACvE,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,EAAE,EAAgB,CACpB,CAAA"}
|
package/build/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export * from './helper.js';
|
|
2
1
|
export type * from './types.js';
|
|
3
|
-
export * from './entrypoint.js';
|
|
4
2
|
export * from './errors.js';
|
|
5
3
|
export * from './protocol.js';
|
|
4
|
+
export { pickPerSchema, provideRequest, stab } from './helper.js';
|
|
6
5
|
//# 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,
|
|
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,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,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":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA"}
|
package/build/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAEzF,OAAO,KAAK,EACV,uBAAuB,EAAE,wBAAwB,EAAE,sBAAsB,EAC1E,MAAM,YAAY,CAAA;AAEnB,4FAA4F;AAC5F,eAAO,MAAM,IAAI,GAAI,QAAQ,SAAS,6BAA6B,YACvD,QAAQ,YACR,uBAAuB,KAChC,wBAAwB,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,6BAA6B,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAEzF,OAAO,KAAK,EACV,uBAAuB,EAAE,wBAAwB,EAAE,sBAAsB,EAC1E,MAAM,YAAY,CAAA;AAEnB,4FAA4F;AAC5F,eAAO,MAAM,IAAI,GAAI,QAAQ,SAAS,6BAA6B,YACvD,QAAQ,YACR,uBAAuB,KAChC,wBAAwB,CAAC,QAAQ,CAQnC,CAAA;AAED,wFAAwF;AACxF,eAAO,MAAM,OAAO,SAAU,cAAc,KAAG,wBAAwB,CAAC,6BAA6B,CAAC,EACrD,CAAA;AAEjD,iEAAiE;AACjE,eAAO,MAAM,UAAU,GAAI,QAAQ,SAAS,6BAA6B,YAC7D,QAAQ,WACT,sBAAsB,YACrB,uBAAuB,KAChC,wBAAwB,CAAC,QAAQ,CAQnC,CAAA"}
|
package/build/protocol.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { materializeEntrypoint, protocols } from '@owlmeans/entrypoint';
|
|
2
|
-
import {
|
|
2
|
+
import { bindMaterializedEntrypoint } from './entrypoint.js';
|
|
3
3
|
/** Bind a shared protocol to the client context without changing the declaration itself. */
|
|
4
4
|
export const bind = (protocol, options) => {
|
|
5
|
-
const bound = Object.assign(
|
|
5
|
+
const bound = Object.assign(bindMaterializedEntrypoint(materializeEntrypoint(protocol), undefined, options), { protocol });
|
|
6
6
|
return bound;
|
|
7
7
|
};
|
|
8
8
|
/** Materialize every protocol in an exported declaration tree for a browser context. */
|
|
9
9
|
export const bindAll = (tree) => protocols(tree).map(protocol => bind(protocol));
|
|
10
10
|
/** Bind a frontend protocol to the component that renders it. */
|
|
11
11
|
export const bindScreen = (protocol, handler, options) => {
|
|
12
|
-
const bound = Object.assign(
|
|
12
|
+
const bound = Object.assign(bindMaterializedEntrypoint(materializeEntrypoint(protocol), handler, options), { protocol });
|
|
13
13
|
return bound;
|
|
14
14
|
};
|
|
15
15
|
//# sourceMappingURL=protocol.js.map
|
package/build/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AAK5D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,QAAkB,EAClB,OAAiC,EACG,EAAE;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,0BAA0B,CACpD,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,SAAS,EACT,OAAO,CACR,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;IAEhB,OAAO,KAA2C,CAAA;AACpD,CAAC,CAAA;AAED,wFAAwF;AACxF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAoB,EAA6D,EAAE,CACzG,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;AAEjD,iEAAiE;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,QAAkB,EAClB,OAA+B,EAC/B,OAAiC,EACG,EAAE;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,0BAA0B,CACpD,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,OAAO,EACP,OAAO,CACR,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;IAEhB,OAAO,KAA2C,CAAA;AACpD,CAAC,CAAA"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import type { EntrypointFilter
|
|
1
|
+
import type { EntrypointFilter } from '../types.js';
|
|
2
2
|
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
3
|
-
import type { EntrypointRef
|
|
4
|
-
export { entrypoint as makeBasicEntrypoint } from '@owlmeans/entrypoint';
|
|
3
|
+
import type { EntrypointRef } from '../types.js';
|
|
5
4
|
export { isEntrypoint } from '@owlmeans/entrypoint/utils';
|
|
6
5
|
/**
|
|
7
6
|
* @throws {SyntaxError} if data shape doesn't match validation
|
|
8
7
|
* @throws {ClientValidationError} if request is not valid
|
|
9
8
|
*/
|
|
10
9
|
export declare const validate: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>) => EntrypointFilter;
|
|
11
|
-
export declare const normalizeHelperParams: <T, R extends AbstractRequest = AbstractRequest>(handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean, opts?: ClientEntrypointOptions | boolean) => [RefedEntrypointHandler<T, R> | undefined, ClientEntrypointOptions | undefined];
|
|
12
10
|
//# sourceMappingURL=entrypoint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAKzD;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,gBAiClG,CAAA"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import Ajv from 'ajv';
|
|
2
2
|
import { ClientValidationError } from '../errors.js';
|
|
3
3
|
import formatsPlugin from 'ajv-formats';
|
|
4
|
-
export { entrypoint as makeBasicEntrypoint } from '@owlmeans/entrypoint';
|
|
5
4
|
export { isEntrypoint } from '@owlmeans/entrypoint/utils';
|
|
6
5
|
const ajv = new Ajv({ strict: false });
|
|
7
6
|
formatsPlugin(ajv);
|
|
@@ -40,12 +39,4 @@ export const validate = (ref) => async (req) => {
|
|
|
40
39
|
}
|
|
41
40
|
return true;
|
|
42
41
|
};
|
|
43
|
-
export const normalizeHelperParams = (handler, opts) => {
|
|
44
|
-
if (typeof handler !== 'function' && handler != null) {
|
|
45
|
-
opts = handler;
|
|
46
|
-
handler = undefined;
|
|
47
|
-
}
|
|
48
|
-
opts = typeof opts === 'boolean' ? { validateOnCall: opts } : opts;
|
|
49
|
-
return [handler, opts];
|
|
50
|
-
};
|
|
51
42
|
//# sourceMappingURL=entrypoint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGpD,OAAO,aAAa,MAAM,aAAa,CAAA;AAEvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AAGrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAGpD,OAAO,aAAa,MAAM,aAAa,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAEzD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;AACtC,aAAa,CAAC,GAAU,CAAC,CAAA;AAEzB;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GACnB,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACrB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAA;IAClB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,gDAAgD,CAAC,CAAA;IACzE,CAAC;IACD,IAAI,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,WAAW,CAAC,gEAAgE,CAAC,CAAA;IACzF,CAAC;IACD,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,WAAW,CAAC,cAAc,GAAG,CAAC,KAAK,oCAAoC,CAAC,CAAA;IACpF,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SAClH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;QAC3B,IAAI,GAAG,CAAC,GAAuB,CAAC,IAAI,IAAI,EAAE,CAAC;YACzC,MAAM,IAAI,WAAW,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAA;QACjE,CAAC;QAED,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACtC,UAAU,CAAC,GAAG,CAAC,GAAuB,CAAC,CAAC,CAAA;QACxC,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAA;QACb,CAAC;aAAM,CAAC;YACN,OAAO,UAAU,CAAC,MAAM,CAAA;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC,CAAA;IACL,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,IAAI,CAAmB,CAAA;QAE1F,MAAM,IAAI,qBAAqB,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IACnF,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client-entrypoint",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@owlmeans/api": "^0.1.18-rc.
|
|
32
|
-
"@owlmeans/client-config": "^0.1.18-rc.
|
|
33
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/client-route": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
31
|
+
"@owlmeans/api": "^0.1.18-rc.16",
|
|
32
|
+
"@owlmeans/client-config": "^0.1.18-rc.15",
|
|
33
|
+
"@owlmeans/client-context": "^0.1.18-rc.16",
|
|
34
|
+
"@owlmeans/client-route": "^0.1.18-rc.16",
|
|
35
|
+
"@owlmeans/config": "^0.1.18-rc.15",
|
|
36
|
+
"@owlmeans/context": "^0.1.18-rc.11",
|
|
37
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.14",
|
|
38
|
+
"@owlmeans/error": "^0.1.18-rc.11",
|
|
39
|
+
"@owlmeans/route": "^0.1.18-rc.12",
|
|
40
40
|
"ajv-formats": "^3.0.1",
|
|
41
41
|
"qs": "^6.13.0"
|
|
42
42
|
},
|
package/src/entrypoint.ts
CHANGED
|
@@ -1,48 +1,32 @@
|
|
|
1
|
-
import type { ClientRouteModel } from '@owlmeans/client-route'
|
|
2
1
|
import type { ClientEntrypoint, ClientEntrypointOptions, EntrypointRef, RefedEntrypointHandler } from './types.js'
|
|
3
2
|
import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { validate } from './utils/entrypoint.js'
|
|
4
|
+
import { route } from '@owlmeans/client-route'
|
|
6
5
|
import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js'
|
|
7
6
|
import { AppType } from '@owlmeans/context'
|
|
8
|
-
import type { RouteModel } from '@owlmeans/route'
|
|
9
7
|
import { provideRequest } from './helper.js'
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
/** Attach client behaviour to an entrypoint already materialized from a protocol. */
|
|
10
|
+
export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = AbstractRequest>(
|
|
11
|
+
arg: CommonEntrypoint,
|
|
12
|
+
handler?: RefedEntrypointHandler<T, R>,
|
|
13
|
+
opts?: ClientEntrypointOptions,
|
|
15
14
|
): ClientEntrypoint<T, R> => {
|
|
16
15
|
const entrypointHandle: EntrypointRef<T, R> = { ref: undefined }
|
|
17
16
|
|
|
18
17
|
let _entrypoint: ClientEntrypoint<T, R>
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// Elevating adds guards, it never swaps them: what the entrypoint declared still applies.
|
|
32
|
-
_entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])]
|
|
33
|
-
_entrypoint.filter = opts?.filter ?? arg.filter
|
|
34
|
-
_entrypoint.gate = opts?.gate ?? arg.gate
|
|
35
|
-
_entrypoint.gateParams = opts?.gateParams ?? arg.gateParams
|
|
36
|
-
} else if (isClientRouteModel(arg)) {
|
|
37
|
-
assertExplicitHandler(arg.route.type, handler as RefedEntrypointHandler<T, R>)
|
|
38
|
-
_entrypoint = makeBasicEntrypoint(arg, { ...opts }) as ClientEntrypoint<T, R>
|
|
39
|
-
_entrypoint.route = arg
|
|
40
|
-
} else {
|
|
41
|
-
assertExplicitHandler(arg.route.type, handler as RefedEntrypointHandler<T, R>)
|
|
42
|
-
const _route = route(arg, opts?.routeOptions)
|
|
43
|
-
_entrypoint = makeBasicEntrypoint(_route, { ...opts }) as ClientEntrypoint<T, R>
|
|
44
|
-
_entrypoint.route = _route
|
|
45
|
-
}
|
|
19
|
+
const _handler = handler ?? (arg.route.route.type === AppType.Backend ? apiHandler : undefined)
|
|
20
|
+
|
|
21
|
+
assertExplicitHandler(arg.route.route.type, handler)
|
|
22
|
+
const routeModel = route(arg.route, opts?.routeOptions)
|
|
23
|
+
_entrypoint = arg as ClientEntrypoint<T, R>
|
|
24
|
+
_entrypoint.route = routeModel
|
|
25
|
+
// Binding adds guards, it never swaps them: what the declaration carries still applies.
|
|
26
|
+
_entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])]
|
|
27
|
+
_entrypoint.filter = opts?.filter ?? arg.filter
|
|
28
|
+
_entrypoint.gate = opts?.gate ?? arg.gate
|
|
29
|
+
_entrypoint.gateParams = opts?.gateParams ?? arg.gateParams
|
|
46
30
|
|
|
47
31
|
_entrypoint.url = ((req?: Partial<R>, urlOpts?: { absolute?: boolean }) =>
|
|
48
32
|
entrypointUrl<T, R>(entrypointHandle, req as never, urlOpts)) as ClientEntrypoint<T, R>['url']
|
package/src/helper.ts
CHANGED
|
@@ -1,34 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
|
|
4
|
-
import { normalizeHelperParams } from './utils/entrypoint.js'
|
|
1
|
+
import type { RefedEntrypointHandler } from './types.js'
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint'
|
|
5
3
|
import type { JSONSchemaType } from "ajv"
|
|
6
4
|
|
|
7
|
-
/**
|
|
8
|
-
* Replace the entrypoint declared under `alias` with its elevated counterpart. Elevating is
|
|
9
|
-
* idempotent — calling it again simply replaces the element once more, and the guards it brings
|
|
10
|
-
* are added to the ones already declared.
|
|
11
|
-
*
|
|
12
|
-
* @throws {SyntaxError} when no entrypoint carries the alias
|
|
13
|
-
*/
|
|
14
|
-
export const elevate = <T = {}, R extends AbstractRequest = AbstractRequest>(
|
|
15
|
-
entrypoints: (CommonEntrypoint | ClientEntrypoint<T, R>)[],
|
|
16
|
-
alias: string,
|
|
17
|
-
handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean,
|
|
18
|
-
opts?: ClientEntrypointOptions | boolean
|
|
19
|
-
): ClientEntrypoint<T, R>[] => {
|
|
20
|
-
[handler, opts] = normalizeHelperParams(handler, opts)
|
|
21
|
-
|
|
22
|
-
const idx = entrypoints.findIndex(({ route }) => route.route.alias === alias)
|
|
23
|
-
if (idx === -1) {
|
|
24
|
-
throw new SyntaxError(`Entrypoint with alias ${alias} not present`)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
entrypoints[idx] = entrypoint(entrypoints[idx], handler, opts)
|
|
28
|
-
|
|
29
|
-
return entrypoints as ClientEntrypoint<T, R>[]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
5
|
export const stab: RefedEntrypointHandler<{}> = () => () => {
|
|
33
6
|
return void 0 as any
|
|
34
7
|
}
|
package/src/index.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { materializeEntrypoint, protocols } from '@owlmeans/entrypoint'
|
|
2
2
|
import type { EntrypointProtocolDeclaration, EntrypointTree } from '@owlmeans/entrypoint'
|
|
3
|
-
import {
|
|
3
|
+
import { bindMaterializedEntrypoint } from './entrypoint.js'
|
|
4
4
|
import type {
|
|
5
5
|
ClientEntrypointOptions, ClientProtocolEntrypoint, RefedEntrypointHandler,
|
|
6
6
|
} from './types.js'
|
|
@@ -10,8 +10,9 @@ export const bind = <Protocol extends EntrypointProtocolDeclaration>(
|
|
|
10
10
|
protocol: Protocol,
|
|
11
11
|
options?: ClientEntrypointOptions,
|
|
12
12
|
): ClientProtocolEntrypoint<Protocol> => {
|
|
13
|
-
const bound = Object.assign(
|
|
13
|
+
const bound = Object.assign(bindMaterializedEntrypoint(
|
|
14
14
|
materializeEntrypoint(protocol),
|
|
15
|
+
undefined,
|
|
15
16
|
options,
|
|
16
17
|
), { protocol })
|
|
17
18
|
|
|
@@ -28,7 +29,7 @@ export const bindScreen = <Protocol extends EntrypointProtocolDeclaration>(
|
|
|
28
29
|
handler: RefedEntrypointHandler,
|
|
29
30
|
options?: ClientEntrypointOptions,
|
|
30
31
|
): ClientProtocolEntrypoint<Protocol> => {
|
|
31
|
-
const bound = Object.assign(
|
|
32
|
+
const bound = Object.assign(bindMaterializedEntrypoint(
|
|
32
33
|
materializeEntrypoint(protocol),
|
|
33
34
|
handler,
|
|
34
35
|
options,
|
package/src/utils/entrypoint.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import Ajv from 'ajv'
|
|
2
2
|
import type { ErrorObject } from 'ajv'
|
|
3
|
-
import type { EntrypointFilter
|
|
3
|
+
import type { EntrypointFilter } from '../types.js'
|
|
4
4
|
import { ClientValidationError } from '../errors.js'
|
|
5
5
|
import type { AbstractRequest } from '@owlmeans/entrypoint'
|
|
6
|
-
import type { EntrypointRef
|
|
6
|
+
import type { EntrypointRef } from '../types.js'
|
|
7
7
|
import formatsPlugin from 'ajv-formats'
|
|
8
8
|
|
|
9
|
-
export { entrypoint as makeBasicEntrypoint } from '@owlmeans/entrypoint'
|
|
10
9
|
export { isEntrypoint } from '@owlmeans/entrypoint/utils'
|
|
11
10
|
|
|
12
11
|
const ajv = new Ajv({ strict: false })
|
|
@@ -50,17 +49,3 @@ export const validate: <T, R extends AbstractRequest = AbstractRequest>(ref: Ent
|
|
|
50
49
|
|
|
51
50
|
return true
|
|
52
51
|
}
|
|
53
|
-
|
|
54
|
-
export const normalizeHelperParams = <T, R extends AbstractRequest = AbstractRequest>(
|
|
55
|
-
handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean,
|
|
56
|
-
opts?: ClientEntrypointOptions | boolean
|
|
57
|
-
): [RefedEntrypointHandler<T, R> | undefined, ClientEntrypointOptions | undefined] => {
|
|
58
|
-
if (typeof handler !== 'function' && handler != null) {
|
|
59
|
-
opts = handler as ClientEntrypointOptions | boolean
|
|
60
|
-
handler = undefined
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
opts = typeof opts === 'boolean' ? { validateOnCall: opts } : opts
|
|
64
|
-
|
|
65
|
-
return [handler, opts]
|
|
66
|
-
}
|