@owlmeans/client-entrypoint 0.1.18-rc.10 → 0.1.18-rc.12

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 CHANGED
@@ -5,8 +5,9 @@ Client-side entrypoint system: elevates route definitions into API-calling `Clie
5
5
  ## Overview
6
6
 
7
7
  - `elevate(entrypoints, alias, handler?, opts?)` — attaches a client handler to an entrypoint (mirrors server `elevate`)
8
- - `ClientEntrypoint<T>` has a `call(request?)` method that resolves the URL and makes an HTTP/WS request
9
- - `stab` — no-op handler for entrypoints that only need URL resolution (no logic)
8
+ - `ClientEntrypoint<T>` exposes three explicit verbs: `call()` for the value, `invoke()` for the value
9
+ plus its outcome, and `url()` for the address
10
+ - `stab` — no-op handler for entrypoints that only need a URL (no logic)
10
11
  - `provideRequest(alias, path)` — creates an `AbstractRequest` for programmatic entrypoint calls
11
12
  - `pickPerSchema(schema, obj)` — extracts fields from an object matching an AJV schema
12
13
  - Re-exported as `celevate` from `@owlmeans/server-app`
@@ -25,42 +26,60 @@ Define and elevate a client entrypoint for API calls:
25
26
  import { elevate, stab } from '@owlmeans/client-entrypoint'
26
27
  import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
27
28
 
28
- const appModules = [
29
+ const appEntrypoints = [
29
30
  entrypoint(route('project-list', '/projects', frontend('base'))),
30
31
  entrypoint(route('project-create', '/projects', backend(RouteMethod.POST))),
31
32
  ]
32
33
 
33
- // Frontend navigation — just a stub, no network call
34
- elevate(appModules, 'project-list', stab)
34
+ // Frontend navigation — a screen, addressed with url(); call()/invoke() throw on it
35
+ elevate(appEntrypoints, 'project-list', stab)
35
36
 
36
37
  // Backend API call — call() makes a POST request
37
- elevate(appModules, 'project-create')
38
+ elevate(appEntrypoints, 'project-create')
38
39
  ```
39
40
 
40
41
  Call an entrypoint from a service:
41
42
 
42
43
  ```typescript
43
44
  const agentEntrypoint = ctx.entrypoint<ClientEntrypoint<Project>>(agent.project.create)
44
- const [result] = await agentEntrypoint.call({
45
- body: { prompt: payload.prompt, entity: req.auth?.entityId }
45
+ const result = await agentEntrypoint.call({
46
+ body: { prompt: payload.prompt, entity: req.auth?.entitySlug }
46
47
  })
47
48
  ```
48
49
 
50
+ Take the outcome when it decides what happens next, and build a link with `url()`:
51
+
52
+ ```typescript
53
+ const { value, outcome } = await agentEntrypoint.invoke({ body: payload })
54
+
55
+ const href = await ctx.entrypoint<ClientEntrypoint>('project-list')
56
+ .url({ params: { id: value.id } }, { absolute: true })
57
+ ```
58
+
49
59
  ## API
50
60
 
51
61
  ### `elevate<T, R>(entrypoints, alias, handler?, opts?): ClientEntrypoint<T, R>[]`
52
62
 
53
- Mutates `entrypoints` in-place and returns the array typed as `ClientEntrypoint`. The `handler` sets how `call()` behaves.
63
+ Replaces the element carrying `alias` with its elevated counterpart, in place, and returns the array typed as `ClientEntrypoint`. The `handler` sets how `call()` behaves. Elevating the same alias again just replaces it again; guards passed here are added to the ones the entrypoint declared. Throws when no entrypoint carries the alias.
54
64
 
55
65
  ### `stab: RefedEntrypointHandler`
56
66
 
57
- No-op handler for frontend-only entrypoints that just need URL resolution.
67
+ No-op handler for frontend-only entrypoints that are addressed by URL rather than called.
58
68
 
59
69
  ### `ClientEntrypoint<T>` (type)
60
70
 
61
- - `call(request?)` — resolves URL, makes HTTP request, returns `[T, EntrypointOutcome]`
71
+ - `call(request?)` — addresses the entrypoint over the wire and resolves to the value, throwing
72
+ whatever error the reply carried
73
+ - `invoke(request?)` — the same round trip, resolving to `{ value, outcome }`
74
+ - `url(request?, { absolute? })` — builds the URL this entrypoint addresses, with `:params` filled in
75
+ and the query appended; absolute when the route belongs to another service or `absolute` is asked for
62
76
  - `validate(request?)` — validates the request against the entrypoint filter schema
63
- - `getPath(partial?)` — returns the URL path (with or without path params)
77
+ - `segment()` / `path()` / `mount()` — the segment this entrypoint contributes, that segment under its
78
+ ancestors, and the same path under the service base. All three are computed from the declaration
79
+ and the context on every call — nothing is written back into the route.
80
+
81
+ An entrypoint carrying a renderer *is* a screen: it is addressed by URL, never called over the wire,
82
+ so `call()` and `invoke()` throw and point the caller at `url()`.
64
83
 
65
84
  ### `provideRequest<T>(alias, path): AbstractRequest<T>`
66
85
 
@@ -70,10 +89,17 @@ Creates a minimal request object for programmatic `call()` invocations.
70
89
 
71
90
  Extracts only the keys present in the AJV schema from `obj`.
72
91
 
92
+ ### `@owlmeans/client-entrypoint/utils`
93
+
94
+ The low-level pair the verbs are built on, for code that holds an entrypoint reference directly:
95
+
96
+ - `entrypointUrl(ref, request, opts?)` — the address behind `url()`
97
+ - `apiInvoke(ref, opts?)` — the round trip behind `invoke()`
98
+
73
99
  ## Related Packages
74
100
 
75
101
  - [`@owlmeans/entrypoint`](../entrypoint) — `CommonEntrypoint` base that gets elevated
76
- - [`@owlmeans/client`](../client) — `useNavigate` uses `ClientEntrypoint.call()`
102
+ - [`@owlmeans/client`](../client) — `useNavigate` navigates by `ClientEntrypoint.url()`
77
103
  - [`@owlmeans/server-app`](../server-app) — re-exports `elevate` as `celevate`
78
104
 
79
105
  <!-- owlmeans:agent-guidance:start -->
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/client-entrypoint",
4
- "version": "0.1.18-rc.10",
5
- "generatedAt": "2026-09-01T12:04:42.724Z",
4
+ "version": "0.1.18-rc.12",
5
+ "generatedAt": "2026-09-01T17:39:40.760Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: client-entrypoint
3
- description: How to use @owlmeans/client-entrypoint — client-side entrypoint helpers extending @owlmeans/entrypoint with React component attachment and call helpers. Auto-invoked when importing client entrypoint helpers. Also covers the deprecated @owlmeans/client-module reexport shim.
3
+ description: How to use @owlmeans/client-entrypoint — client-side entrypoints extending @owlmeans/entrypoint with the call/invoke/url verbs, React component attachment and elevation. Auto-invoked when importing client entrypoint helpers.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,20 +8,24 @@ user-invocable: false
8
8
  # @owlmeans/client-entrypoint
9
9
 
10
10
  **Layer:** Client
11
- **Install:** `"@owlmeans/client-entrypoint": "^0.1.18-rc.10"` in `dependencies`
11
+ **Install:** `"@owlmeans/client-entrypoint": "^0.1.18-rc.12"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
15
15
  | Export | Description |
16
16
  |--------|-------------|
17
- | `ClientEntrypoint<T>` types | Client entrypoint interface (handler component + call helpers) |
18
- | `EntrypointCall` / `EntrypointFilter` | Typed call and validation helpers |
17
+ | `ClientEntrypoint<T, R>` | Client entrypoint interface — `call`, `invoke`, `url`, `validate`, `request` |
18
+ | `entrypoint(arg, handler?, opts?)` | Build a client entrypoint from a route model or an existing declaration |
19
+ | `elevate(entrypoints, alias, handler?, opts?)` | Make a declared entrypoint client-callable, optionally attaching a screen |
20
+ | `EntrypointCall` / `EntrypointInvoke` / `EntrypointUrl` | The typed signatures of the three verbs |
21
+ | `EntrypointReply<T>` | `{ value, outcome }` — what `invoke` resolves to |
19
22
  | `EntrypointRef` / `RefedEntrypointHandler` | Handler reference pattern |
20
- | Entrypoint helpers | Build client entrypoints; resolve callable references |
23
+ | `provideRequest(alias, path)` / `pickPerSchema(obj, schema)` | Request construction helpers |
24
+ | `ClientEntrypointError` / `ClientValidationError` | Typed client-side failures |
21
25
 
22
26
  ## Subpath Exports
23
27
 
24
- - `./utils`
28
+ - `./utils` — `entrypointUrl(ref, req?, opts?)`, `apiInvoke(ref, opts?)`, `apiHandler(ref)`, `validate(ref)`
25
29
 
26
30
  ## Usage
27
31
 
@@ -31,20 +35,46 @@ Most app code uses `elevate()` from `@owlmeans/web-client` (which builds on this
31
35
  import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
32
36
  ```
33
37
 
34
- ## URL Generation via Entrypoint Call
38
+ Client-side callability is an **explicit opt-in**: a declaration only becomes callable from a client
39
+ once a bare client `elevate` (or `celevate` on the server side) has been applied to it. Elevating is
40
+ idempotent, and guards passed at elevation are added to the ones the declaration already carries.
35
41
 
36
- Entrypoints with a `handler` (React component) use `urlCall` internally — calling `.call()` returns a URL string. Use `{ full: true }` to get a fully-qualified URL via `makeSecurityHelper`:
42
+ ## The three verbs
43
+
44
+ ```typescript
45
+ const ep = context.entrypoint<ClientEntrypoint<Project>>(manager.back.project.create)
46
+
47
+ const project = await ep.call({ body }) // the VALUE; the reply error is thrown
48
+ const { value, outcome } = await ep.invoke({ body }) // value AND outcome
49
+ ```
50
+
51
+ `call` is the default — it resolves to the value and throws whatever the reply carried, so a caller
52
+ that only needs the result never inspects an outcome. Reach for `invoke` only where the outcome
53
+ (`Ok`, `Accepted`, `Created`, `Finished`) decides what happens next.
54
+
55
+ An entrypoint that carries a **renderer IS a screen**: it is addressed by URL, never called over the
56
+ wire, and it throws from `call()`/`invoke()` saying so.
57
+
58
+ ## URL generation
59
+
60
+ `url()` fills in `:params`, appends the query, and returns a **relative** path when the route belongs
61
+ to the asking service — addressing an in-app target absolutely would turn navigation into a full page
62
+ load. Ask for `{ absolute: true }` when the URL leaves the app (redirect URIs, webhook callbacks,
63
+ anything pasted into another system), and a cross-service route is absolute regardless.
37
64
 
38
65
  ```typescript
39
66
  import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
40
67
  import { HOME } from '@owlmeans/context'
41
68
 
42
- const [url] = await context.entrypoint<ClientEntrypoint<string>>(HOME).call({ full: true }) ?? []
69
+ const url = await context.entrypoint<ClientEntrypoint<string>>(HOME).url({}, { absolute: true })
43
70
  // Returns e.g. "https://app.example.com/"
44
71
  ```
45
72
 
46
- This is the preferred pattern for redirect URIs and navigation targets instead of manual `window.location` concatenation.
73
+ This is the preferred pattern for redirect URIs and navigation targets instead of manual
74
+ `window.location` concatenation. The underlying helper is `entrypointUrl(ref, req?, opts?)` from
75
+ `./utils`, which packages building their own addressing (sockets, for instance) call directly.
47
76
 
48
77
  ## Depends On
49
78
 
50
79
  - `@owlmeans/entrypoint`, `@owlmeans/client-route`, `@owlmeans/client-context`
80
+ - `@owlmeans/api` (the HTTP carrier), `@owlmeans/config` (`makeSecurityHelper` for absolute URLs)
@@ -1,6 +1,6 @@
1
1
  import type { ClientRouteModel } from '@owlmeans/client-route';
2
2
  import type { ClientEntrypoint, ClientEntrypointOptions, RefedEntrypointHandler } from './types.js';
3
3
  import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint';
4
- import type { CommonRouteModel } from '@owlmeans/route';
5
- export declare const entrypoint: <T, R extends AbstractRequest = AbstractRequest>(arg: CommonEntrypoint | ClientRouteModel | CommonRouteModel, handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean, opts?: ClientEntrypointOptions | boolean) => ClientEntrypoint<T, R>;
4
+ import type { RouteModel } from '@owlmeans/route';
5
+ export declare const entrypoint: <T, R extends AbstractRequest = AbstractRequest>(arg: CommonEntrypoint | ClientRouteModel | RouteModel, handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean, opts?: ClientEntrypointOptions | boolean) => ClientEntrypoint<T, R>;
6
6
  //# 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,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAiB,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAO7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGvD,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,OAClE,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,YACjD,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,SACnE,uBAAuB,GAAG,OAAO,KACvC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CA+DvB,CAAA"}
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAiB,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAK7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGjD,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EACvE,KAAK,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,EACrD,UAAU,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,EAC1E,OAAO,uBAAuB,GAAG,OAAO,KACvC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAoEvB,CAAA"}
@@ -1,8 +1,7 @@
1
1
  import { isEntrypoint, makeBasicEntrypoint, normalizeHelperParams, validate } from './utils/entrypoint.js';
2
2
  import { isClientRouteModel, route } from '@owlmeans/client-route';
3
- import { apiCall, apiHandler, urlCall } from './utils/handler.js';
3
+ import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js';
4
4
  import { AppType } from '@owlmeans/context';
5
- import { normalizePath } from '@owlmeans/route';
6
5
  import { provideRequest } from './helper.js';
7
6
  export const entrypoint = (arg, handler, opts) => {
8
7
  const entrypointHandle = { ref: undefined };
@@ -16,7 +15,8 @@ export const entrypoint = (arg, handler, opts) => {
16
15
  const routeModel = route(arg.route, opts?.routeOptions);
17
16
  _entrypoint = arg;
18
17
  _entrypoint.route = routeModel;
19
- _entrypoint.guards = opts?.guards ?? arg.guards;
18
+ // Elevating adds guards, it never swaps them: what the entrypoint declared still applies.
19
+ _entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])];
20
20
  _entrypoint.filter = opts?.filter ?? arg.filter;
21
21
  _entrypoint.gate = opts?.gate ?? arg.gate;
22
22
  _entrypoint.gateParams = opts?.gateParams ?? arg.gateParams;
@@ -32,13 +32,20 @@ export const entrypoint = (arg, handler, opts) => {
32
32
  _entrypoint = makeBasicEntrypoint(_route, { ...opts });
33
33
  _entrypoint.route = _route;
34
34
  }
35
- _entrypoint.getPath = (partial) => partial === true ? normalizePath(_entrypoint.route.route.partialPath) : _entrypoint.route.route.path;
36
- _entrypoint.call = handler != null ? urlCall(entrypointHandle, opts) : apiCall(entrypointHandle, opts);
35
+ _entrypoint.url = ((req, urlOpts) => entrypointUrl(entrypointHandle, req, urlOpts));
36
+ // An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
37
+ // wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
38
+ _entrypoint.invoke = (handler != null
39
+ ? (async () => {
40
+ throw new SyntaxError(`Entrypoint ${_entrypoint.alias} renders a screen - address it with url() instead of call()/invoke()`);
41
+ })
42
+ : apiInvoke(entrypointHandle, opts));
43
+ _entrypoint.call = (async (req) => (await _entrypoint.invoke(req)).value);
37
44
  _entrypoint.request = ((request) => {
38
45
  if (entrypointHandle.ref == null) {
39
46
  throw SyntaxError(`Try to request uninitialized entrypoint ${JSON.stringify(arg)}`);
40
47
  }
41
- const _request = provideRequest(entrypointHandle.ref.getAlias(), entrypointHandle.ref.getPath());
48
+ const _request = provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path());
42
49
  request != null && Object.entries(request).forEach(([key, value]) => {
43
50
  _request[key] = value;
44
51
  });
@@ -46,11 +53,6 @@ export const entrypoint = (arg, handler, opts) => {
46
53
  });
47
54
  _entrypoint.handle = _handler?.(entrypointHandle);
48
55
  _entrypoint.validate = validate(entrypointHandle);
49
- _entrypoint.reinitializeContext = (context) => {
50
- const newEntrypoint = entrypoint(_entrypoint.route, handler, opts);
51
- newEntrypoint.ctx = context;
52
- return newEntrypoint;
53
- };
54
56
  entrypointHandle.ref = _entrypoint;
55
57
  return _entrypoint;
56
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,qBAAa,qBAAsB,SAAQ,cAAc;IACvD,OAAuB,QAAQ,SAAsB;IAErD,YAAY,OAAO,EAAE,MAAM,EAE1B;CACF;AAED,qBAAa,qBAAsB,SAAQ,qBAAqB;IAC9D,OAAuB,QAAQ,SAAgD;IAE/E,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,qBAAa,qBAAsB,SAAQ,cAAc;IACvD,OAAuB,QAAQ,SAAsB;gBAEzC,OAAO,EAAE,MAAM;CAG5B;AAED,qBAAa,qBAAsB,SAAQ,qBAAqB;IAC9D,OAAuB,QAAQ,SAAgD;gBAEnE,OAAO,EAAE,MAAM;CAI5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,OAAO,qBAAsB,SAAQ,cAAc;IAChD,MAAM,CAAU,QAAQ,GAAG,mBAAmB,CAAA;IAErD,YAAY,OAAe;QACzB,KAAK,CAAC,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,OAAO,EAAE,CAAC,CAAA;IACnE,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,qBAAqB;IACvD,MAAM,CAAU,QAAQ,GAAG,GAAG,qBAAqB,CAAC,QAAQ,YAAY,CAAA;IAE/E,YAAY,OAAe;QACzB,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAA;QAC9B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,QAAQ,CAAA;IAC5C,CAAC;CACF;AAGD,cAAc,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;AACxD,cAAc,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,CAAA"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,OAAO,qBAAsB,SAAQ,cAAc;IAChD,MAAM,CAAU,QAAQ,GAAG,mBAAmB,CAAA;IAErD,YAAY,OAAe;QACzB,KAAK,CAAC,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,OAAO,EAAE,CAAC,CAAA;IACnE,CAAC;;AAGH,MAAM,OAAO,qBAAsB,SAAQ,qBAAqB;IACvD,MAAM,CAAU,QAAQ,GAAG,GAAG,qBAAqB,CAAC,QAAQ,YAAY,CAAA;IAE/E,YAAY,OAAe;QACzB,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAA;QAC9B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,QAAQ,CAAA;IAC5C,CAAC;;AAIH,cAAc,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;AACxD,cAAc,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,CAAA"}
package/build/helper.d.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  import type { ClientEntrypoint, ClientEntrypointOptions, RefedEntrypointHandler } from './types.js';
2
2
  import type { AbstractRequest, CommonEntrypoint } 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
+ */
4
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>[];
5
12
  export declare const stab: RefedEntrypointHandler<{}>;
6
13
  export declare const provideRequest: <T extends {} = {}>(alias: string, path: string) => AbstractRequest<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAGnG,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC,eAAO,MAAM,OAAO,GAAI,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,eAC5D,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SACnD,MAAM,YACH,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,SACnE,uBAAuB,GAAG,OAAO,KACvC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAcxB,CAAA;AAED,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"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAEnG,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EACzE,aAAa,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAC1D,OAAO,MAAM,EACb,UAAU,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,EAC1E,OAAO,uBAAuB,GAAG,OAAO,KACvC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAWxB,CAAA;AAED,eAAO,MAAM,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAE3C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,OAAO,MAAM,EAAE,MAAM,MAAM,KAAG,eAAe,CAAC,CAAC,CAYhG,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAQjF,CAAA"}
package/build/helper.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import { entrypoint } from './entrypoint.js';
2
- import { isClientRouteModel } from '@owlmeans/client-route';
3
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
+ */
4
10
  export const elevate = (entrypoints, alias, handler, opts) => {
5
11
  [handler, opts] = normalizeHelperParams(handler, opts);
6
12
  const idx = entrypoints.findIndex(({ route }) => route.route.alias === alias);
7
13
  if (idx === -1) {
8
14
  throw new SyntaxError(`Entrypoint with alias ${alias} not present`);
9
15
  }
10
- if (isClientRouteModel(entrypoints[idx].route) && opts?.force !== true) {
11
- throw new SyntaxError(`Entrypoint with alias ${alias} is already elevated`);
12
- }
13
16
  entrypoints[idx] = entrypoint(entrypoints[idx], handler, opts);
14
17
  return entrypoints;
15
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAG7D,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,WAA0D,EAC1D,KAAa,EACb,OAA0E,EAC1E,IAAwC,EACd,EAAE;IAC5B,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAEtD,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;IAC7E,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,yBAAyB,KAAK,cAAc,CAAC,CAAA;IACrE,CAAC;IACD,IAAI,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;QACvE,MAAM,IAAI,WAAW,CAAC,yBAAyB,KAAK,sBAAsB,CAAC,CAAA;IAC7E,CAAC;IAED,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IAE9D,OAAO,WAAuC,CAAA;AAChD,CAAC,CAAA;AAED,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"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAG7D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,WAA0D,EAC1D,KAAa,EACb,OAA0E,EAC1E,IAAwC,EACd,EAAE;IAC5B,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAEtD,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;IAC7E,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,yBAAyB,KAAK,cAAc,CAAC,CAAA;IACrE,CAAC;IAED,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IAE9D,OAAO,WAAuC,CAAA;AAChD,CAAC,CAAA;AAED,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/types.d.ts CHANGED
@@ -1,26 +1,48 @@
1
1
  import type { ClientRouteModel, ClientRouteOptions } from '@owlmeans/client-route';
2
- import type { AbstractRequest, AbstractResponse, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler, EntrypointOutcome } from '@owlmeans/entrypoint';
2
+ import type { AbstractRequest, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler, EntrypointOutcome } from '@owlmeans/entrypoint';
3
3
  export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientRequest> extends CommonEntrypoint {
4
4
  route: ClientRouteModel;
5
+ /**
6
+ * Address the entrypoint and resolve to what it answered. The reply's error is thrown, so a
7
+ * caller that only needs the value never inspects an outcome.
8
+ */
5
9
  call: EntrypointCall<T, R>;
10
+ /**
11
+ * The same round trip as {@link ClientEntrypoint.call}, resolving to the value AND the outcome.
12
+ * Use it only where the outcome decides what happens next.
13
+ */
14
+ invoke: EntrypointInvoke<T, R>;
15
+ /**
16
+ * Build the URL this entrypoint addresses, with `:params` filled in and the query appended.
17
+ * Absolute when the route belongs to another service, or when `absolute` is asked for.
18
+ */
19
+ url: EntrypointUrl<R>;
6
20
  validate: EntrypointFilter<R>;
7
- getPath: (partial?: boolean) => string;
8
21
  request: (request?: Partial<R>) => R;
9
22
  }
10
23
  export interface EntrypointCall<T, Req extends ClientRequest = ClientRequest> {
11
- <Type extends T, R extends Req = Req, P extends AbstractResponse<Type> = AbstractResponse<Type>>(req?: Partial<R>, res?: P): Promise<[Type, EntrypointOutcome]>;
24
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>;
25
+ }
26
+ export interface EntrypointInvoke<T, Req extends ClientRequest = ClientRequest> {
27
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<EntrypointReply<Type>>;
28
+ }
29
+ export interface EntrypointReply<T> {
30
+ value: T;
31
+ outcome: EntrypointOutcome;
32
+ }
33
+ export interface EntrypointUrl<Req extends ClientRequest = ClientRequest> {
34
+ <R extends Req = Req>(req?: Partial<R>, opts?: EntrypointUrlOptions): Promise<string>;
35
+ }
36
+ export interface EntrypointUrlOptions {
37
+ /** Force a fully qualified URL even when the route belongs to the current service. */
38
+ absolute?: boolean;
12
39
  }
13
40
  export interface EntrypointFilter<Req extends AbstractRequest = AbstractRequest> {
14
41
  <R extends Req>(req?: Partial<R>): Promise<boolean>;
15
42
  }
16
43
  export interface ClientRequest<T extends {} = {}> extends AbstractRequest<T> {
17
- full?: boolean;
18
44
  }
19
45
  export interface ClientEntrypointOptions extends CommonEntrypointOptions {
20
- /**
21
- * Force entrypoint to be elevated even if it is already elevated
22
- */
23
- force?: boolean;
24
46
  routeOptions?: ClientRouteOptions;
25
47
  validateOnCall?: boolean;
26
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE9J,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,aAAa,GAAG,aAAa,CAAE,SAAQ,gBAAgB;IACzG,KAAK,EAAE,gBAAgB,CAAA;IACvB,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC7B,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,MAAM,CAAA;IACtC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,GAAG,SAAS,aAAa,GAAG,aAAa;IAC1E,CACE,IAAI,SAAS,CAAC,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,CAAC,SAAS,gBAAgB,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAC9F,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAA;CACjE;AAED,MAAM,WAAW,gBAAgB,CAAC,GAAG,SAAS,eAAe,GAAG,eAAe;IAC7E,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe;IAC3E,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe;IACpF,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,iBAAiB,CAAA;CAC9C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE5I,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,aAAa,GAAG,aAAa,CAAE,SAAQ,gBAAgB;IACzG,KAAK,EAAE,gBAAgB,CAAA;IACvB;;;OAGG;IACH,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B;;;OAGG;IACH,MAAM,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9B;;;OAGG;IACH,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACrB,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IAC7B,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;CACrC;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,GAAG,SAAS,aAAa,GAAG,aAAa;IAC1E,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvE;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,GAAG,SAAS,aAAa,GAAG,aAAa;IAC5E,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;CACxF;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,CAAC,CAAA;IACR,OAAO,EAAE,iBAAiB,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa,CAAC,GAAG,SAAS,aAAa,GAAG,aAAa;IACtE,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACtF;AAED,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB,CAAC,GAAG,SAAS,eAAe,GAAG,eAAe;IAC7E,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;CAC3E;AAED,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe;IAC3E,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe;IACpF,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,iBAAiB,CAAA;CAC9C"}
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGxE,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACxE,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;AAEH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,YACxE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,SACnE,uBAAuB,GAAG,OAAO,KACvC,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,uBAAuB,GAAG,SAAS,CAShF,CAAA"}
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGxE,OAAO,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACxE,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;AAEH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAClF,UAAU,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,uBAAuB,GAAG,OAAO,EAC1E,OAAO,uBAAuB,GAAG,OAAO,KACvC,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,EAAE,uBAAuB,GAAG,SAAS,CAShF,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import type { AbstractRequest, EntrypointHandler } from '@owlmeans/entrypoint';
2
- import type { EntrypointCall, ClientEntrypointOptions, EntrypointRef, ClientRequest } from '../types.js';
2
+ import type { EntrypointInvoke, EntrypointUrlOptions, ClientEntrypointOptions, EntrypointRef, ClientRequest } from '../types.js';
3
3
  export declare const apiHandler: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>) => EntrypointHandler;
4
- export declare const apiCall: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointCall<T, R>;
5
- export declare const urlCall: <T, R extends ClientRequest = ClientRequest>(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointCall<T, R>;
4
+ export declare const apiInvoke: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R>;
5
+ export declare const entrypointUrl: <T, R extends ClientRequest = ClientRequest>(ref: EntrypointRef<T, R>, req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string>;
6
6
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE9E,OAAO,KAAK,EAAoB,cAAc,EAAE,uBAAuB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAW1H,eAAO,MAAM,UAAU,EAAE,CACvB,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAC9C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,iBA0B9B,CAAA;AAED,eAAO,MAAM,OAAO,EAAE,CACpB,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAC9C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,uBAAuB,KAAK,cAAc,CAAC,CAAC,EAAE,CAAC,CAyDvD,CAAA;AAE3B,eAAO,MAAM,OAAO,EAAE,CACpB,CAAC,EAAE,CAAC,SAAS,aAAa,GAAG,aAAa,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,uBAAuB,KAAK,cAAc,CAAC,CAAC,EAAE,CAAC,CA4BjF,CAAA"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAuB,MAAM,sBAAsB,CAAA;AAEnG,OAAO,KAAK,EAAoB,gBAAgB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAWlJ,eAAO,MAAM,UAAU,EAAE,CACvB,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAC9C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,iBAqC9B,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,CACtB,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAC9C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,uBAAuB,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAoDvD,CAAA;AAE7B,eAAO,MAAM,aAAa,EAAE,CAC1B,CAAC,EAAE,CAAC,SAAS,aAAa,GAAG,aAAa,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,CA6B3F,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_KEY } from '@owlmeans/client-config';
2
- import { EntrypointOutcome, provideResponse } from '@owlmeans/entrypoint';
2
+ import { EntrypointOutcome, provideResponse, transportAlias } from '@owlmeans/entrypoint';
3
3
  import { validate } from './entrypoint.js';
4
4
  import { extractParams } from '@owlmeans/client-route';
5
5
  import { PARAM } from '@owlmeans/route';
@@ -13,20 +13,28 @@ export const apiHandler = (ref) => async (req, res) => {
13
13
  throw new SyntaxError('No webService provided');
14
14
  }
15
15
  const ep = context.entrypoint(req.alias);
16
- const route = await ep.route.resolve(context);
17
- let alias = typeof context.cfg.webService === 'string'
16
+ // A route names the protocol it answers on, and a protocol may be carried by something other than
17
+ // HTTP — a queue, say. Whatever is bound under this protocol takes the call, so a consumer writes
18
+ // `ep.call(...)` and never learns which of them ran.
19
+ const transport = transportAlias(ep.route.route.protocol);
20
+ if (context.hasService(transport)) {
21
+ req.path = ep.path();
22
+ return context.service(transport).handle(req, res);
23
+ }
24
+ // Which web client carries this call is decided by the service the route answers on — the one it
25
+ // names, or the one the context picks for its app type when it names none.
26
+ const route = ep.service();
27
+ const alias = typeof context.cfg.webService === 'string'
18
28
  ? context.cfg.webService
19
- : (route.service != null
20
- ? context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY]
21
- : context.cfg.webService[DEFAULT_KEY]);
29
+ : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY];
22
30
  if (alias == null) {
23
31
  throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`);
24
32
  }
25
33
  const service = context.service(alias);
26
- req.path = ep.getPath();
34
+ req.path = ep.path();
27
35
  return service.handler(req, res);
28
36
  };
29
- export const apiCall = (ref, opts) => (async (req, res) => {
37
+ export const apiInvoke = (ref, opts) => (async (req) => {
30
38
  const ep = ref.ref;
31
39
  if (ep == null) {
32
40
  throw new SyntaxError('Try to make API call before the entrypoint is created');
@@ -35,9 +43,8 @@ export const apiCall = (ref, opts) => (async (req, res) => {
35
43
  if (ctx == null) {
36
44
  throw new SyntaxError(`No context provided in apiCall for ${ep.alias} entrypoint`);
37
45
  }
38
- await ep.route.resolve(ctx);
39
46
  if (req?.canceled) {
40
- return;
47
+ return { value: null, outcome: EntrypointOutcome.Ok };
41
48
  }
42
49
  const request = {
43
50
  alias: ep.alias,
@@ -47,7 +54,7 @@ export const apiCall = (ref, opts) => (async (req, res) => {
47
54
  query: req?.query ?? {},
48
55
  host: req?.host,
49
56
  base: req?.base,
50
- path: ep.getPath(),
57
+ path: ep.path(),
51
58
  timeout: req?.timeout,
52
59
  signal: req?.signal,
53
60
  };
@@ -67,10 +74,6 @@ export const apiCall = (ref, opts) => (async (req, res) => {
67
74
  throw e;
68
75
  }
69
76
  }
70
- if (res != null) {
71
- await apiHandler(ref)(request, res);
72
- return;
73
- }
74
77
  const reply = provideResponse();
75
78
  if (ctx == null && ep.ctx == null) {
76
79
  throw new SyntaxError(`Use entrypoint ${ep.alias} without context`);
@@ -79,28 +82,31 @@ export const apiCall = (ref, opts) => (async (req, res) => {
79
82
  if (reply.error != null) {
80
83
  throw reply.error;
81
84
  }
82
- return [reply.value ?? null, reply.outcome ?? EntrypointOutcome.Ok];
85
+ return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok };
83
86
  });
84
- export const urlCall = ref => async (req, res) => {
87
+ export const entrypointUrl = async (ref, req, opts) => {
85
88
  const ep = ref.ref;
86
89
  if (ep == null) {
87
90
  throw new SyntaxError('Try to make URL before the entrypoint is created');
88
91
  }
89
92
  const ctx = ep.ctx;
90
93
  if (ctx == null) {
91
- throw new SyntaxError(`No context provided in urlCall for ${ep.alias} entrypoint`);
94
+ throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`);
92
95
  }
93
- await ep.route.resolve(ctx);
94
- const pathParams = extractParams(ep.getPath());
96
+ // The base is left off here: an in-service URL is addressed relative to it, and the absolute
97
+ // branch below has `makeUrl` prepend it.
98
+ const epPath = ep.path();
99
+ const pathParams = extractParams(epPath);
95
100
  let path = pathParams.reduce((p, param) => {
96
101
  return p.replace(`${PARAM}${param}`, `${req?.params?.[param]}`);
97
- }, ep.getPath()) + (req?.query != null ? `?${stringify(req?.query)}` : '');
98
- if (ep.route.route.service !== null && (ctx.cfg.service !== ep.route.route.service
99
- || req?.full === true)) {
102
+ }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '');
103
+ // Locality is a question about the RESOLVED service, not about what the declaration happens to
104
+ // name: a route that names no service belongs to the asking context, and addressing it absolutely
105
+ // would turn in-app navigation into a full page load.
106
+ if (!ep.isLocal() || opts?.absolute === true) {
100
107
  const helper = makeSecurityHelper(ctx);
101
- path = helper.makeUrl(ep.route.route, path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
108
+ path = helper.makeUrl(ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
102
109
  }
103
- res?.resolve(path, EntrypointOutcome.Ok);
104
- return [path, EntrypointOutcome.Ok];
110
+ return path;
105
111
  };
106
112
  //# sourceMappingURL=handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAGrD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAEzF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAKrD,MAAM,CAAC,MAAM,UAAU,GAE4B,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC7E,MAAM,QAAQ,GAAG,iCAAiC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAA;IAClE,MAAM,OAAO,GAAG,aAAa,CAAkB,GAAG,CAAC,GAAG,EAAE,GAAc,EAAE,QAAQ,CAAC,CAAA;IAEjF,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,WAAW,CAAC,wBAAwB,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAmB,GAAG,CAAC,KAAK,CAAC,CAAA;IAE1D,kGAAkG;IAClG,kGAAkG;IAClG,qDAAqD;IACrD,MAAM,SAAS,GAAG,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IACzD,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;QAEpB,OAAO,OAAO,CAAC,OAAO,CAAsB,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACzE,CAAC;IAED,iGAAiG;IACjG,2EAA2E;IAC3E,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IAE1B,MAAM,KAAK,GAAuB,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,QAAQ;QAC1E,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU;QACxB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAEhF,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,WAAW,CAAC,oCAAoC,EAAE,CAAC,KAAK,aAAa,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,OAAO,GAAc,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAEjD,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;IAEpB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAU,CAAC,CAAA;AACzC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAGpB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5B,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAA;IAClB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,uDAAuD,CAAC,CAAA;IAChF,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAA;IAClB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,WAAW,CAAC,sCAAsC,EAAE,CAAC,KAAK,aAAa,CAAC,CAAA;IACpF,CAAC;IAED,IAAI,GAAG,EAAE,QAAQ,EAAE,CAAC;QAClB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAA;IACvD,CAAC;IAED,MAAM,OAAO,GAAoB;QAC/B,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,EAAE;QACzB,IAAI,EAAE,GAAG,EAAE,IAAI;QACf,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE;QAC3B,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACvB,IAAI,EAAE,GAAG,EAAE,IAAI;QACf,IAAI,EAAE,GAAG,EAAE,IAAI;QACf,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,OAAO;QACrB,MAAM,EAAE,GAAG,EAAE,MAAM;KACpB,CAAA;IACD,IAAI,GAAG,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;QACzB,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;YAChB,MAAM,EAAE,CAAA;YACR,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;QACzB,CAAC,CAAA;IACH,CAAC;IACD,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;QAC9B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAChB,MAAM,CAAC,CAAA;QACT,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,EAAW,CAAA;IACxC,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE,CAAC,KAAK,kBAAkB,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACrC,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,iBAAiB,CAAC,EAAE,EAAE,CAAA;AACvF,CAAC,CAA0B,CAAA;AAE7B,MAAM,CAAC,MAAM,aAAa,GAEsE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACvH,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAA;IAClB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,kDAAkD,CAAC,CAAA;IAC3E,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAA;IAClB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,WAAW,CAAC,4CAA4C,EAAE,CAAC,KAAK,aAAa,CAAC,CAAA;IAC1F,CAAC;IAED,6FAA6F;IAC7F,yCAAyC;IACzC,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;IACxB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QACxC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,GAAG,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC,KAAgC,CAAC,EAAE,CAAC,CAAA;IAC5F,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAEpE,+FAA+F;IAC/F,kGAAkG;IAClG,sDAAsD;IACtD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,GAAG,MAAM,CAAC,OAAO,CACnB,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,CACvF,CAAA;IACH,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.10",
3
+ "version": "0.1.18-rc.12",
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.9",
32
- "@owlmeans/client-config": "^0.1.18-rc.8",
33
- "@owlmeans/client-context": "^0.1.18-rc.9",
34
- "@owlmeans/client-route": "^0.1.18-rc.9",
35
- "@owlmeans/config": "^0.1.18-rc.8",
36
- "@owlmeans/context": "^0.1.18-rc.6",
37
- "@owlmeans/entrypoint": "^0.1.18-rc.8",
38
- "@owlmeans/error": "^0.1.18-rc.6",
39
- "@owlmeans/route": "^0.1.18-rc.6",
31
+ "@owlmeans/api": "^0.1.18-rc.12",
32
+ "@owlmeans/client-config": "^0.1.18-rc.11",
33
+ "@owlmeans/client-context": "^0.1.18-rc.12",
34
+ "@owlmeans/client-route": "^0.1.18-rc.12",
35
+ "@owlmeans/config": "^0.1.18-rc.11",
36
+ "@owlmeans/context": "^0.1.18-rc.7",
37
+ "@owlmeans/entrypoint": "^0.1.18-rc.10",
38
+ "@owlmeans/error": "^0.1.18-rc.7",
39
+ "@owlmeans/route": "^0.1.18-rc.8",
40
40
  "ajv-formats": "^3.0.1",
41
41
  "qs": "^6.13.0"
42
42
  },
package/src/entrypoint.ts CHANGED
@@ -3,15 +3,13 @@ import type { ClientEntrypoint, ClientEntrypointOptions, EntrypointRef, RefedEnt
3
3
  import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
4
4
  import { isEntrypoint, makeBasicEntrypoint, normalizeHelperParams, validate } from './utils/entrypoint.js'
5
5
  import { isClientRouteModel, route } from '@owlmeans/client-route'
6
- import { apiCall, apiHandler, urlCall } from './utils/handler.js'
6
+ import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js'
7
7
  import { AppType } from '@owlmeans/context'
8
- import type { BasicContext } from '@owlmeans/context'
9
- import { normalizePath } from '@owlmeans/route'
10
- import type { CommonRouteModel } from '@owlmeans/route'
8
+ import type { RouteModel } from '@owlmeans/route'
11
9
  import { provideRequest } from './helper.js'
12
10
 
13
11
  export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
14
- arg: CommonEntrypoint | ClientRouteModel | CommonRouteModel,
12
+ arg: CommonEntrypoint | ClientRouteModel | RouteModel,
15
13
  handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean,
16
14
  opts?: ClientEntrypointOptions | boolean
17
15
  ): ClientEntrypoint<T, R> => {
@@ -30,7 +28,8 @@ export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
30
28
  const routeModel = route(arg.route, opts?.routeOptions)
31
29
  _entrypoint = arg as ClientEntrypoint<T, R>
32
30
  _entrypoint.route = routeModel
33
- _entrypoint.guards = opts?.guards ?? arg.guards
31
+ // Elevating adds guards, it never swaps them: what the entrypoint declared still applies.
32
+ _entrypoint.guards = [...new Set([...(arg.guards ?? []), ...(opts?.guards ?? [])])]
34
33
  _entrypoint.filter = opts?.filter ?? arg.filter
35
34
  _entrypoint.gate = opts?.gate ?? arg.gate
36
35
  _entrypoint.gateParams = opts?.gateParams ?? arg.gateParams
@@ -45,16 +44,27 @@ export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
45
44
  _entrypoint.route = _route
46
45
  }
47
46
 
48
- _entrypoint.getPath = (partial?: boolean) =>
49
- partial === true ? normalizePath(_entrypoint.route.route.partialPath) : _entrypoint.route.route.path
47
+ _entrypoint.url = ((req?: Partial<R>, urlOpts?: { absolute?: boolean }) =>
48
+ entrypointUrl<T, R>(entrypointHandle, req as never, urlOpts)) as ClientEntrypoint<T, R>['url']
50
49
 
51
- _entrypoint.call = handler != null ? urlCall<T, R>(entrypointHandle, opts) : apiCall<T, R>(entrypointHandle, opts)
50
+ // An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
51
+ // wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
52
+ _entrypoint.invoke = (handler != null
53
+ ? (async () => {
54
+ throw new SyntaxError(
55
+ `Entrypoint ${_entrypoint.alias} renders a screen - address it with url() instead of call()/invoke()`
56
+ )
57
+ })
58
+ : apiInvoke<T, R>(entrypointHandle, opts)) as ClientEntrypoint<T, R>['invoke']
59
+
60
+ _entrypoint.call = (async (req?: Partial<R>) =>
61
+ (await _entrypoint.invoke(req)).value) as ClientEntrypoint<T, R>['call']
52
62
 
53
63
  _entrypoint.request = ((request: R): R => {
54
64
  if (entrypointHandle.ref == null) {
55
65
  throw SyntaxError(`Try to request uninitialized entrypoint ${JSON.stringify(arg)}`)
56
66
  }
57
- const _request = provideRequest(entrypointHandle.ref.getAlias(), entrypointHandle.ref.getPath()) as R
67
+ const _request = provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path()) as R
58
68
 
59
69
  request != null && Object.entries(request).forEach(([key, value]) => {
60
70
  _request[key as keyof R] = value
@@ -67,13 +77,6 @@ export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
67
77
 
68
78
  _entrypoint.validate = validate(entrypointHandle)
69
79
 
70
- _entrypoint.reinitializeContext = <T>(context: BasicContext<any>) => {
71
- const newEntrypoint = entrypoint(_entrypoint.route, handler, opts)
72
- newEntrypoint.ctx = context
73
-
74
- return newEntrypoint as T
75
- }
76
-
77
80
  entrypointHandle.ref = _entrypoint
78
81
 
79
82
  return _entrypoint
package/src/helper.ts CHANGED
@@ -1,10 +1,16 @@
1
1
  import type { ClientEntrypoint, ClientEntrypointOptions, RefedEntrypointHandler } from './types.js'
2
2
  import { entrypoint } from './entrypoint.js'
3
- import { isClientRouteModel } from '@owlmeans/client-route'
4
3
  import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
5
4
  import { normalizeHelperParams } from './utils/entrypoint.js'
6
5
  import type { JSONSchemaType } from "ajv"
7
6
 
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
+ */
8
14
  export const elevate = <T = {}, R extends AbstractRequest = AbstractRequest>(
9
15
  entrypoints: (CommonEntrypoint | ClientEntrypoint<T, R>)[],
10
16
  alias: string,
@@ -17,9 +23,6 @@ export const elevate = <T = {}, R extends AbstractRequest = AbstractRequest>(
17
23
  if (idx === -1) {
18
24
  throw new SyntaxError(`Entrypoint with alias ${alias} not present`)
19
25
  }
20
- if (isClientRouteModel(entrypoints[idx].route) && opts?.force !== true) {
21
- throw new SyntaxError(`Entrypoint with alias ${alias} is already elevated`)
22
- }
23
26
 
24
27
  entrypoints[idx] = entrypoint(entrypoints[idx], handler, opts)
25
28
 
package/src/types.ts CHANGED
@@ -1,18 +1,47 @@
1
1
  import type { ClientRouteModel, ClientRouteOptions } from '@owlmeans/client-route'
2
- import type { AbstractRequest, AbstractResponse, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler, EntrypointOutcome } from '@owlmeans/entrypoint'
2
+ import type { AbstractRequest, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler, EntrypointOutcome } from '@owlmeans/entrypoint'
3
3
 
4
4
  export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientRequest> extends CommonEntrypoint {
5
5
  route: ClientRouteModel
6
+ /**
7
+ * Address the entrypoint and resolve to what it answered. The reply's error is thrown, so a
8
+ * caller that only needs the value never inspects an outcome.
9
+ */
6
10
  call: EntrypointCall<T, R>
11
+ /**
12
+ * The same round trip as {@link ClientEntrypoint.call}, resolving to the value AND the outcome.
13
+ * Use it only where the outcome decides what happens next.
14
+ */
15
+ invoke: EntrypointInvoke<T, R>
16
+ /**
17
+ * Build the URL this entrypoint addresses, with `:params` filled in and the query appended.
18
+ * Absolute when the route belongs to another service, or when `absolute` is asked for.
19
+ */
20
+ url: EntrypointUrl<R>
7
21
  validate: EntrypointFilter<R>
8
- getPath: (partial?: boolean) => string
9
22
  request: (request?: Partial<R>) => R
10
23
  }
11
24
 
12
25
  export interface EntrypointCall<T, Req extends ClientRequest = ClientRequest> {
13
- <
14
- Type extends T, R extends Req = Req, P extends AbstractResponse<Type> = AbstractResponse<Type>
15
- >(req?: Partial<R>, res?: P): Promise<[Type, EntrypointOutcome]>
26
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>
27
+ }
28
+
29
+ export interface EntrypointInvoke<T, Req extends ClientRequest = ClientRequest> {
30
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<EntrypointReply<Type>>
31
+ }
32
+
33
+ export interface EntrypointReply<T> {
34
+ value: T
35
+ outcome: EntrypointOutcome
36
+ }
37
+
38
+ export interface EntrypointUrl<Req extends ClientRequest = ClientRequest> {
39
+ <R extends Req = Req>(req?: Partial<R>, opts?: EntrypointUrlOptions): Promise<string>
40
+ }
41
+
42
+ export interface EntrypointUrlOptions {
43
+ /** Force a fully qualified URL even when the route belongs to the current service. */
44
+ absolute?: boolean
16
45
  }
17
46
 
18
47
  export interface EntrypointFilter<Req extends AbstractRequest = AbstractRequest> {
@@ -20,14 +49,9 @@ export interface EntrypointFilter<Req extends AbstractRequest = AbstractRequest>
20
49
  }
21
50
 
22
51
  export interface ClientRequest<T extends {} = {}> extends AbstractRequest<T> {
23
- full?: boolean
24
52
  }
25
53
 
26
54
  export interface ClientEntrypointOptions extends CommonEntrypointOptions {
27
- /**
28
- * Force entrypoint to be elevated even if it is already elevated
29
- */
30
- force?: boolean
31
55
  routeOptions?: ClientRouteOptions
32
56
  validateOnCall?: boolean
33
57
  }
@@ -1,9 +1,9 @@
1
1
  import type { ApiClient } from '@owlmeans/api'
2
2
  import { DEFAULT_KEY } from '@owlmeans/client-config'
3
3
  import type { ClientConfig, ClientContext } from '@owlmeans/client-context'
4
- import type { AbstractRequest, EntrypointHandler } from '@owlmeans/entrypoint'
5
- import { EntrypointOutcome, provideResponse } from '@owlmeans/entrypoint'
6
- import type { ClientEntrypoint, EntrypointCall, ClientEntrypointOptions, EntrypointRef, ClientRequest } from '../types.js'
4
+ import type { AbstractRequest, EntrypointHandler, EntrypointTransport } from '@owlmeans/entrypoint'
5
+ import { EntrypointOutcome, provideResponse, transportAlias } from '@owlmeans/entrypoint'
6
+ import type { ClientEntrypoint, EntrypointInvoke, EntrypointUrlOptions, ClientEntrypointOptions, EntrypointRef, ClientRequest } from '../types.js'
7
7
  import { validate } from './entrypoint.js'
8
8
  import { extractParams } from '@owlmeans/client-route'
9
9
  import { PARAM } from '@owlmeans/route'
@@ -25,13 +25,24 @@ export const apiHandler: <
25
25
  }
26
26
 
27
27
  const ep = context.entrypoint<ClientEntrypoint>(req.alias)
28
- const route = await ep.route.resolve<Config, Context>(context)
29
28
 
30
- let alias: string | undefined = typeof context.cfg.webService === 'string'
29
+ // A route names the protocol it answers on, and a protocol may be carried by something other than
30
+ // HTTP — a queue, say. Whatever is bound under this protocol takes the call, so a consumer writes
31
+ // `ep.call(...)` and never learns which of them ran.
32
+ const transport = transportAlias(ep.route.route.protocol)
33
+ if (context.hasService(transport)) {
34
+ req.path = ep.path()
35
+
36
+ return context.service<EntrypointTransport>(transport).handle(req, res)
37
+ }
38
+
39
+ // Which web client carries this call is decided by the service the route answers on — the one it
40
+ // names, or the one the context picks for its app type when it names none.
41
+ const route = ep.service()
42
+
43
+ const alias: string | undefined = typeof context.cfg.webService === 'string'
31
44
  ? context.cfg.webService
32
- : (route.service != null
33
- ? context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY]
34
- : context.cfg.webService[DEFAULT_KEY])
45
+ : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY]
35
46
 
36
47
  if (alias == null) {
37
48
  throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`)
@@ -39,15 +50,15 @@ export const apiHandler: <
39
50
 
40
51
  const service: ApiClient = context.service(alias)
41
52
 
42
- req.path = ep.getPath()
53
+ req.path = ep.path()
43
54
 
44
55
  return service.handler(req, res as any)
45
56
  }
46
57
 
47
- export const apiCall: <
58
+ export const apiInvoke: <
48
59
  T, R extends AbstractRequest = AbstractRequest
49
- >(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointCall<T, R> =
50
- (ref, opts) => (async (req, res) => {
60
+ >(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R> =
61
+ (ref, opts) => (async (req) => {
51
62
  const ep = ref.ref
52
63
  if (ep == null) {
53
64
  throw new SyntaxError('Try to make API call before the entrypoint is created')
@@ -56,10 +67,9 @@ export const apiCall: <
56
67
  if (ctx == null) {
57
68
  throw new SyntaxError(`No context provided in apiCall for ${ep.alias} entrypoint`)
58
69
  }
59
- await ep.route.resolve(ctx)
60
70
 
61
71
  if (req?.canceled) {
62
- return
72
+ return { value: null, outcome: EntrypointOutcome.Ok }
63
73
  }
64
74
 
65
75
  const request: AbstractRequest = {
@@ -70,7 +80,7 @@ export const apiCall: <
70
80
  query: req?.query ?? {},
71
81
  host: req?.host,
72
82
  base: req?.base,
73
- path: ep.getPath(),
83
+ path: ep.path(),
74
84
  timeout: req?.timeout,
75
85
  signal: req?.signal,
76
86
  }
@@ -89,10 +99,6 @@ export const apiCall: <
89
99
  throw e
90
100
  }
91
101
  }
92
- if (res != null) {
93
- await apiHandler(ref)(request, res)
94
- return
95
- }
96
102
  const reply = provideResponse<unknown>()
97
103
  if (ctx == null && ep.ctx == null) {
98
104
  throw new SyntaxError(`Use entrypoint ${ep.alias} without context`)
@@ -102,37 +108,38 @@ export const apiCall: <
102
108
  throw reply.error
103
109
  }
104
110
 
105
- return [reply.value ?? null, reply.outcome ?? EntrypointOutcome.Ok]
106
- }) as EntrypointCall<any>
111
+ return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok }
112
+ }) as EntrypointInvoke<any>
107
113
 
108
- export const urlCall: <
114
+ export const entrypointUrl: <
109
115
  T, R extends ClientRequest = ClientRequest
110
- >(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointCall<T, R> = ref => async (req, res) => {
116
+ >(ref: EntrypointRef<T, R>, req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string> = async (ref, req, opts) => {
111
117
  const ep = ref.ref
112
118
  if (ep == null) {
113
119
  throw new SyntaxError('Try to make URL before the entrypoint is created')
114
120
  }
115
121
  const ctx = ep.ctx
116
122
  if (ctx == null) {
117
- throw new SyntaxError(`No context provided in urlCall for ${ep.alias} entrypoint`)
123
+ throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`)
118
124
  }
119
- await ep.route.resolve(ctx)
120
125
 
121
- const pathParams = extractParams(ep.getPath())
126
+ // The base is left off here: an in-service URL is addressed relative to it, and the absolute
127
+ // branch below has `makeUrl` prepend it.
128
+ const epPath = ep.path()
129
+ const pathParams = extractParams(epPath)
122
130
  let path = pathParams.reduce((p, param) => {
123
131
  return p.replace(`${PARAM}${param}`, `${req?.params?.[param as keyof typeof req.params]}`)
124
- }, ep.getPath()) + (req?.query != null ? `?${stringify(req?.query)}` : '')
132
+ }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '')
125
133
 
126
- if (ep.route.route.service !== null && (
127
- ctx.cfg.service !== ep.route.route.service
128
- || req?.full === true)) {
134
+ // Locality is a question about the RESOLVED service, not about what the declaration happens to
135
+ // name: a route that names no service belongs to the asking context, and addressing it absolutely
136
+ // would turn in-app navigation into a full page load.
137
+ if (!ep.isLocal() || opts?.absolute === true) {
129
138
  const helper = makeSecurityHelper(ctx)
130
139
  path = helper.makeUrl(
131
- ep.route.route, path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure }
140
+ ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure }
132
141
  )
133
142
  }
134
143
 
135
- res?.resolve(path as any, EntrypointOutcome.Ok)
136
-
137
- return [path as any, EntrypointOutcome.Ok]
144
+ return path
138
145
  }