@owlmeans/entrypoint 0.1.18-rc.0 → 0.1.18-rc.10

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.0",
5
- "generatedAt": "2026-08-16T22:20:50.515Z",
4
+ "version": "0.1.18-rc.10",
5
+ "generatedAt": "2026-09-01T17:39:40.768Z",
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,27 +8,121 @@ user-invocable: false
8
8
  # @owlmeans/entrypoint
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/entrypoint": "^0.1.18-rc.0"` in `dependencies`
11
+ **Install:** `"@owlmeans/entrypoint": "^0.1.18-rc.10"` 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(...builders)` | Compose an entrypoint declaration from builders |
18
- | `guard(alias, ...gates)` | Attach a security guard |
19
- | `gate(alias, scopes[])` | Define an auth gate (used inside a guard) |
20
- | `filter(...validators)` | 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(...)` |
21
+ | `entrypoint(route, opts?)` | Declare an entrypoint on a route model |
22
+ | `guard(alias, opts?)` | Require a guard; returns options, so it wraps rather than takes them |
23
+ | `gate(alias, params, opts?)` | Require a gate; passed as the `opts` of `guard(...)` |
24
+ | `filter(filter, opts?)` | Attach request validators |
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>`) |
33
+
34
+ `guard`, `gate` and `filter` are **options-object combinators, not variadic composers**. Each
35
+ returns a `CommonEntrypointOptions` and takes the next one as its final argument, so they nest:
36
+
37
+ ```typescript
38
+ entrypoint(
39
+ route(app.api.item.remove, '/:id', { parent: app.api.item, method: RouteMethod.DELETE }),
40
+ guard(DEFAULT_GUARD, gate(OIDC_GATE, ['item--delete@id']))
41
+ )
42
+ ```
43
+
44
+ Guards and gates are **inherited by child entrypoints** and enforced by the framework before a
45
+ handler runs — a handler that re-checks them is duplicating an enforced rule, and is wrong even
46
+ when it agrees.
27
47
 
28
48
  ## Subpath Exports
29
49
 
30
50
  - `./utils` — entrypoint construction helpers (`isEntrypoint`, `CreateEntrypointSignature`)
31
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
+
121
+ `@owlmeans/queue` is the worked example: `appendQueueTransport(context)` binds
122
+ `RouteProtocols.QUEUE`, and a declaration built with `job()` instead of `backend()` is then carried
123
+ as a broker job. Nothing at the call site changes — which is the point of putting the protocol on
124
+ the route rather than at the call.
125
+
32
126
  ## Usage
33
127
 
34
128
  Define entrypoints in a shared `common` package, then `elevate()` them with handlers in server/web packages:
@@ -40,7 +134,7 @@ import { DEFAULT_GUARD } from '@owlmeans/auth-common'
40
134
  import { OIDC_GATE } from '@owlmeans/oidc'
41
135
  import { CreateProjectSchema } from './schemas.js'
42
136
 
43
- export const managerModules = [
137
+ export const managerEntrypoints = [
44
138
  entrypoint(
45
139
  route(manager.back.account.base, '/account'),
46
140
  guard(DEFAULT_GUARD, gate(OIDC_GATE, [`my-service-account-{entity}`]))
@@ -57,6 +151,6 @@ export const managerModules = [
57
151
 
58
152
  ## Depends On
59
153
 
60
- - `@owlmeans/route` — `route()`, `RouteMethod`
154
+ - `@owlmeans/route` — `route()`, `RouteMethod`, `RouteProtocols`, and the address helpers under `/utils`
61
155
  - `@owlmeans/auth-common` — guard aliases (`DEFAULT_GUARD`)
62
156
  - `@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":"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"}
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EACL,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EACxE,MAAM,uBAAuB,CAAA;AAG9B,MAAM,CAAC,MAAM,UAAU,GAAgD,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrF,MAAM,EAAE,GAAqB,gBAAgB,CAAmB,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE;QACjF,WAAW,EAAE,IAAI;QAEjB,MAAM,EAAE,KAAK;QAEb,KAAK;QAEL,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;QAElC,IAAI,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAEvD,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAEzD,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAE7D,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAE7D,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAE3D,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;YAChD,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,UAAU,CAAmB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAEtE,+FAA+F;QAC/F,4BAA4B;QAC5B,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;YACnC,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,CAAA;YAC1B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC7E,CAAC;YAED,OAAO,MAAM,CAAA;QACf,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,KAAK,GAAyB,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;oBACrD,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,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,CAAA;YAC1B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAA;YACvF,CAAC;YAED,OAAO,KAAK,CAAA;QACd,CAAC;QAED,GAAG,IAAI;KACR,CAAC,CAAA;IAEF,OAAO,EAAE,CAAA;AACX,CAAC,CAAA"}
@@ -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> {
@@ -39,6 +53,17 @@ export interface EntrypointAssert {
39
53
  export interface AbstractRequest<T extends {} = {}> {
40
54
  alias: string;
41
55
  auth?: Auth;
56
+ /**
57
+ * The organization entity this request acts for, resolved from `auth.entitySlug` once, at the
58
+ * server boundary.
59
+ *
60
+ * The slug on the token is renameable and therefore unusable as a key; `entity.id` is the stable
61
+ * value that records, grants and minted infrastructure names are keyed by. Resolving it here —
62
+ * rather than in each handler — is what keeps a rename from meaning a sweep of every call site,
63
+ * and it is absent whenever no resolver is registered (an implementation that has no notion of
64
+ * an organization store), so consumers must handle that rather than assume it.
65
+ */
66
+ entity?: ResolvedEntity;
42
67
  params: Record<string, string | number | undefined | null> | Partial<T>;
43
68
  body?: Record<string, any> | Partial<T>;
44
69
  headers: Record<string, string[] | string | undefined>;
@@ -53,6 +78,20 @@ export interface AbstractRequest<T extends {} = {}> {
53
78
  timeout?: number;
54
79
  signal?: AbortSignal;
55
80
  }
81
+ /**
82
+ * An organization entity as request handlers see it: the stable id to key by, the current slug to
83
+ * compose user-facing names from, and the frozen key that external systems already know it under.
84
+ */
85
+ export interface ResolvedEntity {
86
+ id: string;
87
+ slug: string;
88
+ /**
89
+ * The identifier this organization is known by in systems whose names cannot be rewritten —
90
+ * an IAM realm, an object-storage prefix, a cluster object. Minted once and never recomputed,
91
+ * so it stays valid across every later rename.
92
+ */
93
+ iamKey: string;
94
+ }
56
95
  export interface AbstractResponse<T> {
57
96
  responseProvider?: any;
58
97
  value?: T;
@@ -80,4 +119,15 @@ export interface Filter {
80
119
  response?: AnySchemaObject;
81
120
  headers?: AnySchemaObject;
82
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
+ }
83
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.0",
3
+ "version": "0.1.18-rc.10",
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.0",
32
- "@owlmeans/context": "^0.1.18-rc.0",
33
- "@owlmeans/route": "^0.1.18-rc.0",
31
+ "@owlmeans/auth": "^0.1.18-rc.8",
32
+ "@owlmeans/context": "^0.1.18-rc.7",
33
+ "@owlmeans/route": "^0.1.18-rc.8",
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
 
@@ -47,6 +62,17 @@ export interface EntrypointAssert {
47
62
  export interface AbstractRequest<T extends {} = {}> {
48
63
  alias: string
49
64
  auth?: Auth
65
+ /**
66
+ * The organization entity this request acts for, resolved from `auth.entitySlug` once, at the
67
+ * server boundary.
68
+ *
69
+ * The slug on the token is renameable and therefore unusable as a key; `entity.id` is the stable
70
+ * value that records, grants and minted infrastructure names are keyed by. Resolving it here —
71
+ * rather than in each handler — is what keeps a rename from meaning a sweep of every call site,
72
+ * and it is absent whenever no resolver is registered (an implementation that has no notion of
73
+ * an organization store), so consumers must handle that rather than assume it.
74
+ */
75
+ entity?: ResolvedEntity
50
76
  params: Record<string, string | number | undefined | null> | Partial<T>
51
77
  body?: Record<string, any> | Partial<T>
52
78
  headers: Record<string, string[] | string | undefined>
@@ -66,6 +92,21 @@ export interface AbstractRequest<T extends {} = {}> {
66
92
  signal?: AbortSignal
67
93
  }
68
94
 
95
+ /**
96
+ * An organization entity as request handlers see it: the stable id to key by, the current slug to
97
+ * compose user-facing names from, and the frozen key that external systems already know it under.
98
+ */
99
+ export interface ResolvedEntity {
100
+ id: string
101
+ slug: string
102
+ /**
103
+ * The identifier this organization is known by in systems whose names cannot be rewritten —
104
+ * an IAM realm, an object-storage prefix, a cluster object. Minted once and never recomputed,
105
+ * so it stays valid across every later rename.
106
+ */
107
+ iamKey: string
108
+ }
109
+
69
110
  export interface AbstractResponse<T> {
70
111
  responseProvider?: any
71
112
  value?: T,
@@ -98,3 +139,15 @@ export interface Filter {
98
139
  response?: AnySchemaObject
99
140
  headers?: AnySchemaObject
100
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
  }