@owlmeans/client-entrypoint 0.1.18-rc.2 → 0.1.18-rc.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,CAwDvD,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,CAmC3F,CAAA"}
@@ -1,8 +1,8 @@
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
- import { PARAM } from '@owlmeans/route';
5
+ import { PARAM, RouteMethod, RouteProtocols } from '@owlmeans/route';
6
6
  import { stringify } from 'qs';
7
7
  import { assertContext } from '@owlmeans/context';
8
8
  import { makeSecurityHelper } from '@owlmeans/config';
@@ -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,19 +43,22 @@ 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,
44
51
  params: req?.params ?? {},
45
- body: req?.body,
52
+ // JSON transports must send a body for mutation methods even when the contract has no
53
+ // payload. Keeping that rule here makes every typed caller use `call({ params })`, never
54
+ // an SDK-specific `{ body: {} }` workaround.
55
+ body: req?.body ?? ([RouteMethod.POST, RouteMethod.PUT, RouteMethod.PATCH]
56
+ .includes(ep.route.route.method ?? RouteMethod.GET) ? {} : undefined),
46
57
  headers: req?.headers ?? {},
47
58
  query: req?.query ?? {},
48
59
  host: req?.host,
49
60
  base: req?.base,
50
- path: ep.getPath(),
61
+ path: ep.path(),
51
62
  timeout: req?.timeout,
52
63
  signal: req?.signal,
53
64
  };
@@ -67,10 +78,6 @@ export const apiCall = (ref, opts) => (async (req, res) => {
67
78
  throw e;
68
79
  }
69
80
  }
70
- if (res != null) {
71
- await apiHandler(ref)(request, res);
72
- return;
73
- }
74
81
  const reply = provideResponse();
75
82
  if (ctx == null && ep.ctx == null) {
76
83
  throw new SyntaxError(`Use entrypoint ${ep.alias} without context`);
@@ -79,28 +86,36 @@ export const apiCall = (ref, opts) => (async (req, res) => {
79
86
  if (reply.error != null) {
80
87
  throw reply.error;
81
88
  }
82
- return [reply.value ?? null, reply.outcome ?? EntrypointOutcome.Ok];
89
+ return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok };
83
90
  });
84
- export const urlCall = ref => async (req, res) => {
91
+ export const entrypointUrl = async (ref, req, opts) => {
85
92
  const ep = ref.ref;
86
93
  if (ep == null) {
87
94
  throw new SyntaxError('Try to make URL before the entrypoint is created');
88
95
  }
89
96
  const ctx = ep.ctx;
90
97
  if (ctx == null) {
91
- throw new SyntaxError(`No context provided in urlCall for ${ep.alias} entrypoint`);
98
+ throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`);
92
99
  }
93
- await ep.route.resolve(ctx);
94
- const pathParams = extractParams(ep.getPath());
100
+ // The base is left off here: an in-service URL is addressed relative to it, and the absolute
101
+ // branch below has `makeUrl` prepend it.
102
+ const epPath = ep.path();
103
+ const pathParams = extractParams(epPath);
95
104
  let path = pathParams.reduce((p, param) => {
96
105
  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)) {
106
+ }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '');
107
+ // A socket address is always absolute, whoever owns the route. `new WebSocket(path)` resolves a
108
+ // relative value against the PAGE's origin, which in a split deployment is the web host and not
109
+ // the service that answers the upgrade — so the handshake goes somewhere that never speaks it
110
+ // and dies on a gateway timeout. Only a same-origin HTTP route benefits from staying relative.
111
+ const socket = ep.route.route.protocol === RouteProtocols.SOCKET;
112
+ // Locality is a question about the RESOLVED service, not about what the declaration happens to
113
+ // name: a route that names no service belongs to the asking context, and addressing it absolutely
114
+ // would turn in-app navigation into a full page load.
115
+ if (socket || !ep.isLocal() || opts?.absolute === true) {
100
116
  const helper = makeSecurityHelper(ctx);
101
- path = helper.makeUrl(ep.route.route, path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
117
+ path = helper.makeUrl(ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
102
118
  }
103
- res?.resolve(path, EntrypointOutcome.Ok);
104
- return [path, EntrypointOutcome.Ok];
119
+ return path;
105
120
  };
106
121
  //# 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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-entrypoint",
3
- "version": "0.1.18-rc.2",
3
+ "version": "0.1.18-rc.21",
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.2",
32
- "@owlmeans/client-config": "^0.1.18-rc.2",
33
- "@owlmeans/client-context": "^0.1.18-rc.2",
34
- "@owlmeans/client-route": "^0.1.18-rc.2",
35
- "@owlmeans/config": "^0.1.18-rc.2",
36
- "@owlmeans/context": "^0.1.18-rc.2",
37
- "@owlmeans/entrypoint": "^0.1.18-rc.2",
38
- "@owlmeans/error": "^0.1.18-rc.2",
39
- "@owlmeans/route": "^0.1.18-rc.2",
31
+ "@owlmeans/api": "^0.1.18-rc.21",
32
+ "@owlmeans/client-config": "^0.1.18-rc.20",
33
+ "@owlmeans/client-context": "^0.1.18-rc.21",
34
+ "@owlmeans/client-route": "^0.1.18-rc.21",
35
+ "@owlmeans/config": "^0.1.18-rc.20",
36
+ "@owlmeans/context": "^0.1.18-rc.16",
37
+ "@owlmeans/entrypoint": "^0.1.18-rc.19",
38
+ "@owlmeans/error": "^0.1.18-rc.16",
39
+ "@owlmeans/route": "^0.1.18-rc.17",
40
40
  "ajv-formats": "^3.0.1",
41
41
  "qs": "^6.13.0"
42
42
  },
package/src/entrypoint.ts CHANGED
@@ -1,60 +1,54 @@
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 { isEntrypoint, makeBasicEntrypoint, normalizeHelperParams, validate } from './utils/entrypoint.js'
5
- import { isClientRouteModel, route } from '@owlmeans/client-route'
6
- import { apiCall, apiHandler, urlCall } from './utils/handler.js'
3
+ import { validate } from './utils/entrypoint.js'
4
+ import { route } from '@owlmeans/client-route'
5
+ import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js'
7
6
  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'
11
7
  import { provideRequest } from './helper.js'
12
8
 
13
- export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
14
- arg: CommonEntrypoint | ClientRouteModel | CommonRouteModel,
15
- handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean,
16
- opts?: ClientEntrypointOptions | boolean
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,
17
14
  ): ClientEntrypoint<T, R> => {
18
15
  const entrypointHandle: EntrypointRef<T, R> = { ref: undefined }
19
16
 
20
17
  let _entrypoint: ClientEntrypoint<T, R>
21
18
 
22
- ;[handler, opts] = normalizeHelperParams(handler, opts)
23
-
24
- const _handler = handler as RefedEntrypointHandler<T, R> | undefined ??
25
- (('route' in arg.route ? arg.route.route.type : arg.route.type)
26
- === AppType.Backend ? apiHandler : undefined)
27
-
28
- if (isEntrypoint(arg)) {
29
- assertExplicitHandler(arg.route.route.type, handler as RefedEntrypointHandler<T, R>)
30
- const routeModel = route(arg.route, opts?.routeOptions)
31
- _entrypoint = arg as ClientEntrypoint<T, R>
32
- _entrypoint.route = routeModel
33
- _entrypoint.guards = opts?.guards ?? arg.guards
34
- _entrypoint.filter = opts?.filter ?? arg.filter
35
- _entrypoint.gate = opts?.gate ?? arg.gate
36
- _entrypoint.gateParams = opts?.gateParams ?? arg.gateParams
37
- } else if (isClientRouteModel(arg)) {
38
- assertExplicitHandler(arg.route.type, handler as RefedEntrypointHandler<T, R>)
39
- _entrypoint = makeBasicEntrypoint(arg, { ...opts }) as ClientEntrypoint<T, R>
40
- _entrypoint.route = arg
41
- } else {
42
- assertExplicitHandler(arg.route.type, handler as RefedEntrypointHandler<T, R>)
43
- const _route = route(arg, opts?.routeOptions)
44
- _entrypoint = makeBasicEntrypoint(_route, { ...opts }) as ClientEntrypoint<T, R>
45
- _entrypoint.route = _route
46
- }
47
-
48
- _entrypoint.getPath = (partial?: boolean) =>
49
- partial === true ? normalizePath(_entrypoint.route.route.partialPath) : _entrypoint.route.route.path
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
30
+
31
+ _entrypoint.url = ((req?: Partial<R>, urlOpts?: { absolute?: boolean }) =>
32
+ entrypointUrl<T, R>(entrypointHandle, req as never, urlOpts)) as ClientEntrypoint<T, R>['url']
33
+
34
+ // An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
35
+ // wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
36
+ _entrypoint.invoke = (handler != null
37
+ ? (async () => {
38
+ throw new SyntaxError(
39
+ `Entrypoint ${_entrypoint.alias} renders a screen - address it with url() instead of call()/invoke()`
40
+ )
41
+ })
42
+ : apiInvoke<T, R>(entrypointHandle, opts)) as ClientEntrypoint<T, R>['invoke']
50
43
 
51
- _entrypoint.call = handler != null ? urlCall<T, R>(entrypointHandle, opts) : apiCall<T, R>(entrypointHandle, opts)
44
+ _entrypoint.call = (async (req?: Partial<R>) =>
45
+ (await _entrypoint.invoke(req)).value) as ClientEntrypoint<T, R>['call']
52
46
 
53
47
  _entrypoint.request = ((request: R): R => {
54
48
  if (entrypointHandle.ref == null) {
55
49
  throw SyntaxError(`Try to request uninitialized entrypoint ${JSON.stringify(arg)}`)
56
50
  }
57
- const _request = provideRequest(entrypointHandle.ref.getAlias(), entrypointHandle.ref.getPath()) as R
51
+ const _request = provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path()) as R
58
52
 
59
53
  request != null && Object.entries(request).forEach(([key, value]) => {
60
54
  _request[key as keyof R] = value
@@ -67,13 +61,6 @@ export const entrypoint = <T, R extends AbstractRequest = AbstractRequest>(
67
61
 
68
62
  _entrypoint.validate = validate(entrypointHandle)
69
63
 
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
64
  entrypointHandle.ref = _entrypoint
78
65
 
79
66
  return _entrypoint
package/src/helper.ts CHANGED
@@ -1,31 +1,7 @@
1
- import type { ClientEntrypoint, ClientEntrypointOptions, RefedEntrypointHandler } from './types.js'
2
- import { entrypoint } from './entrypoint.js'
3
- import { isClientRouteModel } from '@owlmeans/client-route'
4
- import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
5
- import { normalizeHelperParams } from './utils/entrypoint.js'
1
+ import type { RefedEntrypointHandler } from './types.js'
2
+ import type { AbstractRequest } from '@owlmeans/entrypoint'
6
3
  import type { JSONSchemaType } from "ajv"
7
4
 
8
- export const elevate = <T = {}, R extends AbstractRequest = AbstractRequest>(
9
- entrypoints: (CommonEntrypoint | ClientEntrypoint<T, R>)[],
10
- alias: string,
11
- handler?: RefedEntrypointHandler<T, R> | ClientEntrypointOptions | boolean,
12
- opts?: ClientEntrypointOptions | boolean
13
- ): ClientEntrypoint<T, R>[] => {
14
- [handler, opts] = normalizeHelperParams(handler, opts)
15
-
16
- const idx = entrypoints.findIndex(({ route }) => route.route.alias === alias)
17
- if (idx === -1) {
18
- throw new SyntaxError(`Entrypoint with alias ${alias} not present`)
19
- }
20
- if (isClientRouteModel(entrypoints[idx].route) && opts?.force !== true) {
21
- throw new SyntaxError(`Entrypoint with alias ${alias} is already elevated`)
22
- }
23
-
24
- entrypoints[idx] = entrypoint(entrypoints[idx], handler, opts)
25
-
26
- return entrypoints as ClientEntrypoint<T, R>[]
27
- }
28
-
29
5
  export const stab: RefedEntrypointHandler<{}> = () => () => {
30
6
  return void 0 as any
31
7
  }
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- export * from './helper.js'
3
2
  export type * from './types.js'
4
- export * from './entrypoint.js'
5
3
  export * from './errors.js'
4
+ export * from './protocol.js'
5
+ export { pickPerSchema, provideRequest, stab } from './helper.js'
@@ -0,0 +1,39 @@
1
+ import { materializeEntrypoint, protocols } from '@owlmeans/entrypoint'
2
+ import type { EntrypointProtocolDeclaration, EntrypointTree } from '@owlmeans/entrypoint'
3
+ import { bindMaterializedEntrypoint } from './entrypoint.js'
4
+ import type {
5
+ ClientEntrypointOptions, ClientProtocolEntrypoint, RefedEntrypointHandler,
6
+ } from './types.js'
7
+
8
+ /** Bind a shared protocol to the client context without changing the declaration itself. */
9
+ export const bind = <Protocol extends EntrypointProtocolDeclaration>(
10
+ protocol: Protocol,
11
+ options?: ClientEntrypointOptions,
12
+ ): ClientProtocolEntrypoint<Protocol> => {
13
+ const bound = Object.assign(bindMaterializedEntrypoint(
14
+ materializeEntrypoint(protocol),
15
+ undefined,
16
+ options,
17
+ ), { protocol })
18
+
19
+ return bound as ClientProtocolEntrypoint<Protocol>
20
+ }
21
+
22
+ /** Materialize every protocol in an exported declaration tree for a browser context. */
23
+ export const bindAll = (tree: EntrypointTree): ClientProtocolEntrypoint<EntrypointProtocolDeclaration>[] =>
24
+ protocols(tree).map(protocol => bind(protocol))
25
+
26
+ /** Bind a frontend protocol to the component that renders it. */
27
+ export const bindScreen = <Protocol extends EntrypointProtocolDeclaration>(
28
+ protocol: Protocol,
29
+ handler: RefedEntrypointHandler,
30
+ options?: ClientEntrypointOptions,
31
+ ): ClientProtocolEntrypoint<Protocol> => {
32
+ const bound = Object.assign(bindMaterializedEntrypoint(
33
+ materializeEntrypoint(protocol),
34
+ handler,
35
+ options,
36
+ ), { protocol })
37
+
38
+ return bound as ClientProtocolEntrypoint<Protocol>
39
+ }
package/src/types.ts CHANGED
@@ -1,18 +1,62 @@
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 {
3
+ AbstractRequest, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler,
4
+ EntrypointOutcome, EntrypointProtocolDeclaration, RegisteredEntrypoint, RequestOf,
5
+ } from '@owlmeans/entrypoint'
3
6
 
4
7
  export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientRequest> extends CommonEntrypoint {
5
8
  route: ClientRouteModel
9
+ /**
10
+ * Address the entrypoint and resolve to what it answered. The reply's error is thrown, so a
11
+ * caller that only needs the value never inspects an outcome.
12
+ */
6
13
  call: EntrypointCall<T, R>
14
+ /**
15
+ * The same round trip as {@link ClientEntrypoint.call}, resolving to the value AND the outcome.
16
+ * Use it only where the outcome decides what happens next.
17
+ */
18
+ invoke: EntrypointInvoke<T, R>
19
+ /**
20
+ * Build the URL this entrypoint addresses, with `:params` filled in and the query appended.
21
+ * Absolute when the route belongs to another service, or when `absolute` is asked for.
22
+ */
23
+ url: EntrypointUrl<R>
7
24
  validate: EntrypointFilter<R>
8
- getPath: (partial?: boolean) => string
9
25
  request: (request?: Partial<R>) => R
10
26
  }
11
27
 
28
+ /**
29
+ * The context-bound client view of a protocol. Unlike the legacy `ClientEntrypoint` generic,
30
+ * its request and reply types are read directly from the declaration and cannot be replaced at a
31
+ * call site.
32
+ */
33
+ export type ClientProtocolEntrypoint<Protocol extends EntrypointProtocolDeclaration> =
34
+ Omit<ClientEntrypoint, 'call' | 'invoke' | 'url' | 'validate' | 'request'>
35
+ & RegisteredEntrypoint<RequestOf<Protocol>, import('@owlmeans/entrypoint').ResponseOf<Protocol>>
36
+ & {
37
+ readonly protocol: Protocol
38
+ }
39
+
12
40
  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]>
41
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>
42
+ }
43
+
44
+ export interface EntrypointInvoke<T, Req extends ClientRequest = ClientRequest> {
45
+ <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<EntrypointReply<Type>>
46
+ }
47
+
48
+ export interface EntrypointReply<T> {
49
+ value: T
50
+ outcome: EntrypointOutcome
51
+ }
52
+
53
+ export interface EntrypointUrl<Req extends ClientRequest = ClientRequest> {
54
+ <R extends Req = Req>(req?: Partial<R>, opts?: EntrypointUrlOptions): Promise<string>
55
+ }
56
+
57
+ export interface EntrypointUrlOptions {
58
+ /** Force a fully qualified URL even when the route belongs to the current service. */
59
+ absolute?: boolean
16
60
  }
17
61
 
18
62
  export interface EntrypointFilter<Req extends AbstractRequest = AbstractRequest> {
@@ -20,14 +64,9 @@ export interface EntrypointFilter<Req extends AbstractRequest = AbstractRequest>
20
64
  }
21
65
 
22
66
  export interface ClientRequest<T extends {} = {}> extends AbstractRequest<T> {
23
- full?: boolean
24
67
  }
25
68
 
26
69
  export interface ClientEntrypointOptions extends CommonEntrypointOptions {
27
- /**
28
- * Force entrypoint to be elevated even if it is already elevated
29
- */
30
- force?: boolean
31
70
  routeOptions?: ClientRouteOptions
32
71
  validateOnCall?: boolean
33
72
  }
@@ -36,6 +75,6 @@ export interface EntrypointRef<T, R extends AbstractRequest = AbstractRequest> {
36
75
  ref?: ClientEntrypoint<T, R>
37
76
  }
38
77
 
39
- export interface RefedEntrypointHandler<T, R extends AbstractRequest = AbstractRequest> {
78
+ export interface RefedEntrypointHandler<T = {}, R extends AbstractRequest = AbstractRequest> {
40
79
  (ref: EntrypointRef<T, R>): EntrypointHandler
41
80
  }
@@ -1,12 +1,11 @@
1
1
  import Ajv from 'ajv'
2
2
  import type { ErrorObject } from 'ajv'
3
- import type { EntrypointFilter, ClientEntrypointOptions } from '../types.js'
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, RefedEntrypointHandler } from '../types.js'
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
- }