@owlmeans/client-entrypoint 0.1.18-rc.46 → 0.1.18-rc.48

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 (45) 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/entrypoint.d.ts.map +1 -1
  5. package/build/entrypoint.js +6 -5
  6. package/build/entrypoint.js.map +1 -1
  7. package/build/helper/types.d.ts +10 -0
  8. package/build/helper/types.d.ts.map +1 -0
  9. package/build/helper/types.js +2 -0
  10. package/build/helper/types.js.map +1 -0
  11. package/build/helper.d.ts +4 -4
  12. package/build/helper.d.ts.map +1 -1
  13. package/build/helper.js +22 -19
  14. package/build/helper.js.map +1 -1
  15. package/build/index.d.ts +3 -1
  16. package/build/index.d.ts.map +1 -1
  17. package/build/index.js +2 -1
  18. package/build/index.js.map +1 -1
  19. package/build/stab.d.ts +4 -0
  20. package/build/stab.d.ts.map +1 -0
  21. package/build/stab.js +5 -0
  22. package/build/stab.js.map +1 -0
  23. package/build/types.d.ts +2 -2
  24. package/build/types.d.ts.map +1 -1
  25. package/build/utils/handler/types.d.ts +15 -0
  26. package/build/utils/handler/types.d.ts.map +1 -0
  27. package/build/utils/handler/types.js +2 -0
  28. package/build/utils/handler/types.js.map +1 -0
  29. package/build/utils/handler.d.ts +6 -4
  30. package/build/utils/handler.d.ts.map +1 -1
  31. package/build/utils/handler.js +119 -113
  32. package/build/utils/handler.js.map +1 -1
  33. package/build/utils/index.d.ts +1 -0
  34. package/build/utils/index.d.ts.map +1 -1
  35. package/build/utils/index.js.map +1 -1
  36. package/package.json +11 -11
  37. package/src/entrypoint.ts +6 -5
  38. package/src/helper/types.ts +10 -0
  39. package/src/helper.ts +28 -23
  40. package/src/index.ts +3 -1
  41. package/src/stab.ts +6 -0
  42. package/src/types.ts +1 -6
  43. package/src/utils/handler/types.ts +15 -0
  44. package/src/utils/handler.ts +77 -71
  45. package/src/utils/index.ts +1 -0
package/README.md CHANGED
@@ -10,7 +10,7 @@ re-exports of `@owlmeans/web-client` or `@owlmeans/web-panel`. Protocols are dec
10
10
  ## Installation
11
11
 
12
12
  ```bash
13
- bun add @owlmeans/client-entrypoint@^0.1.18-rc.46
13
+ bun add @owlmeans/client-entrypoint@^0.1.18-rc.48
14
14
  ```
15
15
 
16
16
  ## Concepts
@@ -116,15 +116,15 @@ so `call({ params })` is enough. Never add `{ body: {} }` as a workaround.
116
116
 
117
117
  ### 5. Narrowing a payload to a schema
118
118
 
119
- `pickPerSchema(object, schema)` keeps only the keys the AJV schema declares and skips `null` values.
119
+ `clientRequestHelper.pickPerSchema(object, schema)` keeps only the keys the AJV schema declares and skips `null` values.
120
120
  It is useful when a form model carries more fields than the contract accepts.
121
121
 
122
122
  ```ts
123
- import { pickPerSchema } from '@owlmeans/client-entrypoint'
123
+ import { clientRequestHelper } from '@owlmeans/client-entrypoint'
124
124
  import type { ProjectUpdate } from 'my-app-common'
125
125
  import { ProjectUpdateSchema } from 'my-app-common'
126
126
 
127
- const body = pickPerSchema<typeof formValues, ProjectUpdate>(formValues, ProjectUpdateSchema)
127
+ const body = clientRequestHelper.pickPerSchema<typeof formValues, ProjectUpdate>(formValues, ProjectUpdateSchema)
128
128
  await ctx.entrypoint(apiProtocols.project.update).call({ params: { id }, body })
129
129
  ```
130
130
 
@@ -138,8 +138,8 @@ await ctx.entrypoint(apiProtocols.project.update).call({ params: { id }, body })
138
138
  | `bindAll(tree)` | function | Materialize every protocol in a named declaration tree |
139
139
  | `bindScreen(protocol, handler, options?)` | function | Materialize a frontend protocol with its renderer |
140
140
  | `stab` | const | No-op `RefedEntrypointHandler` for a URL-only frontend binding |
141
- | `provideRequest(alias, path)` | function | A minimal `AbstractRequest` for a dynamic boundary (for example a socket request) |
142
- | `pickPerSchema(object, schema)` | function | Keep only the non-null keys an AJV schema declares |
141
+ | `clientRequestHelper.provideRequest(alias, path)` | helper member | A minimal `AbstractRequest` for a dynamic boundary (for example a socket request) |
142
+ | `clientRequestHelper.pickPerSchema(object, schema)` | helper member | Keep only the non-null keys an AJV schema declares |
143
143
  | `ClientProtocolEntrypoint<Protocol>` | type | The bound view of a protocol — see *Entrypoint members* |
144
144
  | `ClientEntrypoint<T, R>` | type | The untyped bound entrypoint shape the protocol view is built from |
145
145
  | `ClientEntrypointOptions` | type | `routeOptions?` (`ClientRouteOptions`), `validateOnCall?`, plus common entrypoint options |
@@ -164,9 +164,10 @@ await ctx.entrypoint(apiProtocols.project.update).call({ params: { id }, body })
164
164
 
165
165
  | Symbol | Kind | Purpose |
166
166
  |---|---|---|
167
- | `apiInvoke(ref, options?)` | function | The round trip behind `invoke()` |
168
- | `apiHandler(ref)` | function | The handler that picks the transport service or the API client |
169
- | `entrypointUrl(ref, request?, options?)` | function | The address behind `url()` |
167
+ | `apiCallOf(ref)` / `makeApiCallHelper(ref)` | helper | The call mechanics bound to one entrypoint ref (one per ref through `apiCallOf`) |
168
+ | `apiCallOf(ref).apiInvoke(options?)` | helper member | The round trip behind `invoke()` |
169
+ | `apiCallOf(ref).apiHandler` | helper member | The handler that picks the transport service or the API client |
170
+ | `apiCallOf(ref).entrypointUrl(request?, options?)` | helper member | The address behind `url()` |
170
171
  | `validate(ref)` | function | The filter behind `validate()` |
171
172
  | `isEntrypoint(value)` | function | Re-export from `@owlmeans/entrypoint/utils` |
172
173
 
@@ -204,7 +205,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
204
205
  your project's skill store (`.agents/skills/`):
205
206
 
206
207
  ```sh
207
- npx @owlmeans/agent-skills@^0.1.18-rc.48
208
+ npx @owlmeans/agent-skills@^0.1.18-rc.51
208
209
  ```
209
210
 
210
211
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/client-entrypoint",
4
- "version": "0.1.18-rc.46",
5
- "generatedAt": "2026-10-05T08:32:19.100Z",
4
+ "version": "0.1.18-rc.48",
5
+ "generatedAt": "2026-10-06T11:45:57.658Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -7,7 +7,7 @@ user-invocable: false
7
7
 
8
8
  # @owlmeans/client-entrypoint
9
9
 
10
- **Install:** `bun add @owlmeans/client-entrypoint@^0.1.18-rc.46`
10
+ **Install:** `bun add @owlmeans/client-entrypoint@^0.1.18-rc.48`
11
11
 
12
12
  Bind a declaration from `@owlmeans/entrypoint`; never construct or replace a contextual
13
13
  entrypoint by alias.
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAiB,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAO7E,qFAAqF;AACrF,eAAO,MAAM,0BAA0B,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,OAClF,gBAAgB,YACX,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,SAC/B,uBAAuB,KAC7B,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAqDvB,CAAA"}
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAiB,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAO7E,qFAAqF;AACrF,eAAO,MAAM,0BAA0B,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,OAClF,gBAAgB,YACX,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,SAC/B,uBAAuB,KAC7B,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAsDvB,CAAA"}
@@ -1,12 +1,13 @@
1
1
  import { validate } from './utils/entrypoint.js';
2
2
  import { route } from '@owlmeans/client-route';
3
- import { apiInvoke, apiHandler, entrypointUrl } from './utils/handler.js';
3
+ import { apiCallOf } from './utils/handler.js';
4
4
  import { AppType } from '@owlmeans/context';
5
- import { provideRequest } from './helper.js';
5
+ import { clientRequestHelper } from './helper.js';
6
6
  /** Attach client behaviour to an entrypoint already materialized from a protocol. */
7
7
  export const bindMaterializedEntrypoint = (arg, handler, opts) => {
8
8
  const entrypointHandle = { ref: undefined };
9
9
  let _entrypoint;
10
+ const apiHandler = ref => apiCallOf(ref).apiHandler;
10
11
  const _handler = handler ?? (arg.route.route.type === AppType.Backend ? apiHandler : undefined);
11
12
  assertExplicitHandler(arg.route.route.type, handler);
12
13
  const routeModel = route(arg.route, opts?.routeOptions);
@@ -17,20 +18,20 @@ export const bindMaterializedEntrypoint = (arg, handler, opts) => {
17
18
  _entrypoint.filter = opts?.filter ?? arg.filter;
18
19
  _entrypoint.gate = opts?.gate ?? arg.gate;
19
20
  _entrypoint.gateParams = opts?.gateParams ?? arg.gateParams;
20
- _entrypoint.url = ((req, urlOpts) => entrypointUrl(entrypointHandle, req, urlOpts));
21
+ _entrypoint.url = ((req, urlOpts) => apiCallOf(entrypointHandle).entrypointUrl(req, urlOpts));
21
22
  // An entrypoint carrying a renderer IS a screen: it is addressed by URL, never called over the
22
23
  // wire. Saying so here turns what used to be a URL-shaped answer from `call()` into a report.
23
24
  _entrypoint.invoke = (handler != null
24
25
  ? (async () => {
25
26
  throw new SyntaxError(`Entrypoint ${_entrypoint.alias} renders a screen - address it with url() instead of call()/invoke()`);
26
27
  })
27
- : apiInvoke(entrypointHandle, opts));
28
+ : apiCallOf(entrypointHandle).apiInvoke(opts));
28
29
  _entrypoint.call = (async (req) => (await _entrypoint.invoke(req)).value);
29
30
  _entrypoint.request = ((request) => {
30
31
  if (entrypointHandle.ref == null) {
31
32
  throw SyntaxError(`Try to request uninitialized entrypoint ${JSON.stringify(arg)}`);
32
33
  }
33
- const _request = provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path());
34
+ const _request = clientRequestHelper.provideRequest(entrypointHandle.ref.alias, entrypointHandle.ref.path());
34
35
  request != null && Object.entries(request).forEach(([key, value]) => {
35
36
  _request[key] = value;
36
37
  });
@@ -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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"}
@@ -0,0 +1,10 @@
1
+ import type { AbstractRequest } from '@owlmeans/entrypoint';
2
+ import type { JSONSchemaType } from 'ajv';
3
+ /** Builds and shapes the requests a client sends. */
4
+ export interface ClientRequestHelper {
5
+ /** A minimal cancellable `AbstractRequest` for an entrypoint alias at a path. */
6
+ provideRequest: <T extends {} = {}>(alias: string, path: string) => AbstractRequest<T>;
7
+ /** Keeps only the non-null keys of `object` the AJV schema declares. */
8
+ pickPerSchema: <T, R>(object: T, schema: JSONSchemaType<R>) => Partial<R>;
9
+ }
10
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,cAAc,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,CAAA;IACtF,wEAAwE;IACxE,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAC1E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":""}
package/build/helper.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { RefedEntrypointHandler } from './types.js';
2
1
  import type { AbstractRequest } from '@owlmeans/entrypoint';
3
- import type { JSONSchemaType } from "ajv";
4
- export declare const stab: RefedEntrypointHandler<{}>;
2
+ import type { ClientRequestHelper } from './helper/types.js';
3
+ export declare const createClientRequestHelper: () => ClientRequestHelper;
4
+ export declare const clientRequestHelper: ClientRequestHelper;
5
+ /** @deprecated compat:factory-refactor — use `clientRequestHelper.provideRequest(…)` */
5
6
  export declare const provideRequest: <T extends {} = {}>(alias: string, path: string) => AbstractRequest<T>;
6
- export declare const pickPerSchema: <T, R>(object: T, schema: JSONSchemaType<R>) => Partial<R>;
7
7
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAEzC,eAAO,MAAM,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAE3C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,MAAM,QAAQ,MAAM,KAAG,eAAe,CAAC,CAAC,CAYhG,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAQjF,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE5D,eAAO,MAAM,yBAAyB,QAAO,mBA0B5C,CAAA;AAED,eAAO,MAAM,mBAAmB,qBAA8B,CAAA;AAE9D,wFAAwF;AACxF,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,MAAM,QAAQ,MAAM,KAAG,eAAe,CAAC,CAAC,CAAuD,CAAA"}
package/build/helper.js CHANGED
@@ -1,22 +1,25 @@
1
- export const stab = () => () => {
2
- return void 0;
3
- };
4
- export const provideRequest = (alias, path) => {
5
- const request = {
6
- alias,
7
- params: {},
8
- headers: {},
9
- query: {},
10
- path,
11
- canceled: false,
12
- cancel: () => request.canceled = true
1
+ export const createClientRequestHelper = () => {
2
+ const provideRequest = (alias, path) => {
3
+ const request = {
4
+ alias,
5
+ params: {},
6
+ headers: {},
7
+ query: {},
8
+ path,
9
+ canceled: false,
10
+ cancel: () => request.canceled = true
11
+ };
12
+ return request;
13
13
  };
14
- return request;
14
+ const pickPerSchema = (object, schema) => Object.keys(schema.properties).reduce((acc, key) => {
15
+ if (object[key] != null) {
16
+ acc[key] = object[key];
17
+ }
18
+ return acc;
19
+ }, {});
20
+ return { provideRequest, pickPerSchema };
15
21
  };
16
- export const pickPerSchema = (object, schema) => Object.keys(schema.properties).reduce((acc, key) => {
17
- if (object[key] != null) {
18
- acc[key] = object[key];
19
- }
20
- return acc;
21
- }, {});
22
+ export const clientRequestHelper = createClientRequestHelper();
23
+ /** @deprecated compat:factory-refactor — use `clientRequestHelper.provideRequest(…)` */
24
+ export const provideRequest = (alias, path) => clientRequestHelper.provideRequest(alias, path);
22
25
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,IAAI,GAA+B,GAAG,EAAE,CAAC,GAAG,EAAE;IACzD,OAAO,KAAK,CAAQ,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAoB,KAAa,EAAE,IAAY,EAAsB,EAAE;IACnG,MAAM,OAAO,GAAG;QACd,KAAK;QACL,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,EAAE;QACX,KAAK,EAAE,EAAE;QACT,IAAI;QACJ,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI;KACtC,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,MAAS,EAAE,MAAyB,EAAc,EAAE,CACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACX,IAAI,MAAM,CAAC,GAAc,CAAC,IAAI,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,GAAc,CAAC,GAAG,MAAM,CAAC,GAAc,CAA0B,CAAA;IACvE,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,EAAE,EAAgB,CACpB,CAAA"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAwB,EAAE;IACjE,MAAM,cAAc,GAAG,CAAoB,KAAa,EAAE,IAAY,EAAsB,EAAE;QAC5F,MAAM,OAAO,GAAG;YACd,KAAK;YACL,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,EAAE;YACT,IAAI;YACJ,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI;SACtC,CAAA;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;IAED,MAAM,aAAa,GAAG,CAAO,MAAS,EAAE,MAAyB,EAAc,EAAE,CAC/E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACX,IAAI,MAAM,CAAC,GAAc,CAAC,IAAI,IAAI,EAAE,CAAC;YACnC,GAAG,CAAC,GAAc,CAAC,GAAG,MAAM,CAAC,GAAc,CAA0B,CAAA;QACvE,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAgB,CACpB,CAAA;IAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA;AAC1C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,EAAE,CAAA;AAE9D,wFAAwF;AACxF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAoB,KAAa,EAAE,IAAY,EAAsB,EAAE,CAAC,mBAAmB,CAAC,cAAc,CAAI,KAAK,EAAE,IAAI,CAAC,CAAA"}
package/build/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export type * from './types.js';
2
+ export type * from './helper/types.js';
2
3
  export * from './errors.js';
3
4
  export * from './failure.js';
4
5
  export * from './consts.js';
5
6
  export * from './protocol.js';
6
- export { pickPerSchema, provideRequest, stab } from './helper.js';
7
+ export { clientRequestHelper, createClientRequestHelper, provideRequest } from './helper.js';
8
+ export { stab } from './stab.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,mBAAmB,CAAA;AACtC,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA"}
package/build/index.js CHANGED
@@ -2,5 +2,6 @@ export * from './errors.js';
2
2
  export * from './failure.js';
3
3
  export * from './consts.js';
4
4
  export * from './protocol.js';
5
- export { pickPerSchema, provideRequest, stab } from './helper.js';
5
+ export { clientRequestHelper, createClientRequestHelper, provideRequest } from './helper.js';
6
+ export { stab } from './stab.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { RefedEntrypointHandler } from './types.js';
2
+ /** The no-op handler of a URL-only frontend binding. */
3
+ export declare const stab: RefedEntrypointHandler<{}>;
4
+ //# sourceMappingURL=stab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stab.d.ts","sourceRoot":"","sources":["../src/stab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExD,wDAAwD;AACxD,eAAO,MAAM,IAAI,EAAE,sBAAsB,CAAC,EAAE,CAE3C,CAAA"}
package/build/stab.js ADDED
@@ -0,0 +1,5 @@
1
+ /** The no-op handler of a URL-only frontend binding. */
2
+ export const stab = () => () => {
3
+ return void 0;
4
+ };
5
+ //# sourceMappingURL=stab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stab.js","sourceRoot":"","sources":["../src/stab.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,CAAC,MAAM,IAAI,GAA+B,GAAG,EAAE,CAAC,GAAG,EAAE;IACzD,OAAO,KAAK,CAAQ,CAAA;AACtB,CAAC,CAAA"}
package/build/types.d.ts CHANGED
@@ -26,9 +26,9 @@ export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientReques
26
26
  * its request and reply types are read directly from the declaration and cannot be replaced at a
27
27
  * call site.
28
28
  */
29
- export type ClientProtocolEntrypoint<Protocol extends EntrypointProtocolDeclaration> = Omit<ClientEntrypoint, 'call' | 'invoke' | 'url' | 'validate' | 'request'> & RegisteredEntrypoint<RequestOf<Protocol>, import('@owlmeans/entrypoint').ResponseOf<Protocol>> & {
29
+ export interface ClientProtocolEntrypoint<Protocol extends EntrypointProtocolDeclaration> extends Omit<ClientEntrypoint, 'call' | 'invoke' | 'url' | 'validate' | 'request'>, RegisteredEntrypoint<RequestOf<Protocol>, import('@owlmeans/entrypoint').ResponseOf<Protocol>> {
30
30
  readonly protocol: Protocol;
31
- };
31
+ }
32
32
  export interface EntrypointCall<T, Req extends ClientRequest = ClientRequest> {
33
33
  <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>;
34
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { AbstractRequest, EntrypointHandler } from '@owlmeans/entrypoint';
2
+ import type { ClientEntrypointOptions, EntrypointInvoke, EntrypointUrlOptions } from '../../types.js';
3
+ /** How a client entrypoint reaches its backend: the handler, the round trip and the address. */
4
+ export interface ApiCallHelper<T, R extends AbstractRequest = AbstractRequest> {
5
+ /**
6
+ * The handler that carries the entrypoint's call: the transport service bound to its route's
7
+ * protocol, else the API client of the web service its route answers on.
8
+ */
9
+ apiHandler: EntrypointHandler;
10
+ /** The round trip behind `invoke()`: builds the request, validates it on demand and notifies failure observers. */
11
+ apiInvoke: (opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R>;
12
+ /** The address behind `url()`: `:params` filled in, the query appended, absolute when the route is not local. */
13
+ entrypointUrl: (req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string>;
14
+ }
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/handler/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErG,gGAAgG;AAChG,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe;IAC3E;;;OAGG;IACH,UAAU,EAAE,iBAAiB,CAAA;IAC7B,mHAAmH;IACnH,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,uBAAuB,KAAK,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACrE,iHAAiH;IACjH,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAClF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/handler/types.ts"],"names":[],"mappings":""}
@@ -1,6 +1,8 @@
1
- import { type AbstractRequest, type EntrypointHandler } from '@owlmeans/entrypoint';
2
- import type { EntrypointInvoke, EntrypointUrlOptions, ClientEntrypointOptions, EntrypointRef, ClientRequest } from '../types.js';
3
- export declare const apiHandler: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>) => EntrypointHandler;
4
- export declare const apiInvoke: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R>;
1
+ import { type AbstractRequest } from '@owlmeans/entrypoint';
2
+ import type { EntrypointUrlOptions, EntrypointRef, ClientRequest } from '../types.js';
3
+ import type { ApiCallHelper } from './handler/types.js';
4
+ export declare const makeApiCallHelper: <T, R extends AbstractRequest = AbstractRequest>(ref: EntrypointRef<T, R>) => ApiCallHelper<T, R>;
5
+ export declare const apiCallOf: <T, R extends AbstractRequest = AbstractRequest<{}>>(target: EntrypointRef<T, R>) => ApiCallHelper<T, R>;
6
+ /** @deprecated compat:factory-refactor — use `makeApiCallHelper(ref).entrypointUrl(…)` */
5
7
  export declare const entrypointUrl: <T, R extends ClientRequest = ClientRequest>(ref: EntrypointRef<T, R>, req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string>;
6
8
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAgF,MAAM,sBAAsB,CAAA;AACjK,OAAO,KAAK,EAAoB,gBAAgB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,aAAa,EAAE,aAAa,EAA4B,MAAM,aAAa,CAAA;AAc5K,eAAO,MAAM,UAAU,EAAE,CACvB,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,EAC9C,GAAG,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,iBAoC9B,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,CA8DvD,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
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/utils/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAwG,MAAM,sBAAsB,CAAA;AACjK,OAAO,KAAK,EAAsC,oBAAoB,EAA2B,aAAa,EAAE,aAAa,EAA4B,MAAM,aAAa,CAAA;AAU5K,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAIvD,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,CAAC,SAAS,eAAe,GAAG,eAAe,OACzE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KACvB,aAAa,CAAC,CAAC,EAAE,CAAC,CA4IpB,CAAA;AAED,eAAO,MAAM,SAAS,GAhJY,CAAC,EAAE,CAAC,SAAS,eAAe,2EAgJA,CAAA;AAE9D,0FAA0F;AAC1F,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,SAAS,aAAa,GAAG,aAAa,OACjE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,OAAO,CAAC,CAAC,CAAC,SAAS,oBAAoB,KACtE,OAAO,CAAC,MAAM,CAAoD,CAAA"}
@@ -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
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-entrypoint",
3
- "version": "0.1.18-rc.46",
3
+ "version": "0.1.18-rc.48",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,16 +28,16 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@owlmeans/api": "^0.1.18-rc.46",
32
- "@owlmeans/client-config": "^0.1.18-rc.43",
33
- "@owlmeans/client-context": "^0.1.18-rc.47",
34
- "@owlmeans/client-route": "^0.1.18-rc.47",
35
- "@owlmeans/config": "^0.1.18-rc.43",
36
- "@owlmeans/context": "^0.1.18-rc.33",
37
- "@owlmeans/entrypoint": "^0.1.18-rc.40",
38
- "@owlmeans/error": "^0.1.18-rc.37",
39
- "@owlmeans/log": "^0.1.18-rc.1",
40
- "@owlmeans/route": "^0.1.18-rc.34",
31
+ "@owlmeans/api": "^0.1.18-rc.48",
32
+ "@owlmeans/client-config": "^0.1.18-rc.44",
33
+ "@owlmeans/client-context": "^0.1.18-rc.49",
34
+ "@owlmeans/client-route": "^0.1.18-rc.49",
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
42
  "qs": "^6.16.0"
43
43
  },
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
@@ -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,7 +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'
5
6
  export * from './consts.js'
6
7
  export * from './protocol.js'
7
- 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
@@ -31,12 +31,7 @@ export interface ClientEntrypoint<T = {}, R extends ClientRequest = ClientReques
31
31
  * its request and reply types are read directly from the declaration and cannot be replaced at a
32
32
  * call site.
33
33
  */
34
- export type ClientProtocolEntrypoint<Protocol extends EntrypointProtocolDeclaration> =
35
- Omit<ClientEntrypoint, 'call' | 'invoke' | 'url' | 'validate' | 'request'>
36
- & RegisteredEntrypoint<RequestOf<Protocol>, import('@owlmeans/entrypoint').ResponseOf<Protocol>>
37
- & {
38
- readonly protocol: Protocol
39
- }
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 }
40
35
 
41
36
  export interface EntrypointCall<T, Req extends ClientRequest = ClientRequest> {
42
37
  <Type extends T, R extends Req = Req>(req?: Partial<R>): Promise<Type>
@@ -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
+ }
@@ -3,62 +3,60 @@ import { DEFAULT_KEY } from '@owlmeans/client-config'
3
3
  import { type AbstractRequest, type EntrypointHandler, type EntrypointTransport, EntrypointOutcome, provideResponse, transportAlias } from '@owlmeans/entrypoint'
4
4
  import type { ClientEntrypoint, EntrypointInvoke, EntrypointUrlOptions, ClientEntrypointOptions, EntrypointRef, ClientRequest, EntrypointFailureService } from '../types.js'
5
5
  import { validate } from './entrypoint.js'
6
- import { extractParams } from '@owlmeans/client-route'
6
+ import { clientRouteHelper } from '@owlmeans/client-route'
7
7
  import { PARAM, RouteMethod, RouteProtocols } from '@owlmeans/route'
8
8
  import { stringify } from 'qs'
9
- import { assertContext } from '@owlmeans/context'
9
+ import { assertContext, memoHelper } from '@owlmeans/context'
10
10
  import { makeSecurityHelper } from '@owlmeans/config'
11
11
  import { ENTRYPOINT_FAILURE_SERVICE } from '../consts.js'
12
12
  import { logger } from '@owlmeans/log'
13
13
  import type { Config, Context } from './types.local.js'
14
+ import type { ApiCallHelper } from './handler/types.js'
14
15
 
15
16
  const log = logger('client-entrypoint')
16
17
 
18
+ export const makeApiCallHelper = <T, R extends AbstractRequest = AbstractRequest>(
19
+ ref: EntrypointRef<T, R>
20
+ ): ApiCallHelper<T, R> => {
21
+ const apiHandler: EntrypointHandler = async (req, res) => {
22
+ const location = `client-entrypoint:api-handler:${ref.ref?.alias}`
23
+ const context = assertContext<Config, Context>(ref.ref?.ctx as Context, location)
17
24
 
18
- export const apiHandler: <
19
- T, R extends AbstractRequest = AbstractRequest
20
- >(ref: EntrypointRef<T, R>) => EntrypointHandler = (ref) => async (req, res) => {
21
- const location = `client-entrypoint:api-handler:${ref.ref?.alias}`
22
- const context = assertContext<Config, Context>(ref.ref?.ctx as Context, location)
23
-
24
- if (context.cfg.webService == null) {
25
- throw new SyntaxError('No webService provided')
26
- }
25
+ if (context.cfg.webService == null) {
26
+ throw new SyntaxError('No webService provided')
27
+ }
27
28
 
28
- const ep = context.entrypoint<ClientEntrypoint>(req.alias)
29
+ const ep = context.entrypoint<ClientEntrypoint>(req.alias)
29
30
 
30
- // A route names the protocol it answers on. Whatever is bound under that protocol takes the
31
- // call, so a consumer writes `ep.call(...)` without learning which transport ran.
32
- const transport = transportAlias(ep.route.route.protocol)
33
- if (context.hasService(transport)) {
34
- req.path = ep.path()
31
+ // A route names the protocol it answers on. Whatever is bound under that protocol takes the
32
+ // call, so a consumer writes `ep.call(...)` without learning which transport ran.
33
+ const transport = transportAlias(ep.route.route.protocol)
34
+ if (context.hasService(transport)) {
35
+ req.path = ep.path()
35
36
 
36
- return context.service<EntrypointTransport>(transport).handle(req, res)
37
- }
37
+ return context.service<EntrypointTransport>(transport).handle(req, res)
38
+ }
38
39
 
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()
40
+ // Which web client carries this call is decided by the service the route answers on — the one it
41
+ // names, or the one the context picks for its app type when it names none.
42
+ const route = ep.service()
42
43
 
43
- const alias: string | undefined = typeof context.cfg.webService === 'string'
44
- ? context.cfg.webService
45
- : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY]
44
+ const alias: string | undefined = typeof context.cfg.webService === 'string'
45
+ ? context.cfg.webService
46
+ : context.cfg.webService[route.service] ?? context.cfg.webService[DEFAULT_KEY]
46
47
 
47
- if (alias == null) {
48
- throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`)
49
- }
48
+ if (alias == null) {
49
+ throw new SyntaxError(`Can't cast web service alias for ${ep.alias} entrypoint`)
50
+ }
50
51
 
51
- const service: ApiClient = context.service(alias)
52
+ const service: ApiClient = context.service(alias)
52
53
 
53
- req.path = ep.path()
54
+ req.path = ep.path()
54
55
 
55
- return service.handler(req, res as any)
56
- }
56
+ return service.handler(req, res as any)
57
+ }
57
58
 
58
- export const apiInvoke: <
59
- T, R extends AbstractRequest = AbstractRequest
60
- >(ref: EntrypointRef<T, R>, opts?: ClientEntrypointOptions) => EntrypointInvoke<T, R> =
61
- (ref, opts) => (async (req) => {
59
+ const apiInvoke = (opts?: ClientEntrypointOptions): EntrypointInvoke<T, R> => (async (req: Partial<R> | undefined) => {
62
60
  const ep = ref.ref
63
61
  if (ep == null) {
64
62
  throw new SyntaxError('Try to make API call before the entrypoint is created')
@@ -108,7 +106,7 @@ export const apiInvoke: <
108
106
  throw new SyntaxError(`Use entrypoint ${ep.alias} without context`)
109
107
  }
110
108
  try {
111
- await apiHandler(ref)(request, reply)
109
+ await apiHandler(request, reply)
112
110
  if (reply.error != null) throw reply.error
113
111
  } catch (error) {
114
112
  if (ctx.hasService(ENTRYPOINT_FAILURE_SERVICE)) {
@@ -121,41 +119,49 @@ export const apiInvoke: <
121
119
  return { value: reply.value ?? null, outcome: reply.outcome ?? EntrypointOutcome.Ok }
122
120
  }) as EntrypointInvoke<any>
123
121
 
124
- export const entrypointUrl: <
125
- T, R extends ClientRequest = ClientRequest
126
- >(ref: EntrypointRef<T, R>, req?: Partial<R>, opts?: EntrypointUrlOptions) => Promise<string> = async (ref, req, opts) => {
127
- const ep = ref.ref
128
- if (ep == null) {
129
- throw new SyntaxError('Try to make URL before the entrypoint is created')
130
- }
131
- const ctx = ep.ctx
132
- if (ctx == null) {
133
- throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`)
134
- }
122
+ const entrypointUrl = async (req?: Partial<R>, opts?: EntrypointUrlOptions): Promise<string> => {
123
+ const ep = ref.ref
124
+ if (ep == null) {
125
+ throw new SyntaxError('Try to make URL before the entrypoint is created')
126
+ }
127
+ const ctx = ep.ctx
128
+ if (ctx == null) {
129
+ throw new SyntaxError(`No context provided in entrypointUrl for ${ep.alias} entrypoint`)
130
+ }
131
+
132
+ // The base is left off here: an in-service URL is addressed relative to it, and the absolute
133
+ // branch below has `makeUrl` prepend it.
134
+ const epPath = ep.path()
135
+ const pathParams = clientRouteHelper.extractParams(epPath)
136
+ let path = pathParams.reduce((p, param) => {
137
+ return p.replace(`${PARAM}${param}`, `${req?.params?.[param as keyof typeof req.params]}`)
138
+ }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '')
139
+
140
+ // A socket address is always absolute, whoever owns the route. `new WebSocket(path)` resolves a
141
+ // relative value against the PAGE's origin, which in a split deployment is the web host and not
142
+ // the service that answers the upgrade — so the handshake goes somewhere that never speaks it
143
+ // and dies on a gateway timeout. Only a same-origin HTTP route benefits from staying relative.
144
+ const socket = ep.route.route.protocol === RouteProtocols.SOCKET
145
+
146
+ // Locality is a question about the RESOLVED service, not about what the declaration happens to
147
+ // name: a route that names no service belongs to the asking context, and addressing it absolutely
148
+ // would turn in-app navigation into a full page load.
149
+ if (socket || !ep.isLocal() || opts?.absolute === true) {
150
+ const helper = makeSecurityHelper(ctx)
151
+ path = helper.makeUrl(
152
+ ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure }
153
+ )
154
+ }
135
155
 
136
- // The base is left off here: an in-service URL is addressed relative to it, and the absolute
137
- // branch below has `makeUrl` prepend it.
138
- const epPath = ep.path()
139
- const pathParams = extractParams(epPath)
140
- let path = pathParams.reduce((p, param) => {
141
- return p.replace(`${PARAM}${param}`, `${req?.params?.[param as keyof typeof req.params]}`)
142
- }, epPath) + (req?.query != null ? `?${stringify(req?.query)}` : '')
143
-
144
- // A socket address is always absolute, whoever owns the route. `new WebSocket(path)` resolves a
145
- // relative value against the PAGE's origin, which in a split deployment is the web host and not
146
- // the service that answers the upgrade — so the handshake goes somewhere that never speaks it
147
- // and dies on a gateway timeout. Only a same-origin HTTP route benefits from staying relative.
148
- const socket = ep.route.route.protocol === RouteProtocols.SOCKET
149
-
150
- // Locality is a question about the RESOLVED service, not about what the declaration happens to
151
- // name: a route that names no service belongs to the asking context, and addressing it absolutely
152
- // would turn in-app navigation into a full page load.
153
- if (socket || !ep.isLocal() || opts?.absolute === true) {
154
- const helper = makeSecurityHelper(ctx)
155
- path = helper.makeUrl(
156
- ep.address(), path, { host: req?.host, base: req?.base, forceUnsecure: req?.unsecure }
157
- )
156
+ return path
158
157
  }
159
158
 
160
- return path
159
+ return { apiHandler, apiInvoke, entrypointUrl }
161
160
  }
161
+
162
+ export const apiCallOf = memoHelper.oncePer(makeApiCallHelper)
163
+
164
+ /** @deprecated compat:factory-refactor — use `makeApiCallHelper(ref).entrypointUrl(…)` */
165
+ export const entrypointUrl = <T, R extends ClientRequest = ClientRequest>(
166
+ ref: EntrypointRef<T, R>, req?: Partial<R>, opts?: EntrypointUrlOptions
167
+ ): Promise<string> => makeApiCallHelper(ref).entrypointUrl(req, opts)
@@ -1,3 +1,4 @@
1
1
 
2
+ export type * from './handler/types.js'
2
3
  export * from './entrypoint.js'
3
4
  export * from './handler.js'