@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,402 @@
1
+ import type { Auth } from '@owlmeans/auth'
2
+ import type { BasicEntrypoint, EntrypointReference } from '@owlmeans/context'
3
+ import type { JSONSchemaType, AnySchemaObject } from 'ajv'
4
+ import type { RouteModel } from '@owlmeans/route'
5
+ import type { EntrypointOutcome } from './consts.js'
6
+ import type { ResolvedEntity } from './types.js'
7
+ import type { AbstractRequest } from './types.js'
8
+
9
+ /** A deliberately broad value used only by declarations without an I/O contract. */
10
+ export type OpenValue = object | string | number | boolean | bigint | null | undefined
11
+
12
+ /** The request accepted by a declaration that intentionally supplies no contract. */
13
+ export interface OpenRequest {
14
+ body?: object
15
+ params?: object
16
+ query?: object
17
+ headers?: object
18
+ }
19
+
20
+ /** The four independent request sections an entrypoint may declare. */
21
+ export interface RequestShape {
22
+ body?: OpenValue
23
+ params?: object
24
+ query?: object
25
+ headers?: object
26
+ }
27
+
28
+ /** Addressing and transport controls are never part of an entrypoint's payload contract. */
29
+ export interface CallOptions {
30
+ auth?: Auth
31
+ host?: string
32
+ base?: string | boolean
33
+ unsecure?: boolean
34
+ timeout?: number
35
+ signal?: AbortSignal
36
+ }
37
+
38
+ interface TypeToken {
39
+ readonly kind: 'entrypoint-type'
40
+ readonly schema?: AnySchemaObject
41
+ }
42
+
43
+ /** A type-only contract source, optionally paired with an AJV schema. */
44
+ export type Typed<T> = TypeToken & { readonly value?: T }
45
+
46
+ declare const entrypointSchemaType: unique symbol
47
+
48
+ /**
49
+ * A JSON schema carrying the model type it validates. Use `schema<Model>(...)` once beside the
50
+ * model; every protocol that consumes it then infers the model without another generic.
51
+ */
52
+ export type EntrypointSchema<T> = JSONSchemaType<T> & {
53
+ readonly [entrypointSchemaType]: T
54
+ }
55
+
56
+ export const schema = <T>(value: JSONSchemaType<T>): EntrypointSchema<T> =>
57
+ value as EntrypointSchema<T>
58
+
59
+ /** A schema or an explicit type-only source for one request/response value. */
60
+ export type ShapeSource<T> = EntrypointSchema<T> | JSONSchemaType<T> | Typed<T>
61
+
62
+ type AnyShapeSource = AnySchemaObject | TypeToken
63
+
64
+ /**
65
+ * Supplies type information where a response has no runtime schema, or attaches a type to an
66
+ * otherwise untyped schema literal at the declaration boundary.
67
+ */
68
+ export function typed<T>(): Typed<T>
69
+ export function typed<T>(schema: JSONSchemaType<T>): Typed<T>
70
+ export function typed<T>(schema?: JSONSchemaType<T>): Typed<T> {
71
+ return schema == null
72
+ ? { kind: 'entrypoint-type' }
73
+ : { kind: 'entrypoint-type', schema }
74
+ }
75
+
76
+ export interface RequestSources {
77
+ body?: AnyShapeSource
78
+ params?: AnyShapeSource
79
+ query?: AnyShapeSource
80
+ headers?: AnyShapeSource
81
+ }
82
+
83
+ export interface RuntimeRequestSchemas {
84
+ body?: AnySchemaObject
85
+ params?: AnySchemaObject
86
+ query?: AnySchemaObject
87
+ headers?: AnySchemaObject
88
+ }
89
+
90
+ export interface RuntimeResponseSchemas {
91
+ default?: AnySchemaObject
92
+ byStatus?: Readonly<Record<number, AnySchemaObject>>
93
+ }
94
+
95
+ /** The runtime schemas and compile-time request/response pair attached to one protocol. */
96
+ export interface EntrypointContract<Request extends RequestShape, Response> {
97
+ readonly kind: 'entrypoint-contract'
98
+ readonly requestSchemas: RuntimeRequestSchemas
99
+ readonly responseSchemas?: RuntimeResponseSchemas
100
+ readonly requestType?: Request
101
+ readonly responseType?: Response
102
+ }
103
+
104
+ /** Runtime fields common to every protocol, regardless of its compile-time request/reply pair. */
105
+ export interface EntrypointProtocolDeclaration {
106
+ readonly kind: 'entrypoint-protocol'
107
+ readonly alias: string
108
+ readonly route: RouteModel
109
+ readonly contract?: Pick<EntrypointContract<RequestShape, OpenValue>,
110
+ 'kind' | 'requestSchemas' | 'responseSchemas'>
111
+ readonly sticky: boolean
112
+ readonly guards: readonly string[]
113
+ readonly gate?: {
114
+ readonly alias: string
115
+ readonly params: readonly string[]
116
+ }
117
+ }
118
+
119
+ /** An access gate declared by a protocol, including inherited parent declarations. */
120
+ export interface EntrypointGate {
121
+ readonly alias: string
122
+ readonly params: readonly string[]
123
+ }
124
+
125
+ type SourceValue<Source> =
126
+ Source extends Typed<infer Value> ? Value
127
+ : Source extends EntrypointSchema<infer Value> ? Value
128
+ : Source extends JSONSchemaType<infer Value>
129
+ ? Value extends OpenValue ? Value : OpenValue
130
+ : OpenValue
131
+
132
+ type RequestFromSources<Sources extends RequestSources> =
133
+ (Sources extends { body: infer Source } ? { body: SourceValue<Source> } : {})
134
+ & (Sources extends { params: infer Source } ? { params: SourceValue<Source> } : {})
135
+ & (Sources extends { query: infer Source } ? { query: SourceValue<Source> } : {})
136
+ & (Sources extends { headers: infer Source } ? { headers: SourceValue<Source> } : {})
137
+
138
+ const schemaOf = (source: AnyShapeSource | undefined): AnySchemaObject | undefined => {
139
+ if (source == null) return undefined
140
+ const schema = 'kind' in source && source.kind === 'entrypoint-type'
141
+ ? source.schema
142
+ : source
143
+
144
+ return schema == null ? undefined : structuredClone(schema)
145
+ }
146
+
147
+ const responseSchemasOf = (source: AnyShapeSource | undefined): RuntimeResponseSchemas | undefined => {
148
+ const schema = schemaOf(source)
149
+ return schema == null ? undefined : { default: schema }
150
+ }
151
+
152
+ /**
153
+ * Declare an exact request and response. The primary overload means a body request; use
154
+ * `contract.request` for independently-shaped request sections.
155
+ */
156
+ export function contract(): EntrypointContract<{}, undefined>
157
+ export function contract<Response>(response: ShapeSource<Response>): EntrypointContract<{}, Response>
158
+ export function contract<Body extends OpenValue, Response>(
159
+ body: ShapeSource<Body>, response: ShapeSource<Response>
160
+ ): EntrypointContract<{ body: Body }, Response>
161
+ export function contract(
162
+ first?: AnyShapeSource, second?: AnyShapeSource
163
+ ): EntrypointContract<RequestShape, OpenValue> {
164
+ const body = second == null ? undefined : first
165
+ const response = second ?? first
166
+
167
+ return {
168
+ kind: 'entrypoint-contract',
169
+ requestSchemas: { body: schemaOf(body) },
170
+ responseSchemas: responseSchemasOf(response),
171
+ }
172
+ }
173
+
174
+ export namespace contract {
175
+ export function request<Sources extends RequestSources, Response>(
176
+ request: Sources,
177
+ response: ShapeSource<Response>
178
+ ): EntrypointContract<RequestFromSources<Sources>, Response> {
179
+ return {
180
+ kind: 'entrypoint-contract',
181
+ requestSchemas: {
182
+ body: schemaOf(request.body),
183
+ params: schemaOf(request.params),
184
+ query: schemaOf(request.query),
185
+ headers: schemaOf(request.headers),
186
+ },
187
+ responseSchemas: responseSchemasOf(response),
188
+ }
189
+ }
190
+ }
191
+
192
+ export interface EntrypointOptions {
193
+ sticky?: boolean
194
+ guards?: string | readonly string[]
195
+ gate?: {
196
+ alias: string
197
+ params?: string | readonly string[]
198
+ }
199
+ }
200
+
201
+ export interface EntrypointResult<Response> {
202
+ value: Response
203
+ outcome: EntrypointOutcome
204
+ }
205
+
206
+ export type CallArguments<Request extends RequestShape> = {} extends Request
207
+ ? [request?: Request & CallOptions]
208
+ : [request: Request & CallOptions]
209
+
210
+ type UrlRequest<Request extends RequestShape> =
211
+ (Request extends { params: infer Params } ? { params: Params }
212
+ : Request extends { params?: infer Params } ? { params?: Params } : {})
213
+ & (Request extends { query: infer Query } ? { query: Query }
214
+ : Request extends { query?: infer Query } ? { query?: Query } : {})
215
+
216
+ export type UrlArguments<Request extends RequestShape> = {} extends UrlRequest<Request>
217
+ ? [request?: UrlRequest<Request> & CallOptions]
218
+ : [request: UrlRequest<Request> & CallOptions]
219
+
220
+ export interface EntrypointRequestMeta {
221
+ alias: string
222
+ auth?: Auth
223
+ entity?: ResolvedEntity
224
+ path: string
225
+ canceled?: boolean
226
+ cancel?: () => void
227
+ }
228
+
229
+ /**
230
+ * A protocol request at an implementation boundary.
231
+ *
232
+ * Transport metadata and empty request sections remain available to handlers; a declared section
233
+ * then refines that base shape to its protocol contract.
234
+ */
235
+ export type HandlerRequest<Request extends RequestShape> = AbstractRequest & Request & EntrypointRequestMeta
236
+
237
+ /** The context-bound counterpart of an immutable protocol declaration. */
238
+ export interface RegisteredEntrypoint<Request extends RequestShape, Response> extends BasicEntrypoint {
239
+ readonly protocol: EntrypointProtocol<Request, Response>
240
+ call: (...args: CallArguments<Request>) => Promise<Response>
241
+ invoke: (...args: CallArguments<Request>) => Promise<EntrypointResult<Response>>
242
+ url: (...args: UrlArguments<Request>) => Promise<string>
243
+ validate: (...args: CallArguments<Request>) => Promise<boolean>
244
+ }
245
+
246
+ /**
247
+ * An immutable shared declaration. Its inherited reference type is what gives a context lookup
248
+ * the exact registered entrypoint type without a consumer-supplied generic.
249
+ */
250
+ export interface EntrypointProtocol<
251
+ Request extends RequestShape = RequestShape,
252
+ Response = OpenValue,
253
+ > extends EntrypointProtocolDeclaration, EntrypointReference<RegisteredEntrypoint<Request, Response>> {
254
+ readonly contract?: EntrypointContract<Request, Response>
255
+ }
256
+
257
+ export type RequestOf<Protocol extends EntrypointProtocolDeclaration> = Protocol extends EntrypointProtocol<infer Request, infer _Response>
258
+ ? Request
259
+ : OpenRequest
260
+
261
+ export type ResponseOf<Protocol extends EntrypointProtocolDeclaration> = Protocol extends EntrypointProtocol<infer _Request, infer Response>
262
+ ? Response
263
+ : OpenValue
264
+
265
+ export type BodyOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { body: infer Body }
266
+ ? Body
267
+ : OpenValue
268
+
269
+ export type ParamsOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { params: infer Params }
270
+ ? Params
271
+ : object
272
+
273
+ export type QueryOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { query: infer Query }
274
+ ? Query
275
+ : object
276
+
277
+ export type HeadersOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { headers: infer Headers }
278
+ ? Headers
279
+ : object
280
+
281
+ export type CallRequestOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> & CallOptions
282
+
283
+ const guardsOf = (guards: EntrypointOptions['guards']): readonly string[] => guards == null
284
+ ? []
285
+ : typeof guards === 'string' ? [guards] : [...guards]
286
+
287
+ const gateOf = (gate: EntrypointOptions['gate']): EntrypointProtocol['gate'] => gate == null
288
+ ? undefined
289
+ : {
290
+ alias: gate.alias,
291
+ params: gate.params == null ? [] : typeof gate.params === 'string' ? [gate.params] : [...gate.params],
292
+ }
293
+
294
+ /** Create an immutable protocol declaration from a route and its contract. */
295
+ export const protocol = <Request extends RequestShape, Response>(
296
+ route: RouteModel,
297
+ entrypointContract: EntrypointContract<Request, Response>,
298
+ options?: EntrypointOptions
299
+ ): EntrypointProtocol<Request, Response> => Object.freeze({
300
+ kind: 'entrypoint-protocol' as const,
301
+ alias: route.route.alias,
302
+ route: Object.freeze({ route: Object.freeze({ ...route.route }) }),
303
+ contract: entrypointContract,
304
+ sticky: options?.sticky ?? false,
305
+ guards: Object.freeze(guardsOf(options?.guards)),
306
+ gate: gateOf(options?.gate),
307
+ })
308
+
309
+ export const openProtocol = (
310
+ route: RouteModel,
311
+ options?: EntrypointOptions
312
+ ): EntrypointProtocol<OpenRequest, OpenValue> => Object.freeze({
313
+ kind: 'entrypoint-protocol' as const,
314
+ alias: route.route.alias,
315
+ route: Object.freeze({ route: Object.freeze({ ...route.route }) }),
316
+ sticky: options?.sticky ?? false,
317
+ guards: Object.freeze(guardsOf(options?.guards)),
318
+ gate: gateOf(options?.gate),
319
+ })
320
+
321
+ export const entrypointRef = <Request extends RequestShape = OpenRequest, Response = OpenValue>(
322
+ alias: string
323
+ ): EntrypointReference<RegisteredEntrypoint<Request, Response>> => ({ alias })
324
+
325
+ export const aliasOf = (reference: EntrypointReference | string): string =>
326
+ typeof reference === 'string' ? reference : reference.alias
327
+
328
+ export const isEntrypointProtocol = (value: object): value is EntrypointProtocolDeclaration =>
329
+ 'kind' in value && value.kind === 'entrypoint-protocol'
330
+
331
+ export interface EntrypointTree {
332
+ readonly [key: string]: EntrypointProtocolDeclaration | EntrypointTree
333
+ }
334
+
335
+ /** Flatten an exported protocol tree for a layer-specific materializer. */
336
+ export const protocols = (tree: EntrypointTree): EntrypointProtocolDeclaration[] => {
337
+ const result: EntrypointProtocolDeclaration[] = []
338
+
339
+ const visit = (node: EntrypointTree): void => {
340
+ Object.values(node).forEach((entry) => {
341
+ if (isEntrypointProtocol(entry)) {
342
+ result.push(entry)
343
+ } else {
344
+ visit(entry)
345
+ }
346
+ })
347
+ }
348
+
349
+ visit(tree)
350
+ return result
351
+ }
352
+
353
+ /**
354
+ * Rebuild an immutable protocol tree while transforming its declarations.
355
+ *
356
+ * Protocol consumers keep addressing declarations by their exported tree path; a cross-cutting
357
+ * concern such as a coguard therefore never needs to flatten the tree and recover declarations
358
+ * by alias.
359
+ */
360
+ export const mapProtocols = <Tree extends EntrypointTree>(
361
+ tree: Tree,
362
+ mapper: (protocol: EntrypointProtocolDeclaration) => EntrypointProtocolDeclaration,
363
+ ): Tree => Object.freeze(Object.fromEntries(
364
+ Object.entries(tree).map(([key, entry]) => [
365
+ key,
366
+ isEntrypointProtocol(entry) ? mapper(entry) : mapProtocols(entry, mapper),
367
+ ])
368
+ )) as Tree
369
+
370
+ /** Resolve the gates a protocol inherits through its route parents without materializing it. */
371
+ export const gatesOf = (
372
+ protocol: EntrypointProtocolDeclaration,
373
+ tree: EntrypointTree,
374
+ ): readonly EntrypointGate[] => {
375
+ const byAlias = new Map(protocols(tree).map(candidate => [candidate.alias, candidate]))
376
+ const result: EntrypointGate[] = []
377
+ const visited = new Set<string>()
378
+ let current: EntrypointProtocolDeclaration | undefined = protocol
379
+
380
+ while (current != null && !visited.has(current.alias)) {
381
+ visited.add(current.alias)
382
+ if (current.gate != null && !result.some(gate => gate.alias === current!.gate!.alias)) {
383
+ result.push(current.gate)
384
+ }
385
+ current = current.route.route.parent == null
386
+ ? undefined
387
+ : byAlias.get(current.route.route.parent)
388
+ }
389
+
390
+ return result
391
+ }
392
+
393
+ /** Clone an immutable protocol while preserving its request/response pair. */
394
+ export const decorateEntrypoint = <Protocol extends EntrypointProtocolDeclaration>(
395
+ protocol: Protocol,
396
+ options: EntrypointOptions
397
+ ): Protocol => Object.freeze({
398
+ ...protocol,
399
+ sticky: options.sticky ?? protocol.sticky,
400
+ guards: options.guards == null ? protocol.guards : guardsOf(options.guards),
401
+ gate: options.gate == null ? protocol.gate : gateOf(options.gate),
402
+ })
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
  }