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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +272 -60
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/entrypoint/SKILL.md +84 -48
  4. package/build/consts.d.ts +5 -0
  5. package/build/consts.d.ts.map +1 -1
  6. package/build/consts.js +5 -0
  7. package/build/consts.js.map +1 -1
  8. package/build/entrypoint.d.ts +0 -1
  9. package/build/entrypoint.d.ts.map +1 -1
  10. package/build/entrypoint.js +31 -57
  11. package/build/entrypoint.js.map +1 -1
  12. package/build/helper.d.ts +1 -2
  13. package/build/helper.d.ts.map +1 -1
  14. package/build/helper.js +0 -9
  15. package/build/helper.js.map +1 -1
  16. package/build/index.d.ts +3 -3
  17. package/build/index.d.ts.map +1 -1
  18. package/build/index.js +3 -3
  19. package/build/index.js.map +1 -1
  20. package/build/materialize.d.ts +12 -0
  21. package/build/materialize.d.ts.map +1 -0
  22. package/build/materialize.js +34 -0
  23. package/build/materialize.js.map +1 -0
  24. package/build/protocol.d.ts +231 -0
  25. package/build/protocol.d.ts.map +1 -0
  26. package/build/protocol.js +124 -0
  27. package/build/protocol.js.map +1 -0
  28. package/build/types.d.ts +60 -10
  29. package/build/types.d.ts.map +1 -1
  30. package/build/utils/entrypoint.d.ts.map +1 -1
  31. package/build/utils/entrypoint.js +1 -1
  32. package/build/utils/entrypoint.js.map +1 -1
  33. package/build/utils/types.d.ts +2 -2
  34. package/build/utils/types.d.ts.map +1 -1
  35. package/package.json +4 -4
  36. package/src/consts.ts +6 -0
  37. package/src/entrypoint.ts +33 -65
  38. package/src/helper.ts +1 -12
  39. package/src/index.ts +3 -3
  40. package/src/materialize.ts +49 -0
  41. package/src/protocol.ts +402 -0
  42. package/src/types.ts +63 -10
  43. package/src/utils/entrypoint.ts +1 -1
  44. package/src/utils/types.ts +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
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,QAAS,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.2",
3
+ "version": "0.1.18-rc.21",
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.2",
32
- "@owlmeans/context": "^0.1.18-rc.2",
33
- "@owlmeans/route": "^0.1.18-rc.2",
31
+ "@owlmeans/auth": "^0.1.18-rc.19",
32
+ "@owlmeans/context": "^0.1.18-rc.18",
33
+ "@owlmeans/route": "^0.1.18-rc.19",
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,67 @@
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
 
43
+ /**
44
+ * The gates standing over this entrypoint: its own, then an ancestor's for each gate service
45
+ * this entrypoint has not already named.
46
+ *
47
+ * KNOWN HAZARD, deliberately left alone: the dedup is by gate SERVICE, and two gates under one
48
+ * service are two different questions because their parameters differ — so a child that
49
+ * declares its own gate silently drops its ancestor's, which is the opposite of what
50
+ * "inherited" means. Anything that needs a group rule AND a member rule must therefore not
51
+ * express the group half as a gate under the same service. Changing this would widen every
52
+ * backend and socket entrypoint that today relies on the replacement, so it is a migration
53
+ * rather than a fix.
54
+ */
65
55
  getGates: () => {
66
- if (gates != null) {
67
- return gates
68
- }
69
-
70
- gates = ep.gate != null ? [[
56
+ const gates: [string, string[]][] = ep.gate != null ? [[
71
57
  ep.gate, ep.gateParams == null
72
58
  ? [] : Array.isArray(ep.gateParams)
73
59
  ? ep.gateParams : [ep.gateParams]
74
60
  ]] : []
75
61
 
76
- if (ep.hasParent()) {
77
- gates.push(
78
- ...ep.getParent().getGates()
79
- .filter(([gate]) => !gates?.some(([g]) => g === gate))
80
- )
62
+ const parent = ep.parent()
63
+ if (parent != null) {
64
+ gates.push(...parent.getGates().filter(([gate]) => !gates.some(([g]) => g === gate)))
81
65
  }
82
66
 
83
67
  return gates
@@ -88,19 +72,3 @@ export const entrypoint: CreateEntrypointSignature<CommonEntrypoint> = (route, o
88
72
 
89
73
  return ep
90
74
  }
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/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  export type * from './types.js'
3
- export * from './entrypoint.js'
4
- export * from './filter.js'
5
- export * from './helper.js'
6
3
  export * from './consts.js'
4
+ export * from './protocol.js'
5
+ export * from './materialize.js'
6
+ export { provideResponse } from './helper.js'
@@ -0,0 +1,49 @@
1
+ import { entrypoint } from './entrypoint.js'
2
+ import type { CommonEntrypoint, CommonEntrypointOptions, Filter } from './types.js'
3
+ import type { EntrypointProtocolDeclaration } from './protocol.js'
4
+
5
+ /** A context-bound entrypoint made from an immutable protocol declaration. */
6
+ export type MaterializedEntrypoint<Protocol extends EntrypointProtocolDeclaration> = CommonEntrypoint & {
7
+ readonly protocol: Protocol
8
+ }
9
+
10
+ const filterOf = (protocol: EntrypointProtocolDeclaration): Filter | undefined => {
11
+ const request = protocol.contract?.requestSchemas
12
+ const response = protocol.contract?.responseSchemas
13
+
14
+ if (request == null && response == null) return undefined
15
+
16
+ return {
17
+ body: request?.body == null ? undefined : structuredClone(request.body),
18
+ params: request?.params == null ? undefined : structuredClone(request.params),
19
+ query: request?.query == null ? undefined : structuredClone(request.query),
20
+ headers: request?.headers == null ? undefined : structuredClone(request.headers),
21
+ // Fastify requires response serializers to be keyed by a status code. A protocol's
22
+ // ordinary response has no explicit outcome, so it is the normal successful 200 reply.
23
+ response: response == null ? undefined : {
24
+ ...(response.default == null ? {} : { 200: structuredClone(response.default) }),
25
+ ...Object.fromEntries(Object.entries(response.byStatus ?? {}).map(([status, schema]) => [
26
+ status, structuredClone(schema),
27
+ ])),
28
+ },
29
+ }
30
+ }
31
+
32
+ const optionsOf = (protocol: EntrypointProtocolDeclaration): CommonEntrypointOptions => ({
33
+ sticky: protocol.sticky,
34
+ guards: [...protocol.guards],
35
+ gate: protocol.gate?.alias,
36
+ gateParams: protocol.gate == null ? undefined : [...protocol.gate.params],
37
+ filter: filterOf(protocol),
38
+ })
39
+
40
+ /**
41
+ * Make a local, mutable registration from a shared declaration. The protocol is never mutated;
42
+ * guards, route resolution and handlers belong exclusively to this materialized entrypoint.
43
+ */
44
+ export const materializeEntrypoint = <Protocol extends EntrypointProtocolDeclaration>(
45
+ protocol: Protocol,
46
+ ): MaterializedEntrypoint<Protocol> => Object.assign(
47
+ entrypoint({ route: { ...protocol.route.route } }, optionsOf(protocol)),
48
+ { protocol },
49
+ )