@owlmeans/entrypoint 0.1.18-rc.8 → 0.1.18-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,12 +4,17 @@ Entrypoint system — the URL unit abstraction shared between server and client
4
4
 
5
5
  ## Overview
6
6
 
7
- - An **entrypoint** is a URL unit: an alias + path + optional guards/gates/filters
7
+ - An **entrypoint** is a URL unit: an alias + a route declaration + optional guards/gates/filters
8
8
  - On the server, entrypoints become API routes with attached handlers
9
9
  - On the client, entrypoints provide URL generation and navigation
10
10
  - All AJV validation schemas are defined at entrypoint level, keeping data contracts consistent fullstack
11
11
  - Most commonly used via re-exports in `@owlmeans/server-app` or `@owlmeans/client-entrypoint`
12
12
 
13
+ The route declaration an entrypoint carries is immutable: its `path` always stays the segment this
14
+ entrypoint contributes under its parent. Addresses are computed on demand against the context the
15
+ entrypoint is registered in — `path()` walks the parent chain, `mount()` adds the service base,
16
+ `address()` picks host, port and scheme — so one declaration answers correctly on both sides.
17
+
13
18
  ## Installation
14
19
 
15
20
  ```bash
@@ -24,7 +29,7 @@ Define an entrypoint with body validation and a guard:
24
29
  import { entrypoint, guard, filter, body, params } from '@owlmeans/server-app'
25
30
  import { route } from '@owlmeans/route'
26
31
 
27
- const createStoryModule = entrypoint(
32
+ const createStoryEntrypoint = entrypoint(
28
33
  route('story-create', '/stories', { method: 'POST', parent: 'api' }),
29
34
  filter(body({
30
35
  type: 'object',
@@ -67,14 +72,24 @@ Attaches validation schemas (AJV format) to the entrypoint.
67
72
 
68
73
  Build a `Filter` object with the given AJV schema applied to the corresponding request part.
69
74
 
70
- ### `parent(entrypoint, parentAlias): CommonEntrypoint`
75
+ ### Parentship
71
76
 
72
- Sets a parent-child relationship so child entrypoints inherit guards/gates.
77
+ A child names its parent in the route declaration (`route('story-create', '/stories', { parent: 'api' })`).
78
+ `path()` prefixes the parent's segments, and `getGuards()` / `getGates()` collect the parent's on
79
+ every call — so a guard added to a parent later still applies.
73
80
 
74
81
  ### `provideResponse<T>(): AbstractResponse<T>`
75
82
 
76
83
  Creates a response object for use in non-elevated handlers.
77
84
 
85
+ ### Transport
86
+
87
+ A route's protocol picks the carrier. Register a service under `transportAlias(protocol)` —
88
+ `transport:<protocol>` — implementing `EntrypointTransport { protocol, handle }`, and every call to
89
+ an entrypoint on that protocol goes through it. A consumer writes `ep.call(...)` and never learns
90
+ whether that became an HTTP request, a socket message or a queued job. Without a registered
91
+ transport the call goes over HTTP.
92
+
78
93
  ### `EntrypointOutcome`
79
94
 
80
95
  ```typescript
@@ -85,7 +100,10 @@ enum EntrypointOutcome { Ok, Accepted, Created, Finished }
85
100
 
86
101
  - `AbstractRequest<T>` — request with `params`, `body`, `query`, `headers`, `auth`
87
102
  - `AbstractResponse<T>` — response with `resolve(value, outcome?)` and `reject(error)`
88
- - `CommonEntrypoint` — entrypoint with `getAlias()`, `getPath()`, `getGuards()`, `handle`
103
+ - `CommonEntrypoint` — entrypoint with `alias`, `route`, `handle`, and the context-computed
104
+ `segment()`, `path()`, `mount()`, `service()`, `address()`, `isLocal()`, `parent()`,
105
+ `getGuards()`, `getGates()`
106
+ - `EntrypointTransport` — `{ protocol, handle }`, the service that carries a call for one protocol
89
107
 
90
108
  ## Related Packages
91
109
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/entrypoint",
4
- "version": "0.1.18-rc.7",
5
- "generatedAt": "2026-08-24T21:14:00.139Z",
4
+ "version": "0.1.18-rc.9",
5
+ "generatedAt": "2026-09-01T16:28:56.997Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: entrypoint
3
- description: How to use @owlmeans/entrypoint — declarative entrypoint/route definitions with entrypoint(), guard(), gate(), filter(), body(), params(), query() builders. Auto-invoked when importing from this package or defining a service entrypoint declaration. Also covers the deprecated @owlmeans/module reexport shim (module() → entrypoint()).
3
+ description: How to use @owlmeans/entrypoint — declarative entrypoint definitions over immutable route declarations, with entrypoint(), guard(), gate(), filter(), body(), params(), query() builders, the address accessors, and the transport seam. Auto-invoked when importing from this package or defining a service entrypoint declaration.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,22 +8,28 @@ user-invocable: false
8
8
  # @owlmeans/entrypoint
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/entrypoint": "^0.1.18-rc.7"` in `dependencies`
11
+ **Install:** `"@owlmeans/entrypoint": "^0.1.18-rc.9"` in `dependencies`
12
+
13
+ An entrypoint is a **URL unit**: an immutable route declaration plus the guards, gates and schemas
14
+ it answers under. It is the single concept an application declares once in a shared package and
15
+ elevates on either side.
12
16
 
13
17
  ## Key Exports
14
18
 
15
19
  | Export | Description |
16
20
  |--------|-------------|
17
- | `entrypoint(route, opts?)` | Declare an entrypoint on a route |
21
+ | `entrypoint(route, opts?)` | Declare an entrypoint on a route model |
18
22
  | `guard(alias, opts?)` | Require a guard; returns options, so it wraps rather than takes them |
19
23
  | `gate(alias, params, opts?)` | Require a gate; passed as the `opts` of `guard(...)` |
20
24
  | `filter(filter, opts?)` | Attach request validators |
21
- | `body(Schema)` | AJV body validator |
22
- | `params(Schema)` | URL params validator |
23
- | `query(Schema)` | Query string validator |
24
- | `ClientEntrypoint<T>` types | Resolved entrypoint type used for `ctx.entrypoint<...>(alias).call(...)` |
25
+ | `body(Schema)` / `params(Schema)` / `query(Schema)` / `headers(Schema)` / `response(Schema, code?)` | AJV validators composed into a `Filter` |
26
+ | `CommonEntrypoint` | The entrypoint interface — declaration, guards/gates, address accessors |
27
+ | `AbstractRequest` / `AbstractResponse` | The request and reply shapes every handler sees |
28
+ | `provideResponse(original?)` | Build a reply object a handler resolves or rejects |
29
+ | `GuardService` / `GateService` | What a guard and a gate implement |
25
30
  | `EntrypointOutcome` | Enum: Ok, Accepted, Created, Finished |
26
- | Constants | Built-in entrypoint aliases |
31
+ | `EntrypointTransport` | `{ protocol, handle }` — a carrier bound to a route protocol |
32
+ | `transportAlias(protocol?)` | The service alias a transport registers under (`transport:<protocol>`) |
27
33
 
28
34
  `guard`, `gate` and `filter` are **options-object combinators, not variadic composers**. Each
29
35
  returns a `CommonEntrypointOptions` and takes the next one as its final argument, so they nest:
@@ -43,6 +49,75 @@ when it agrees.
43
49
 
44
50
  - `./utils` — entrypoint construction helpers (`isEntrypoint`, `CreateEntrypointSignature`)
45
51
 
52
+ ## Declaration and model
53
+
54
+ The `RouteDeclaration` an entrypoint carries is plain, immutable data: its `path` is the **segment**
55
+ this entrypoint contributes under its parent, and nothing rewrites it. `RouteModel` only wraps that
56
+ declaration. Every address question is therefore a question about the declaration asked **against
57
+ the context that asks it** — computed on demand, never stored — so the same declaration answers one
58
+ way in a server and another in a client without being touched.
59
+
60
+ | Accessor | Answers |
61
+ |----------|---------|
62
+ | `segment()` | The segment declared under the parent |
63
+ | `path()` | Every ancestor's segment, then this one |
64
+ | `mount()` | `base` + `path()` — what a server registers and a client requests |
65
+ | `service()` | The resolved service route this entrypoint answers on |
66
+ | `address()` | `{ host, port, base, secure, protocol }` — where it actually answers |
67
+ | `isLocal()` | Does it belong to the service the asking context IS? |
68
+ | `parent()` | The parent entrypoint, or `null` |
69
+ | `getGuards()` | Own guards plus every ancestor's, deduped |
70
+ | `getGates()` | Own gate plus every ancestor's, as `[gate, params]` |
71
+
72
+ `getGuards()` and `getGates()` walk the chain afresh on every call and are never memoised: a guard
73
+ attached to an ancestor after this entrypoint was first asked still has to count.
74
+
75
+ ## Calling an entrypoint
76
+
77
+ Three explicit verbs, so the caller says which answer it wants:
78
+
79
+ ```typescript
80
+ const project = await ep.call({ params: { id } }) // the VALUE; the reply error is thrown
81
+ const { value, outcome } = await ep.invoke({ body }) // value AND outcome
82
+ const href = await ep.url({ params: { id } }, { absolute: true }) // the URL string
83
+ ```
84
+
85
+ Use `invoke` only where the outcome decides what happens next; `call` covers everything else. An
86
+ entrypoint that **renders a screen** is addressed by URL and never over the wire — it throws from
87
+ `call()`/`invoke()` telling the caller to use `url()`.
88
+
89
+ The three verbs sit on the callable entrypoint that `@owlmeans/client-entrypoint` produces; the
90
+ declaration built here is what they address.
91
+
92
+ ## Elevation
93
+
94
+ `elevate` replaces the declaration in the entrypoint list with its elevated counterpart, so it is
95
+ **idempotent**: elevating the same alias again simply replaces the element once more. Guards passed
96
+ at elevation are **unioned** with the ones the entrypoint declared — elevating adds guards, it never
97
+ swaps them. Server-side elevation lives in `@owlmeans/server-entrypoint`, client-side callability is
98
+ an explicit opt-in through `@owlmeans/client-entrypoint`.
99
+
100
+ ## Transport seam
101
+
102
+ A route names the protocol it answers on, and a protocol may be carried by something other than
103
+ HTTP. A service registered under `transportAlias(protocol)` implementing `EntrypointTransport` takes
104
+ the call, so a consumer writes `ep.call(...)` and never learns whether that became an HTTP request,
105
+ a socket message or a queued job. Bind nothing and the call goes over HTTP.
106
+
107
+ ```typescript
108
+ import { transportAlias } from '@owlmeans/entrypoint'
109
+ import type { EntrypointTransport } from '@owlmeans/entrypoint'
110
+ import { RouteProtocols } from '@owlmeans/route'
111
+ import { createService } from '@owlmeans/context'
112
+
113
+ const transport = createService<EntrypointTransport>(transportAlias(RouteProtocols.SOCKET), {
114
+ protocol: RouteProtocols.SOCKET,
115
+ handle: async (req, res) => { /* carry the call, resolve or reject res */ }
116
+ }, service => async () => { service.initialized = true })
117
+
118
+ context.registerService(transport)
119
+ ```
120
+
46
121
  ## Usage
47
122
 
48
123
  Define entrypoints in a shared `common` package, then `elevate()` them with handlers in server/web packages:
@@ -54,7 +129,7 @@ import { DEFAULT_GUARD } from '@owlmeans/auth-common'
54
129
  import { OIDC_GATE } from '@owlmeans/oidc'
55
130
  import { CreateProjectSchema } from './schemas.js'
56
131
 
57
- export const managerModules = [
132
+ export const managerEntrypoints = [
58
133
  entrypoint(
59
134
  route(manager.back.account.base, '/account'),
60
135
  guard(DEFAULT_GUARD, gate(OIDC_GATE, [`my-service-account-{entity}`]))
@@ -71,6 +146,6 @@ export const managerModules = [
71
146
 
72
147
  ## Depends On
73
148
 
74
- - `@owlmeans/route` — `route()`, `RouteMethod`
149
+ - `@owlmeans/route` — `route()`, `RouteMethod`, `RouteProtocols`, and the address helpers under `/utils`
75
150
  - `@owlmeans/auth-common` — guard aliases (`DEFAULT_GUARD`)
76
151
  - `@owlmeans/error`, `@owlmeans/i18n`
package/build/consts.d.ts CHANGED
@@ -4,4 +4,9 @@ export declare enum EntrypointOutcome {
4
4
  Created = "created",
5
5
  Finished = "finished"
6
6
  }
7
+ /**
8
+ * Service alias a transport registers under. The default protocol is the web one, so an application
9
+ * that binds nothing keeps talking HTTP.
10
+ */
11
+ export declare const transportAlias: (protocol?: string) => string;
7
12
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,iBAAiB;IAC3B,EAAE,OAAO;IACT,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,iBAAiB;IAC3B,EAAE,OAAO;IACT,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,WAAU,MAAe,WAA4B,CAAA"}
package/build/consts.js CHANGED
@@ -5,4 +5,9 @@ export var EntrypointOutcome;
5
5
  EntrypointOutcome["Created"] = "created";
6
6
  EntrypointOutcome["Finished"] = "finished";
7
7
  })(EntrypointOutcome || (EntrypointOutcome = {}));
8
+ /**
9
+ * Service alias a transport registers under. The default protocol is the web one, so an application
10
+ * that binds nothing keeps talking HTTP.
11
+ */
12
+ export const transportAlias = (protocol = 'http') => `transport:${protocol}`;
8
13
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,iBAKX;AALD,WAAY,iBAAiB;IAC3B,8BAAS,CAAA;IACT,0CAAqB,CAAA;IACrB,wCAAmB,CAAA;IACnB,0CAAqB,CAAA;AACvB,CAAC,EALW,iBAAiB,KAAjB,iBAAiB,QAK5B"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,iBAKX;AALD,WAAY,iBAAiB;IAC3B,8BAAS,CAAA;IACT,0CAAqB,CAAA;IACrB,wCAAmB,CAAA;IACnB,0CAAqB,CAAA;AACvB,CAAC,EALW,iBAAiB,KAAjB,iBAAiB,QAK5B;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,WAAmB,MAAM,EAAE,EAAE,CAAC,aAAa,QAAQ,EAAE,CAAA"}
@@ -1,5 +1,4 @@
1
1
  import type { CommonEntrypoint } from './types.js';
2
2
  import type { CreateEntrypointSignature } from './utils/types.js';
3
3
  export declare const entrypoint: CreateEntrypointSignature<CommonEntrypoint>;
4
- export declare const parent: <T extends CommonEntrypoint | CommonEntrypoint[]>(ep: T, aliasOrParent: string, _parent?: string) => T;
5
4
  //# sourceMappingURL=entrypoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAEjE,eAAO,MAAM,UAAU,EAAE,yBAAyB,CAAC,gBAAgB,CAqFlE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,MAAM,YAAY,MAAM,KAAG,CAcxH,CAAA"}
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAKlD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAEjE,eAAO,MAAM,UAAU,EAAE,yBAAyB,CAAC,gBAAgB,CAsDlE,CAAA"}
@@ -1,61 +1,37 @@
1
1
  import { appendContextual } from '@owlmeans/context';
2
+ import { isLocalRoute, resolveAddress, resolveMount, resolvePath, resolveService } from '@owlmeans/route/utils';
2
3
  export const entrypoint = (route, opts) => {
3
- let guards = null;
4
- let gates = null;
5
4
  const ep = appendContextual(route.route.alias, {
6
5
  _entrypoint: true,
7
- _module: true,
8
6
  sticky: false,
9
7
  route,
10
- getAlias: () => ep.route.route.alias,
11
- getPath: () => ep.route.route.path,
12
- getParentAlias: () => ep.route.route.parent ?? null,
13
- hasParent: () => ep.getParentAlias() != null,
14
- resolve: async () => {
15
- if (ep.ctx == null) {
16
- throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`);
17
- }
18
- await ep.route.resolve(ep.ctx);
19
- return ep;
20
- },
21
- getParent: () => {
22
- const parentAlias = ep.getParentAlias();
23
- if (parentAlias == null) {
24
- throw new SyntaxError(`Entrypoint has no parent - ${ep.getAlias()}`);
25
- }
26
- if (ep.ctx == null) {
27
- throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`);
28
- }
29
- return ep.ctx.entrypoint(parentAlias);
30
- },
31
- setService: service => {
32
- if (ep.route.route.resolved) {
33
- throw new SyntaxError(`Cannot update a resolved entrypoint - ${ep.getAlias()}`);
34
- }
35
- ep.route.route.service = service;
36
- },
8
+ segment: () => ep.route.route.path,
9
+ path: () => resolvePath(ep.assertCtx(), ep.route.route),
10
+ mount: () => resolveMount(ep.assertCtx(), ep.route.route),
11
+ service: () => resolveService(ep.assertCtx(), ep.route.route),
12
+ address: () => resolveAddress(ep.assertCtx(), ep.route.route),
13
+ isLocal: () => isLocalRoute(ep.assertCtx(), ep.route.route),
14
+ parent: () => ep.route.route.parent == null ? null
15
+ : ep.assertCtx().entrypoint(ep.route.route.parent),
16
+ // Walked afresh on every call: a guard attached to an ancestor after this entrypoint was first
17
+ // asked still has to count.
37
18
  getGuards: () => {
38
- if (guards != null) {
39
- return guards;
40
- }
41
- guards = ep.guards ?? [];
42
- if (ep.hasParent()) {
43
- guards.push(...ep.getParent().getGuards().filter(guard => !guards?.includes(guard)));
19
+ const guards = [...ep.guards ?? []];
20
+ const parent = ep.parent();
21
+ if (parent != null) {
22
+ guards.push(...parent.getGuards().filter(guard => !guards.includes(guard)));
44
23
  }
45
24
  return guards;
46
25
  },
47
26
  getGates: () => {
48
- if (gates != null) {
49
- return gates;
50
- }
51
- gates = ep.gate != null ? [[
27
+ const gates = ep.gate != null ? [[
52
28
  ep.gate, ep.gateParams == null
53
29
  ? [] : Array.isArray(ep.gateParams)
54
30
  ? ep.gateParams : [ep.gateParams]
55
31
  ]] : [];
56
- if (ep.hasParent()) {
57
- gates.push(...ep.getParent().getGates()
58
- .filter(([gate]) => !gates?.some(([g]) => g === gate)));
32
+ const parent = ep.parent();
33
+ if (parent != null) {
34
+ gates.push(...parent.getGates().filter(([gate]) => !gates.some(([g]) => g === gate)));
59
35
  }
60
36
  return gates;
61
37
  },
@@ -63,18 +39,4 @@ export const entrypoint = (route, opts) => {
63
39
  });
64
40
  return ep;
65
41
  };
66
- export const parent = (ep, aliasOrParent, _parent) => {
67
- if (Array.isArray(ep)) {
68
- if (_parent == null) {
69
- throw SyntaxError('Elevating parent requires parent name to be specified');
70
- }
71
- ep = ep.find(e => e.route.route.alias === aliasOrParent);
72
- if (ep == null) {
73
- throw SyntaxError(`Entrypoint not found ${aliasOrParent}`);
74
- }
75
- return parent(ep, _parent);
76
- }
77
- ep.route.route.parent = aliasOrParent;
78
- return ep;
79
- };
80
42
  //# sourceMappingURL=entrypoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGpD,MAAM,CAAC,MAAM,UAAU,GAAgD,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrF,IAAI,MAAM,GAAoB,IAAI,CAAA;IAClC,IAAI,KAAK,GAAgC,IAAI,CAAA;IAC7C,MAAM,EAAE,GAAqB,gBAAgB,CAAmB,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE;QACjF,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,IAAI;QAEb,MAAM,EAAE,KAAK;QAEb,KAAK;QAEL,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;QACpC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;QAClC,cAAc,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI;QACnD,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,IAAI;QAE5C,OAAO,EAAE,KAAK,IAAgC,EAAE;YAC9C,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,WAAW,CAAC,mCAAmC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YAC3E,CAAC;YAED,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAE9B,OAAO,EAAO,CAAA;QAChB,CAAC;QAED,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,WAAW,GAAG,EAAE,CAAC,cAAc,EAAE,CAAA;YACvC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,IAAI,WAAW,CAAC,8BAA8B,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YACtE,CAAC;YACD,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,WAAW,CAAC,mCAAmC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YAC3E,CAAC;YAED,OAAO,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QACvC,CAAC;QAED,UAAU,EAAE,OAAO,CAAC,EAAE;YACpB,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,WAAW,CAAC,yCAAyC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;YACjF,CAAC;YACD,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA;QAClC,CAAC;QAED,SAAS,EAAE,GAAG,EAAE;YACd,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,OAAO,MAAM,CAAA;YACf,CAAC;YACD,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,EAAE,CAAA;YAExB,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CACT,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CACxE,CAAA;YACH,CAAC;YAED,OAAO,MAAM,CAAA;QACf,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,OAAO,KAAK,CAAA;YACd,CAAC;YAED,KAAK,GAAG,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;oBACzB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,IAAI,IAAI;wBAC5B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC;wBACjC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC;iBACtC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;YAEP,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CACR,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE;qBACzB,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CACzD,CAAA;YACH,CAAC;YAED,OAAO,KAAK,CAAA;QACd,CAAC;QAED,GAAG,IAAI;KACR,CAAC,CAAA;IAEF,OAAO,EAAE,CAAA;AACX,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAkD,EAAK,EAAE,aAAqB,EAAE,OAAgB,EAAK,EAAE;IAC3H,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,WAAW,CAAC,uDAAuD,CAAC,CAAA;QAC5E,CAAC;QACD,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,aAAa,CAAM,CAAA;QAC7D,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;YACf,MAAM,WAAW,CAAC,wBAAwB,aAAa,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,OAAO,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC5B,CAAC;IACD,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,aAAa,CAAA;IAErC,OAAO,EAAE,CAAA;AACX,CAAC,CAAA"}
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,eAAO,MAAM,IAAI,GAAI,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,WAAW,MAAM,KAAG,MAEpE,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,WAAW,MAAM,KAAG,MAErE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,WAAW,MAAM,KAAG,MAEtE,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,SAAS,MAAM,WAAW,MAAM,KAAG,MAMvF,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,CAAC,UAAU,cAAc,CAAC,CAAC,CAAC,WAAW,MAAM,KAAG,MAEvE,CAAA"}
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEpE,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAErE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEtE,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,OAAO,MAAM,EAAE,SAAS,MAAM,KAAG,MAMvF,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEvE,CAAA"}
package/build/helper.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import { Filter, CommonEntrypointOptions, AbstractResponse, CommonEntrypoint } from './types.js';
1
+ import { Filter, CommonEntrypointOptions, AbstractResponse } from './types.js';
2
2
  export declare const filter: (filter: Filter, opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
3
3
  export declare const guard: (guard: string, opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
4
4
  export declare const gate: (gate: string, params: string | string[], opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
5
5
  export declare const provideResponse: <T>(originalResponse?: unknown) => AbstractResponse<T>;
6
- export declare const clone: <M extends CommonEntrypoint>(entrypoints: M[], from: string, to: string, service: string) => void;
7
6
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGhG,eAAO,MAAM,MAAM,WAAY,MAAM,SAAS,uBAAuB,KAAG,uBAAgD,CAAA;AAExH,eAAO,MAAM,KAAK,UAAW,MAAM,SAAS,uBAAuB,KAAG,uBACC,CAAA;AAEvE,eAAO,MAAM,IAAI,SAAU,MAAM,UAAU,MAAM,GAAG,MAAM,EAAE,SAAS,uBAAuB,KAAG,uBACtD,CAAA;AAEzC,eAAO,MAAM,eAAe,GAAI,CAAC,qBAAqB,OAAO,KAAG,gBAAgB,CAAC,CAAC,CAejF,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,gBAAgB,eAAe,CAAC,EAAE,QAAQ,MAAM,MAAM,MAAM,WAAW,MAAM,SAO5G,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE9E,eAAO,MAAM,MAAM,GAAI,QAAQ,MAAM,EAAE,OAAO,uBAAuB,KAAG,uBAAgD,CAAA;AAExH,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,OAAO,uBAAuB,KAAG,uBACC,CAAA;AAEvE,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,uBAAuB,KAAG,uBACtD,CAAA;AAEzC,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,mBAAmB,OAAO,KAAG,gBAAgB,CAAC,CAAC,CAejF,CAAA"}
package/build/helper.js CHANGED
@@ -1,5 +1,3 @@
1
- import { route } from '@owlmeans/route';
2
- import { entrypoint } from './entrypoint.js';
3
1
  export const filter = (filter, opts) => ({ filter, ...opts });
4
2
  export const guard = (guard, opts) => ({ ...opts, guards: [...new Set([guard, ...(opts?.guards ?? [])])] });
5
3
  export const gate = (gate, params, opts) => ({ ...opts, gate, gateParams: params });
@@ -16,11 +14,4 @@ export const provideResponse = (originalResponse) => {
16
14
  };
17
15
  return handler;
18
16
  };
19
- export const clone = (entrypoints, from, to, service) => {
20
- const source = entrypoints.find(e => e.alias === from);
21
- if (source?.route.route != null) {
22
- const _route = { ...source.route.route, service, resolved: false, alias: to };
23
- entrypoints.push(entrypoint(route(to, _route.path, _route)));
24
- }
25
- };
26
17
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,IAA8B,EAA2B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;AAExH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,IAA8B,EAA2B,EAAE,CAC9F,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAyB,EAAE,IAA8B,EAA2B,EAAE,CACvH,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,gBAA0B,EAAuB,EAAE;IACpF,MAAM,OAAO,GAAwB;QACnC,gBAAgB,EAAE,gBAAgB;QAElC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1B,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;YACrB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;QAC3B,CAAC;QAED,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;KACF,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAA6B,WAAgB,EAAE,IAAY,EAAE,EAAU,EAAE,OAAe,EAAE,EAAE;IAC/G,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;IAEtD,IAAI,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAC7E,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC,CAAA;IACnE,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,IAA8B,EAA2B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;AAExH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,IAA8B,EAA2B,EAAE,CAC9F,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAyB,EAAE,IAA8B,EAA2B,EAAE,CACvH,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,gBAA0B,EAAuB,EAAE;IACpF,MAAM,OAAO,GAAwB;QACnC,gBAAgB,EAAE,gBAAgB;QAElC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1B,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;YACrB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;QAC3B,CAAC;QAED,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;KACF,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
package/build/types.d.ts CHANGED
@@ -1,28 +1,42 @@
1
- import type { CommonRouteModel } from '@owlmeans/route';
1
+ import type { ResolvedServiceRoute, RouteAddress, RouteModel, RouteProtocols } from '@owlmeans/route';
2
2
  import type { InitializedService, LazyService, BasicEntrypoint } from '@owlmeans/context';
3
3
  import type { AnySchemaObject } from 'ajv';
4
4
  import type { EntrypointOutcome } from './consts.js';
5
5
  import type { Auth } from '@owlmeans/auth';
6
+ /**
7
+ * A URL unit: an immutable route declaration plus what guards, gates and schemas it answers under.
8
+ *
9
+ * Nothing here is rewritten once declared. Every address question — segment, path, mount, service,
10
+ * host — is a question about the declaration asked against the context the entrypoint is registered
11
+ * in, so the same declaration answers differently in a client and in a server without being touched.
12
+ */
6
13
  export interface CommonEntrypoint extends BasicEntrypoint {
7
- route: CommonRouteModel;
14
+ route: RouteModel;
8
15
  /**
9
16
  * @property {boolean} - if true — router attaches this entrypoint unconditionally
10
17
  * @default false
11
18
  */
12
19
  sticky: boolean;
13
- filter?: Filter;
20
+ /** The guards declared on this entrypoint alone — see `getGuards()` for the inherited set. */
14
21
  guards?: string[];
15
22
  gate?: string;
16
23
  gateParams?: string | string[];
24
+ filter?: Filter;
17
25
  handle?: EntrypointHandler;
18
- getAlias: () => string;
19
- getPath: () => string;
20
- getParentAlias: () => string | null;
21
- hasParent: () => boolean;
22
- resolve: <M extends CommonEntrypoint>() => Promise<M>;
23
- getParent: <M extends CommonEntrypoint>() => M;
24
- setService: (service: string) => void;
26
+ /** The segment this entrypoint contributes under its parent. */
27
+ segment: () => string;
28
+ /** Every ancestor's segment, then this one. */
29
+ path: () => string;
30
+ /** `base` + `path()` — what a server mounts and a client requests. */
31
+ mount: () => string;
32
+ service: () => ResolvedServiceRoute;
33
+ address: () => RouteAddress;
34
+ /** Does this entrypoint belong to the service its context IS? */
35
+ isLocal: () => boolean;
36
+ parent: () => CommonEntrypoint | null;
37
+ /** Own guards and every ancestor's, deduped. Recomputed on each call. */
25
38
  getGuards: () => string[];
39
+ /** Own gate and every ancestor's, as `[gate, params]`. Recomputed on each call. */
26
40
  getGates: () => [string, string[]][];
27
41
  }
28
42
  export interface CommonEntrypointOptions extends Partial<CommonEntrypoint> {
@@ -105,4 +119,15 @@ export interface Filter {
105
119
  response?: AnySchemaObject;
106
120
  headers?: AnySchemaObject;
107
121
  }
122
+ /**
123
+ * How a call to an entrypoint is actually carried.
124
+ *
125
+ * The transport is chosen by the route's protocol, so a consumer always writes `ep.call(...)` and
126
+ * never learns whether that became an HTTP request, a socket message or a queued job. An
127
+ * application binds a protocol by registering a transport service under `transportAlias(protocol)`.
128
+ */
129
+ export interface EntrypointTransport extends InitializedService {
130
+ readonly protocol: RouteProtocols;
131
+ handle: EntrypointHandler;
132
+ }
108
133
  //# sourceMappingURL=types.d.ts.map
@@ -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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,GAAG,IAAI,gBACR,CAAA"}
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,gBAC5B,CAAA"}
@@ -1,2 +1,2 @@
1
- export const isEntrypoint = (obj) => '_entrypoint' in obj || '_module' in obj;
1
+ export const isEntrypoint = (obj) => '_entrypoint' in obj;
2
2
  //# sourceMappingURL=entrypoint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAA2B,EAAE,CACnE,aAAa,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,CAAA"}
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAA2B,EAAE,CACnE,aAAa,IAAI,GAAG,CAAA"}
@@ -1,6 +1,6 @@
1
- import { CommonRouteModel } from '@owlmeans/route';
1
+ import { RouteModel } from '@owlmeans/route';
2
2
  import { CommonEntrypointOptions } from '../types.js';
3
3
  export interface CreateEntrypointSignature<M> {
4
- (route: CommonRouteModel, opts?: CommonEntrypointOptions): M;
4
+ (route: RouteModel, opts?: CommonEntrypointOptions): M;
5
5
  }
6
6
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,uBAAuB,GAAG,CAAC,CAAC;CAC9D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,uBAAuB,GAAG,CAAC,CAAC;CACxD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/entrypoint",
3
- "version": "0.1.18-rc.8",
3
+ "version": "0.1.18-rc.9",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,9 +28,9 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@owlmeans/auth": "^0.1.18-rc.7",
32
- "@owlmeans/context": "^0.1.18-rc.6",
33
- "@owlmeans/route": "^0.1.18-rc.6",
31
+ "@owlmeans/auth": "^0.1.18-rc.8",
32
+ "@owlmeans/context": "^0.1.18-rc.7",
33
+ "@owlmeans/route": "^0.1.18-rc.7",
34
34
  "ajv": "^8.17.1"
35
35
  },
36
36
  "devDependencies": {
package/src/consts.ts CHANGED
@@ -5,3 +5,9 @@ export enum EntrypointOutcome {
5
5
  Created = 'created',
6
6
  Finished = 'finished'
7
7
  }
8
+
9
+ /**
10
+ * Service alias a transport registers under. The default protocol is the web one, so an application
11
+ * that binds nothing keeps talking HTTP.
12
+ */
13
+ export const transportAlias = (protocol: string = 'http') => `transport:${protocol}`
package/src/entrypoint.ts CHANGED
@@ -1,83 +1,55 @@
1
1
  import type { CommonEntrypoint } from './types.js'
2
2
  import { appendContextual } from '@owlmeans/context'
3
+ import {
4
+ isLocalRoute, resolveAddress, resolveMount, resolvePath, resolveService
5
+ } from '@owlmeans/route/utils'
3
6
  import type { CreateEntrypointSignature } from './utils/types.js'
4
7
 
5
8
  export const entrypoint: CreateEntrypointSignature<CommonEntrypoint> = (route, opts) => {
6
- let guards: string[] | null = null
7
- let gates: [string, string[]][] | null = null
8
9
  const ep: CommonEntrypoint = appendContextual<CommonEntrypoint>(route.route.alias, {
9
10
  _entrypoint: true,
10
- _module: true,
11
11
 
12
12
  sticky: false,
13
13
 
14
14
  route,
15
15
 
16
- getAlias: () => ep.route.route.alias,
17
- getPath: () => ep.route.route.path,
18
- getParentAlias: () => ep.route.route.parent ?? null,
19
- hasParent: () => ep.getParentAlias() != null,
16
+ segment: () => ep.route.route.path,
20
17
 
21
- resolve: async <M extends CommonEntrypoint>() => {
22
- if (ep.ctx == null) {
23
- throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`)
24
- }
18
+ path: () => resolvePath(ep.assertCtx(), ep.route.route),
25
19
 
26
- await ep.route.resolve(ep.ctx)
20
+ mount: () => resolveMount(ep.assertCtx(), ep.route.route),
27
21
 
28
- return ep as M
29
- },
22
+ service: () => resolveService(ep.assertCtx(), ep.route.route),
30
23
 
31
- getParent: () => {
32
- const parentAlias = ep.getParentAlias()
33
- if (parentAlias == null) {
34
- throw new SyntaxError(`Entrypoint has no parent - ${ep.getAlias()}`)
35
- }
36
- if (ep.ctx == null) {
37
- throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`)
38
- }
24
+ address: () => resolveAddress(ep.assertCtx(), ep.route.route),
39
25
 
40
- return ep.ctx.entrypoint(parentAlias)
41
- },
26
+ isLocal: () => isLocalRoute(ep.assertCtx(), ep.route.route),
42
27
 
43
- setService: service => {
44
- if (ep.route.route.resolved) {
45
- throw new SyntaxError(`Cannot update a resolved entrypoint - ${ep.getAlias()}`)
46
- }
47
- ep.route.route.service = service
48
- },
28
+ parent: () => ep.route.route.parent == null ? null
29
+ : ep.assertCtx().entrypoint<CommonEntrypoint>(ep.route.route.parent),
49
30
 
31
+ // Walked afresh on every call: a guard attached to an ancestor after this entrypoint was first
32
+ // asked still has to count.
50
33
  getGuards: () => {
51
- if (guards != null) {
52
- return guards
53
- }
54
- guards = ep.guards ?? []
55
-
56
- if (ep.hasParent()) {
57
- guards.push(
58
- ...ep.getParent().getGuards().filter(guard => !guards?.includes(guard))
59
- )
34
+ const guards = [...ep.guards ?? []]
35
+ const parent = ep.parent()
36
+ if (parent != null) {
37
+ guards.push(...parent.getGuards().filter(guard => !guards.includes(guard)))
60
38
  }
61
39
 
62
40
  return guards
63
41
  },
64
42
 
65
43
  getGates: () => {
66
- if (gates != null) {
67
- return gates
68
- }
69
-
70
- gates = ep.gate != null ? [[
44
+ const gates: [string, string[]][] = ep.gate != null ? [[
71
45
  ep.gate, ep.gateParams == null
72
46
  ? [] : Array.isArray(ep.gateParams)
73
47
  ? ep.gateParams : [ep.gateParams]
74
48
  ]] : []
75
49
 
76
- if (ep.hasParent()) {
77
- gates.push(
78
- ...ep.getParent().getGates()
79
- .filter(([gate]) => !gates?.some(([g]) => g === gate))
80
- )
50
+ const parent = ep.parent()
51
+ if (parent != null) {
52
+ gates.push(...parent.getGates().filter(([gate]) => !gates.some(([g]) => g === gate)))
81
53
  }
82
54
 
83
55
  return gates
@@ -88,19 +60,3 @@ export const entrypoint: CreateEntrypointSignature<CommonEntrypoint> = (route, o
88
60
 
89
61
  return ep
90
62
  }
91
-
92
- export const parent = <T extends CommonEntrypoint | CommonEntrypoint[]>(ep: T, aliasOrParent: string, _parent?: string): T => {
93
- if (Array.isArray(ep)) {
94
- if (_parent == null) {
95
- throw SyntaxError('Elevating parent requires parent name to be specified')
96
- }
97
- ep = ep.find(e => e.route.route.alias === aliasOrParent) as T
98
- if (ep == null) {
99
- throw SyntaxError(`Entrypoint not found ${aliasOrParent}`)
100
- }
101
- return parent(ep, _parent)
102
- }
103
- ep.route.route.parent = aliasOrParent
104
-
105
- return ep
106
- }
package/src/helper.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { route } from '@owlmeans/route'
2
- import { Filter, CommonEntrypointOptions, AbstractResponse, CommonEntrypoint } from './types.js'
3
- import { entrypoint } from './entrypoint.js'
1
+ import { Filter, CommonEntrypointOptions, AbstractResponse } from './types.js'
4
2
 
5
3
  export const filter = (filter: Filter, opts?: CommonEntrypointOptions): CommonEntrypointOptions => ({ filter, ...opts })
6
4
 
@@ -26,12 +24,3 @@ export const provideResponse = <T>(originalResponse?: unknown): AbstractResponse
26
24
 
27
25
  return handler
28
26
  }
29
-
30
- export const clone = <M extends CommonEntrypoint>(entrypoints: M[], from: string, to: string, service: string) => {
31
- const source = entrypoints.find(e => e.alias === from)
32
-
33
- if (source?.route.route != null) {
34
- const _route = { ...source.route.route, service, resolved: false, alias: to }
35
- entrypoints.push(entrypoint(route(to, _route.path, _route)) as M)
36
- }
37
- }
package/src/types.ts CHANGED
@@ -1,29 +1,44 @@
1
- import type { CommonRouteModel } from '@owlmeans/route'
1
+ import type { ResolvedServiceRoute, RouteAddress, RouteModel, RouteProtocols } from '@owlmeans/route'
2
2
  import type { InitializedService, LazyService, BasicEntrypoint } from '@owlmeans/context'
3
3
  import type { AnySchemaObject } from 'ajv'
4
4
  import type { EntrypointOutcome } from './consts.js'
5
5
  import type { Auth } from '@owlmeans/auth'
6
6
 
7
+ /**
8
+ * A URL unit: an immutable route declaration plus what guards, gates and schemas it answers under.
9
+ *
10
+ * Nothing here is rewritten once declared. Every address question — segment, path, mount, service,
11
+ * host — is a question about the declaration asked against the context the entrypoint is registered
12
+ * in, so the same declaration answers differently in a client and in a server without being touched.
13
+ */
7
14
  export interface CommonEntrypoint extends BasicEntrypoint {
8
- route: CommonRouteModel
15
+ route: RouteModel
9
16
  /**
10
17
  * @property {boolean} - if true — router attaches this entrypoint unconditionally
11
18
  * @default false
12
19
  */
13
20
  sticky: boolean
14
- filter?: Filter
21
+ /** The guards declared on this entrypoint alone — see `getGuards()` for the inherited set. */
15
22
  guards?: string[]
16
23
  gate?: string
17
24
  gateParams?: string | string[]
25
+ filter?: Filter
18
26
  handle?: EntrypointHandler
19
- getAlias: () => string
20
- getPath: () => string
21
- getParentAlias: () => string | null
22
- hasParent: () => boolean
23
- resolve: <M extends CommonEntrypoint>() => Promise<M>
24
- getParent: <M extends CommonEntrypoint>() => M
25
- setService: (service: string) => void
27
+
28
+ /** The segment this entrypoint contributes under its parent. */
29
+ segment: () => string
30
+ /** Every ancestor's segment, then this one. */
31
+ path: () => string
32
+ /** `base` + `path()` — what a server mounts and a client requests. */
33
+ mount: () => string
34
+ service: () => ResolvedServiceRoute
35
+ address: () => RouteAddress
36
+ /** Does this entrypoint belong to the service its context IS? */
37
+ isLocal: () => boolean
38
+ parent: () => CommonEntrypoint | null
39
+ /** Own guards and every ancestor's, deduped. Recomputed on each call. */
26
40
  getGuards: () => string[]
41
+ /** Own gate and every ancestor's, as `[gate, params]`. Recomputed on each call. */
27
42
  getGates: () => [string, string[]][]
28
43
  }
29
44
 
@@ -124,3 +139,15 @@ export interface Filter {
124
139
  response?: AnySchemaObject
125
140
  headers?: AnySchemaObject
126
141
  }
142
+
143
+ /**
144
+ * How a call to an entrypoint is actually carried.
145
+ *
146
+ * The transport is chosen by the route's protocol, so a consumer always writes `ep.call(...)` and
147
+ * never learns whether that became an HTTP request, a socket message or a queued job. An
148
+ * application binds a protocol by registering a transport service under `transportAlias(protocol)`.
149
+ */
150
+ export interface EntrypointTransport extends InitializedService {
151
+ readonly protocol: RouteProtocols
152
+ handle: EntrypointHandler
153
+ }
@@ -1,4 +1,4 @@
1
1
  import { CommonEntrypoint } from '../types.js'
2
2
 
3
3
  export const isEntrypoint = (obj: object): obj is CommonEntrypoint =>
4
- '_entrypoint' in obj || '_module' in obj
4
+ '_entrypoint' in obj
@@ -1,6 +1,6 @@
1
- import { CommonRouteModel } from '@owlmeans/route'
1
+ import { RouteModel } from '@owlmeans/route'
2
2
  import { CommonEntrypointOptions } from '../types.js'
3
3
 
4
4
  export interface CreateEntrypointSignature<M> {
5
- (route: CommonRouteModel, opts?: CommonEntrypointOptions): M,
5
+ (route: RouteModel, opts?: CommonEntrypointOptions): M,
6
6
  }