@owlmeans/client-entrypoint 0.1.18-rc.45 → 0.1.18-rc.47

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.
Files changed (60) hide show
  1. package/README.md +11 -10
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/client-entrypoint/SKILL.md +1 -1
  4. package/build/consts.d.ts +2 -0
  5. package/build/consts.d.ts.map +1 -0
  6. package/build/consts.js +2 -0
  7. package/build/consts.js.map +1 -0
  8. package/build/entrypoint.d.ts.map +1 -1
  9. package/build/entrypoint.js +6 -5
  10. package/build/entrypoint.js.map +1 -1
  11. package/build/failure.d.ts +2 -16
  12. package/build/failure.d.ts.map +1 -1
  13. package/build/failure.js +1 -1
  14. package/build/failure.js.map +1 -1
  15. package/build/helper/types.d.ts +10 -0
  16. package/build/helper/types.d.ts.map +1 -0
  17. package/build/helper/types.js +2 -0
  18. package/build/helper/types.js.map +1 -0
  19. package/build/helper.d.ts +4 -4
  20. package/build/helper.d.ts.map +1 -1
  21. package/build/helper.js +22 -19
  22. package/build/helper.js.map +1 -1
  23. package/build/index.d.ts +4 -1
  24. package/build/index.d.ts.map +1 -1
  25. package/build/index.js +3 -1
  26. package/build/index.js.map +1 -1
  27. package/build/stab.d.ts +4 -0
  28. package/build/stab.d.ts.map +1 -0
  29. package/build/stab.js +5 -0
  30. package/build/stab.js.map +1 -0
  31. package/build/types.d.ts +16 -2
  32. package/build/types.d.ts.map +1 -1
  33. package/build/utils/handler/types.d.ts +15 -0
  34. package/build/utils/handler/types.d.ts.map +1 -0
  35. package/build/utils/handler/types.js +2 -0
  36. package/build/utils/handler/types.js.map +1 -0
  37. package/build/utils/handler.d.ts +6 -4
  38. package/build/utils/handler.d.ts.map +1 -1
  39. package/build/utils/handler.js +120 -114
  40. package/build/utils/handler.js.map +1 -1
  41. package/build/utils/index.d.ts +1 -0
  42. package/build/utils/index.d.ts.map +1 -1
  43. package/build/utils/index.js.map +1 -1
  44. package/build/utils/types.local.d.ts +5 -0
  45. package/build/utils/types.local.d.ts.map +1 -0
  46. package/build/utils/types.local.js +2 -0
  47. package/build/utils/types.local.js.map +1 -0
  48. package/package.json +13 -13
  49. package/src/consts.ts +1 -0
  50. package/src/entrypoint.ts +6 -5
  51. package/src/failure.ts +3 -21
  52. package/src/helper/types.ts +10 -0
  53. package/src/helper.ts +28 -23
  54. package/src/index.ts +4 -1
  55. package/src/stab.ts +6 -0
  56. package/src/types.ts +18 -6
  57. package/src/utils/handler/types.ts +15 -0
  58. package/src/utils/handler.ts +81 -79
  59. package/src/utils/index.ts +1 -0
  60. package/src/utils/types.local.ts +5 -0
@@ -1,131 +1,137 @@
1
1
  import { DEFAULT_KEY } from '@owlmeans/client-config';
2
2
  import { EntrypointOutcome, provideResponse, transportAlias } from '@owlmeans/entrypoint';
3
3
  import { validate } from './entrypoint.js';
4
- import { extractParams } from '@owlmeans/client-route';
4
+ import { clientRouteHelper } from '@owlmeans/client-route';
5
5
  import { PARAM, RouteMethod, RouteProtocols } from '@owlmeans/route';
6
6
  import { stringify } from 'qs';
7
- import { assertContext } from '@owlmeans/context';
7
+ import { assertContext, memoHelper } from '@owlmeans/context';
8
8
  import { makeSecurityHelper } from '@owlmeans/config';
9
- import { ENTRYPOINT_FAILURE_SERVICE } from '../failure.js';
9
+ import { ENTRYPOINT_FAILURE_SERVICE } from '../consts.js';
10
10
  import { logger } from '@owlmeans/log';
11
11
  const log = logger('client-entrypoint');
12
- export const apiHandler = (ref) => async (req, res) => {
13
- const location = `client-entrypoint:api-handler:${ref.ref?.alias}`;
14
- const context = assertContext(ref.ref?.ctx, location);
15
- if (context.cfg.webService == null) {
16
- throw new SyntaxError('No webService provided');
17
- }
18
- const ep = context.entrypoint(req.alias);
19
- // A route names the protocol it answers on. Whatever is bound under that protocol takes the
20
- // call, so a consumer writes `ep.call(...)` without learning which transport ran.
21
- const transport = transportAlias(ep.route.route.protocol);
22
- if (context.hasService(transport)) {
12
+ export const makeApiCallHelper = (ref) => {
13
+ const apiHandler = async (req, res) => {
14
+ const location = `client-entrypoint:api-handler:${ref.ref?.alias}`;
15
+ const context = assertContext(ref.ref?.ctx, location);
16
+ if (context.cfg.webService == null) {
17
+ throw new SyntaxError('No webService provided');
18
+ }
19
+ const ep = context.entrypoint(req.alias);
20
+ // A route names the protocol it answers on. Whatever is bound under that protocol takes the
21
+ // call, so a consumer writes `ep.call(...)` without learning which transport ran.
22
+ const transport = transportAlias(ep.route.route.protocol);
23
+ if (context.hasService(transport)) {
24
+ req.path = ep.path();
25
+ return context.service(transport).handle(req, res);
26
+ }
27
+ // Which web client carries this call is decided by the service the route answers on — the one it
28
+ // names, or the one the context picks for its app type when it names none.
29
+ const route = ep.service();
30
+ const alias = typeof context.cfg.webService === 'string'
31
+ ? context.cfg.webService
32
+ : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY];
33
+ if (alias == null) {
34
+ throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`);
35
+ }
36
+ const service = context.service(alias);
23
37
  req.path = ep.path();
24
- return context.service(transport).handle(req, res);
25
- }
26
- // Which web client carries this call is decided by the service the route answers on — the one it
27
- // names, or the one the context picks for its app type when it names none.
28
- const route = ep.service();
29
- const alias = typeof context.cfg.webService === 'string'
30
- ? context.cfg.webService
31
- : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY];
32
- if (alias == null) {
33
- throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`);
34
- }
35
- const service = context.service(alias);
36
- req.path = ep.path();
37
- return service.handler(req, res);
38
- };
39
- export const apiInvoke = (ref, opts) => (async (req) => {
40
- const ep = ref.ref;
41
- if (ep == null) {
42
- throw new SyntaxError('Try to make API call before the entrypoint is created');
43
- }
44
- const ctx = ep.ctx;
45
- if (ctx == null) {
46
- throw new SyntaxError(`No context provided in apiCall for ${ep.alias} entrypoint`);
47
- }
48
- if (req?.canceled) {
49
- return { value: null, outcome: EntrypointOutcome.Ok };
50
- }
51
- const request = {
52
- alias: ep.alias,
53
- params: req?.params ?? {},
54
- // JSON transports must send a body for mutation methods even when the contract has no
55
- // payload. Keeping that rule here makes every typed caller use `call({ params })`, never
56
- // an SDK-specific `{ body: {} }` workaround.
57
- body: req?.body ?? ([RouteMethod.POST, RouteMethod.PUT, RouteMethod.PATCH]
58
- .includes(ep.route.route.method ?? RouteMethod.GET) ? {} : undefined),
59
- headers: req?.headers ?? {},
60
- query: req?.query ?? {},
61
- host: req?.host,
62
- base: req?.base,
63
- path: ep.path(),
64
- timeout: req?.timeout,
65
- signal: req?.signal,
38
+ return service.handler(req, res);
66
39
  };
67
- if (req?.cancel != null) {
68
- const cancel = req.cancel;
69
- req.cancel = () => {
70
- cancel();
71
- request.canceled = true;
40
+ const apiInvoke = (opts) => (async (req) => {
41
+ const ep = ref.ref;
42
+ if (ep == null) {
43
+ throw new SyntaxError('Try to make API call before the entrypoint is created');
44
+ }
45
+ const ctx = ep.ctx;
46
+ if (ctx == null) {
47
+ throw new SyntaxError(`No context provided in apiCall for ${ep.alias} entrypoint`);
48
+ }
49
+ if (req?.canceled) {
50
+ return { value: null, outcome: EntrypointOutcome.Ok };
51
+ }
52
+ const request = {
53
+ alias: ep.alias,
54
+ params: req?.params ?? {},
55
+ // JSON transports must send a body for mutation methods even when the contract has no
56
+ // payload. Keeping that rule here makes every typed caller use `call({ params })`, never
57
+ // an SDK-specific `{ body: {} }` workaround.
58
+ body: req?.body ?? ([RouteMethod.POST, RouteMethod.PUT, RouteMethod.PATCH]
59
+ .includes(ep.route.route.method ?? RouteMethod.GET) ? {} : undefined),
60
+ headers: req?.headers ?? {},
61
+ query: req?.query ?? {},
62
+ host: req?.host,
63
+ base: req?.base,
64
+ path: ep.path(),
65
+ timeout: req?.timeout,
66
+ signal: req?.signal,
72
67
  };
73
- }
74
- if (opts?.validateOnCall) {
68
+ if (req?.cancel != null) {
69
+ const cancel = req.cancel;
70
+ req.cancel = () => {
71
+ cancel();
72
+ request.canceled = true;
73
+ };
74
+ }
75
+ if (opts?.validateOnCall) {
76
+ try {
77
+ await validate(ref)(request);
78
+ }
79
+ catch (e) {
80
+ log.error('Request validation failed', { alias: ep.alias, error: e });
81
+ throw e;
82
+ }
83
+ }
84
+ const reply = provideResponse();
85
+ if (ctx == null && ep.ctx == null) {
86
+ throw new SyntaxError(`Use entrypoint ${ep.alias} without context`);
87
+ }
75
88
  try {
76
- await validate(ref)(request);
89
+ await apiHandler(request, reply);
90
+ if (reply.error != null)
91
+ throw reply.error;
77
92
  }
78
- catch (e) {
79
- log.error('Request validation failed', { alias: ep.alias, error: e });
80
- throw e;
93
+ catch (error) {
94
+ if (ctx.hasService(ENTRYPOINT_FAILURE_SERVICE)) {
95
+ await ctx.service(ENTRYPOINT_FAILURE_SERVICE)
96
+ .notify({ alias: ep.alias, request, error });
97
+ }
98
+ throw error;
81
99
  }
82
- }
83
- const reply = provideResponse();
84
- if (ctx == null && ep.ctx == null) {
85
- throw new SyntaxError(`Use entrypoint ${ep.alias} without context`);
86
- }
87
- try {
88
- await apiHandler(ref)(request, reply);
89
- if (reply.error != null)
90
- throw reply.error;
91
- }
92
- catch (error) {
93
- if (ctx.hasService(ENTRYPOINT_FAILURE_SERVICE)) {
94
- await ctx.service(ENTRYPOINT_FAILURE_SERVICE)
95
- .notify({ alias: ep.alias, request, error });
100
+ return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok };
101
+ });
102
+ const entrypointUrl = async (req, opts) => {
103
+ const ep = ref.ref;
104
+ if (ep == null) {
105
+ throw new SyntaxError('Try to make URL before the entrypoint is created');
96
106
  }
97
- throw error;
98
- }
99
- return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok };
100
- });
101
- export const entrypointUrl = async (ref, req, opts) => {
102
- const ep = ref.ref;
103
- if (ep == null) {
104
- throw new SyntaxError('Try to make URL before the entrypoint is created');
105
- }
106
- const ctx = ep.ctx;
107
- if (ctx == null) {
108
- throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`);
109
- }
110
- // The base is left off here: an in-service URL is addressed relative to it, and the absolute
111
- // branch below has `makeUrl` prepend it.
112
- const epPath = ep.path();
113
- const pathParams = extractParams(epPath);
114
- let path = pathParams.reduce((p, param) => {
115
- return p.replace(`${PARAM}${param}`, `${req?.params?.[param]}`);
116
- }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '');
117
- // A socket address is always absolute, whoever owns the route. `new WebSocket(path)` resolves a
118
- // relative value against the PAGE's origin, which in a split deployment is the web host and not
119
- // the service that answers the upgrade — so the handshake goes somewhere that never speaks it
120
- // and dies on a gateway timeout. Only a same-origin HTTP route benefits from staying relative.
121
- const socket = ep.route.route.protocol === RouteProtocols.SOCKET;
122
- // Locality is a question about the RESOLVED service, not about what the declaration happens to
123
- // name: a route that names no service belongs to the asking context, and addressing it absolutely
124
- // would turn in-app navigation into a full page load.
125
- if (socket || !ep.isLocal() || opts?.absolute === true) {
126
- const helper = makeSecurityHelper(ctx);
127
- path = helper.makeUrl(ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
128
- }
129
- return path;
107
+ const ctx = ep.ctx;
108
+ if (ctx == null) {
109
+ throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`);
110
+ }
111
+ // The base is left off here: an in-service URL is addressed relative to it, and the absolute
112
+ // branch below has `makeUrl` prepend it.
113
+ const epPath = ep.path();
114
+ const pathParams = clientRouteHelper.extractParams(epPath);
115
+ let path = pathParams.reduce((p, param) => {
116
+ return p.replace(`${PARAM}${param}`, `${req?.params?.[param]}`);
117
+ }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '');
118
+ // A socket address is always absolute, whoever owns the route. `new WebSocket(path)` resolves a
119
+ // relative value against the PAGE's origin, which in a split deployment is the web host and not
120
+ // the service that answers the upgrade — so the handshake goes somewhere that never speaks it
121
+ // and dies on a gateway timeout. Only a same-origin HTTP route benefits from staying relative.
122
+ const socket = ep.route.route.protocol === RouteProtocols.SOCKET;
123
+ // Locality is a question about the RESOLVED service, not about what the declaration happens to
124
+ // name: a route that names no service belongs to the asking context, and addressing it absolutely
125
+ // would turn in-app navigation into a full page load.
126
+ if (socket || !ep.isLocal() || opts?.absolute === true) {
127
+ const helper = makeSecurityHelper(ctx);
128
+ path = helper.makeUrl(ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure });
129
+ }
130
+ return path;
131
+ };
132
+ return { apiHandler, apiInvoke, entrypointUrl };
130
133
  };
134
+ export const apiCallOf = memoHelper.oncePer(makeApiCallHelper);
135
+ /** @deprecated compat:factory-refactor — use `makeApiCallHelper(ref).entrypointUrl(…)` */
136
+ export const entrypointUrl = (ref, req, opts) => makeApiCallHelper(ref).entrypointUrl(req, opts);
131
137
  //# 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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"}
@@ -1,3 +1,4 @@
1
+ export type * from './handler/types.js';
1
2
  export * from './entrypoint.js';
2
3
  export * from './handler.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,mBAAmB,oBAAoB,CAAA;AACvC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { ClientConfig, ClientContext } from '@owlmeans/client-context';
2
+ export type Config = ClientConfig;
3
+ export interface Context<C extends Config = Config> extends ClientContext<C> {
4
+ }
5
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE3E,MAAM,MAAM,MAAM,GAAG,YAAY,CAAA;AAEjC,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;CAAI"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-entrypoint",
3
- "version": "0.1.18-rc.45",
3
+ "version": "0.1.18-rc.47",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,25 +28,25 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@owlmeans/api": "^0.1.18-rc.45",
32
- "@owlmeans/client-config": "^0.1.18-rc.42",
33
- "@owlmeans/client-context": "^0.1.18-rc.46",
34
- "@owlmeans/client-route": "^0.1.18-rc.46",
35
- "@owlmeans/config": "^0.1.18-rc.42",
36
- "@owlmeans/context": "^0.1.18-rc.32",
37
- "@owlmeans/entrypoint": "^0.1.18-rc.39",
38
- "@owlmeans/error": "^0.1.18-rc.36",
39
- "@owlmeans/log": "^0.1.18-rc.0",
40
- "@owlmeans/route": "^0.1.18-rc.33",
31
+ "@owlmeans/api": "^0.1.18-rc.47",
32
+ "@owlmeans/client-config": "^0.1.18-rc.44",
33
+ "@owlmeans/client-context": "^0.1.18-rc.48",
34
+ "@owlmeans/client-route": "^0.1.18-rc.48",
35
+ "@owlmeans/config": "^0.1.18-rc.44",
36
+ "@owlmeans/context": "^0.1.18-rc.34",
37
+ "@owlmeans/entrypoint": "^0.1.18-rc.41",
38
+ "@owlmeans/error": "^0.1.18-rc.38",
39
+ "@owlmeans/log": "^0.1.18-rc.2",
40
+ "@owlmeans/route": "^0.1.18-rc.35",
41
41
  "ajv-formats": "^3.0.1",
42
- "qs": "^6.13.0"
42
+ "qs": "^6.16.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "ajv": "*"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@owlmeans/dep-config": "workspace:*",
49
- "@types/qs": "^6.9.16",
49
+ "@types/qs": "^6.15.1",
50
50
  "nodemon": "^3.1.14",
51
51
  "typescript": "^7.0.2"
52
52
  },
package/src/consts.ts ADDED
@@ -0,0 +1 @@
1
+ export const ENTRYPOINT_FAILURE_SERVICE = 'client-entrypoint:failure'
package/src/entrypoint.ts CHANGED
@@ -2,9 +2,9 @@ import type { ClientEntrypoint, ClientEntrypointOptions, EntrypointRef, RefedEnt
2
2
  import type { AbstractRequest, CommonEntrypoint } from '@owlmeans/entrypoint'
3
3
  import { validate } from './utils/entrypoint.js'
4
4
  import { route } from '@owlmeans/client-route'
5
- import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js'
5
+ import { apiCallOf } from './utils/handler.js'
6
6
  import { AppType } from '@owlmeans/context'
7
- import { provideRequest } from './helper.js'
7
+ import { clientRequestHelper } from './helper.js'
8
8
 
9
9
  /** Attach client behaviour to an entrypoint already materialized from a protocol. */
10
10
  export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = AbstractRequest>(
@@ -16,6 +16,7 @@ export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = Abstra
16
16
 
17
17
  let _entrypoint: ClientEntrypoint<T, R>
18
18
 
19
+ const apiHandler: RefedEntrypointHandler<T, R> = ref => apiCallOf(ref).apiHandler
19
20
  const _handler = handler ?? (arg.route.route.type === AppType.Backend ? apiHandler : undefined)
20
21
 
21
22
  assertExplicitHandler(arg.route.route.type, handler)
@@ -29,7 +30,7 @@ export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = Abstra
29
30
  _entrypoint.gateParams = opts?.gateParams ?? arg.gateParams
30
31
 
31
32
  _entrypoint.url = ((req?: Partial<R>, urlOpts?: { absolute?: boolean }) =>
32
- entrypointUrl<T, R>(entrypointHandle, req as never, urlOpts)) as ClientEntrypoint<T, R>['url']
33
+ apiCallOf(entrypointHandle).entrypointUrl(req as never, urlOpts)) as ClientEntrypoint<T, R>['url']
33
34
 
34
35
  // An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
35
36
  // wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
@@ -39,7 +40,7 @@ export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = Abstra
39
40
  `Entrypoint ${_entrypoint.alias} renders a screen - address it with url() instead of call()/invoke()`
40
41
  )
41
42
  })
42
- : apiInvoke<T, R>(entrypointHandle, opts)) as ClientEntrypoint<T, R>['invoke']
43
+ : apiCallOf(entrypointHandle).apiInvoke(opts)) as ClientEntrypoint<T, R>['invoke']
43
44
 
44
45
  _entrypoint.call = (async (req?: Partial<R>) =>
45
46
  (await _entrypoint.invoke(req)).value) as ClientEntrypoint<T, R>['call']
@@ -48,7 +49,7 @@ export const bindMaterializedEntrypoint = <T, R extends AbstractRequest = Abstra
48
49
  if (entrypointHandle.ref == null) {
49
50
  throw SyntaxError(`Try to request uninitialized entrypoint ${JSON.stringify(arg)}`)
50
51
  }
51
- const _request = provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path()) as R
52
+ const _request = clientRequestHelper.provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path()) as R
52
53
 
53
54
  request != null && Object.entries(request).forEach(([key, value]) => {
54
55
  _request[key as keyof R] = value
package/src/failure.ts CHANGED
@@ -1,28 +1,10 @@
1
- import { createLazyService } from '@owlmeans/context'
2
- import type { BasicContext, LazyService } from '@owlmeans/context'
3
- import type { AbstractRequest } from '@owlmeans/entrypoint'
1
+ import { createLazyService, type BasicContext } from '@owlmeans/context'
4
2
  import { logger } from '@owlmeans/log'
3
+ import { ENTRYPOINT_FAILURE_SERVICE } from './consts.js'
4
+ import type { EntrypointFailurePlugin, EntrypointFailureService } from './types.js'
5
5
 
6
6
  const log = logger('client-entrypoint')
7
7
 
8
- export const ENTRYPOINT_FAILURE_SERVICE = 'client-entrypoint:failure'
9
-
10
- export interface EntrypointFailure {
11
- alias: string
12
- request: AbstractRequest
13
- error: unknown
14
- }
15
-
16
- export interface EntrypointFailurePlugin {
17
- alias: string
18
- onFailure: (failure: EntrypointFailure) => void | Promise<void>
19
- }
20
-
21
- export interface EntrypointFailureService extends LazyService {
22
- registerPlugin: (plugin: EntrypointFailurePlugin) => void
23
- notify: (failure: EntrypointFailure) => Promise<void>
24
- }
25
-
26
8
  /** Context-local observers for rejected client calls; observers never replace the thrown error. */
27
9
  export const ensureEntrypointFailureService = (ctx: BasicContext<any>): EntrypointFailureService => {
28
10
  if (ctx.hasService(ENTRYPOINT_FAILURE_SERVICE)) {
@@ -0,0 +1,10 @@
1
+ import type { AbstractRequest } from '@owlmeans/entrypoint'
2
+ import type { JSONSchemaType } from 'ajv'
3
+
4
+ /** Builds and shapes the requests a client sends. */
5
+ export interface ClientRequestHelper {
6
+ /** A minimal cancellable `AbstractRequest` for an entrypoint alias at a path. */
7
+ provideRequest: <T extends {} = {}>(alias: string, path: string) => AbstractRequest<T>
8
+ /** Keeps only the non-null keys of `object` the AJV schema declares. */
9
+ pickPerSchema: <T, R>(object: T, schema: JSONSchemaType<R>) => Partial<R>
10
+ }
package/src/helper.ts CHANGED
@@ -1,31 +1,36 @@
1
- import type { RefedEntrypointHandler } from './types.js'
2
1
  import type { AbstractRequest } from '@owlmeans/entrypoint'
3
2
  import type { JSONSchemaType } from "ajv"
3
+ import type { ClientRequestHelper } from './helper/types.js'
4
4
 
5
- export const stab: RefedEntrypointHandler<{}> = () => () => {
6
- return void 0 as any
7
- }
5
+ export const createClientRequestHelper = (): ClientRequestHelper => {
6
+ const provideRequest = <T extends {} = {}>(alias: string, path: string): AbstractRequest<T> => {
7
+ const request = {
8
+ alias,
9
+ params: {},
10
+ headers: {},
11
+ query: {},
12
+ path,
13
+ canceled: false,
14
+ cancel: () => request.canceled = true
15
+ }
8
16
 
9
- export const provideRequest = <T extends {} = {}>(alias: string, path: string): AbstractRequest<T> => {
10
- const request = {
11
- alias,
12
- params: {},
13
- headers: {},
14
- query: {},
15
- path,
16
- canceled: false,
17
- cancel: () => request.canceled = true
17
+ return request
18
18
  }
19
19
 
20
- return request
20
+ const pickPerSchema = <T, R>(object: T, schema: JSONSchemaType<R>): Partial<R> =>
21
+ Object.keys(schema.properties).reduce(
22
+ (acc, key) => {
23
+ if (object[key as keyof T] != null) {
24
+ acc[key as keyof R] = object[key as keyof T] as unknown as R[keyof R]
25
+ }
26
+ return acc
27
+ }, {} as Partial<R>
28
+ )
29
+
30
+ return { provideRequest, pickPerSchema }
21
31
  }
22
32
 
23
- export const pickPerSchema = <T, R>(object: T, schema: JSONSchemaType<R>): Partial<R> =>
24
- Object.keys(schema.properties).reduce(
25
- (acc, key) => {
26
- if (object[key as keyof T] != null) {
27
- acc[key as keyof R] = object[key as keyof T] as unknown as R[keyof R]
28
- }
29
- return acc
30
- }, {} as Partial<R>
31
- )
33
+ export const clientRequestHelper = createClientRequestHelper()
34
+
35
+ /** @deprecated compat:factory-refactor — use `clientRequestHelper.provideRequest(…)` */
36
+ export const provideRequest = <T extends {} = {}>(alias: string, path: string): AbstractRequest<T> => clientRequestHelper.provideRequest<T>(alias, path)
package/src/index.ts CHANGED
@@ -1,6 +1,9 @@
1
1
 
2
2
  export type * from './types.js'
3
+ export type * from './helper/types.js'
3
4
  export * from './errors.js'
4
5
  export * from './failure.js'
6
+ export * from './consts.js'
5
7
  export * from './protocol.js'
6
- export { pickPerSchema, provideRequest, stab } from './helper.js'
8
+ export { clientRequestHelper, createClientRequestHelper, provideRequest } from './helper.js'
9
+ export { stab } from './stab.js'
package/src/stab.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { RefedEntrypointHandler } from './types.js'
2
+
3
+ /** The no-op handler of a URL-only frontend binding. */
4
+ export const stab: RefedEntrypointHandler<{}> = () => () => {
5
+ return void 0 as any
6
+ }
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@ import type {
3
3
  AbstractRequest, CommonEntrypoint, CommonEntrypointOptions, EntrypointHandler,
4
4
  EntrypointOutcome, EntrypointProtocolDeclaration, RegisteredEntrypoint, RequestOf,
5
5
  } from '@owlmeans/entrypoint'
6
+ import type { LazyService } from '@owlmeans/context'
6
7
 
7
8
  export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientRequest> extends CommonEntrypoint {
8
9
  route: ClientRouteModel
@@ -30,12 +31,7 @@ export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientReques
30
31
  * its request and reply types are read directly from the declaration and cannot be replaced at a
31
32
  * call site.
32
33
  */
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
- }
34
+ export interface ClientProtocolEntrypoint<Protocol extends EntrypointProtocolDeclaration> extends Omit<ClientEntrypoint, 'call' | 'invoke' | 'url' | 'validate' | 'request'>, RegisteredEntrypoint<RequestOf<Protocol>, import('@owlmeans/entrypoint').ResponseOf<Protocol>> { readonly protocol: Protocol }
39
35
 
40
36
  export interface EntrypointCall<T, Req extends ClientRequest = ClientRequest> {
41
37
  <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>
@@ -78,3 +74,19 @@ export interface EntrypointRef<T, R extends AbstractRequest = AbstractRequest> {
78
74
  export interface RefedEntrypointHandler<T = {}, R extends AbstractRequest = AbstractRequest> {
79
75
  (ref: EntrypointRef<T, R>): EntrypointHandler
80
76
  }
77
+
78
+ export interface EntrypointFailure {
79
+ alias: string
80
+ request: AbstractRequest
81
+ error: unknown
82
+ }
83
+
84
+ export interface EntrypointFailurePlugin {
85
+ alias: string
86
+ onFailure: (failure: EntrypointFailure) => void | Promise<void>
87
+ }
88
+
89
+ export interface EntrypointFailureService extends LazyService {
90
+ registerPlugin: (plugin: EntrypointFailurePlugin) => void
91
+ notify: (failure: EntrypointFailure) => Promise<void>
92
+ }
@@ -0,0 +1,15 @@
1
+ import type { AbstractRequest, EntrypointHandler } from '@owlmeans/entrypoint'
2
+ import type { ClientEntrypointOptions, EntrypointInvoke, EntrypointUrlOptions } from '../../types.js'
3
+
4
+ /** How a client entrypoint reaches its backend: the handler, the round trip and the address. */
5
+ export interface ApiCallHelper<T, R extends AbstractRequest = AbstractRequest> {
6
+ /**
7
+ * The handler that carries the entrypoint's call: the transport service bound to its route's
8
+ * protocol, else the API client of the web service its route answers on.
9
+ */
10
+ apiHandler: EntrypointHandler
11
+ /** The round trip behind `invoke()`: builds the request, validates it on demand and notifies failure observers. */
12
+ apiInvoke: (opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R>
13
+ /** The address behind `url()`: `:params` filled in, the query appended, absolute when the route is not local. */
14
+ entrypointUrl: (req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string>
15
+ }