@owlmeans/entrypoint 0.1.18-rc.39 → 0.1.18-rc.40

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/src/types.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import type { ResolvedServiceRoute, RouteAddress, RouteModel, RouteProtocol } from '@owlmeans/route'
2
- import type { InitializedService, LazyService, BasicEntrypoint } from '@owlmeans/context'
3
- import type { AnySchemaObject } from 'ajv'
2
+ import type { InitializedService, LazyService, BasicEntrypoint, EntrypointReference } from '@owlmeans/context'
3
+ import type { AnySchemaObject, JSONSchemaType } from 'ajv'
4
4
  import type { EntrypointOutcome } from './consts.js'
5
5
  import type { Auth } from '@owlmeans/auth'
6
6
 
7
+ import type { AnyShapeSource, entrypointSchemaType, SourceValue, TypeToken, UrlRequest } from './types.local.js'
8
+ import type { createFilterHelper } from './filter.js'
9
+
7
10
  /**
8
11
  * A URL unit: an immutable route declaration plus what guards, gates and schemas it answers under.
9
12
  *
@@ -151,3 +154,197 @@ export interface EntrypointTransport extends InitializedService {
151
154
  readonly protocol: RouteProtocol
152
155
  handle: EntrypointHandler
153
156
  }
157
+
158
+ /** A deliberately broad value used only by declarations without an I/O contract. */
159
+ export type OpenValue = object | string | number | boolean | bigint | null | undefined
160
+
161
+ /** The four independent request sections an entrypoint may declare. */
162
+ export interface RequestShape {
163
+ body?: OpenValue
164
+ params?: object
165
+ query?: object
166
+ headers?: object
167
+ }
168
+
169
+ export interface RuntimeRequestSchemas {
170
+ body?: AnySchemaObject
171
+ params?: AnySchemaObject
172
+ query?: AnySchemaObject
173
+ headers?: AnySchemaObject
174
+ }
175
+
176
+ export interface RuntimeResponseSchemas {
177
+ default?: AnySchemaObject
178
+ byStatus?: Readonly<Record<number, AnySchemaObject>>
179
+ }
180
+
181
+ /** The runtime schemas and compile-time request/response pair attached to one protocol. */
182
+ export interface EntrypointContract<Request extends RequestShape, Response> {
183
+ readonly kind: 'entrypoint-contract'
184
+ readonly requestSchemas: RuntimeRequestSchemas
185
+ readonly responseSchemas?: RuntimeResponseSchemas
186
+ readonly requestType?: Request
187
+ readonly responseType?: Response
188
+ }
189
+
190
+ /** Runtime fields common to every protocol, regardless of its compile-time request/reply pair. */
191
+ export interface EntrypointProtocolDeclaration {
192
+ readonly kind: 'entrypoint-protocol'
193
+ readonly alias: string
194
+ readonly route: RouteModel
195
+ readonly contract?: Pick<EntrypointContract<RequestShape, OpenValue>,
196
+ 'kind' | 'requestSchemas' | 'responseSchemas'>
197
+ readonly sticky: boolean
198
+ readonly guards: readonly string[]
199
+ readonly gate?: {
200
+ readonly alias: string
201
+ readonly params: readonly string[]
202
+ }
203
+ }
204
+
205
+ /** A context-bound entrypoint made from an immutable protocol declaration. */
206
+ export type MaterializedEntrypoint<Protocol extends EntrypointProtocolDeclaration> = CommonEntrypoint & {
207
+ readonly protocol: Protocol
208
+ }
209
+
210
+ /** The request accepted by a declaration that intentionally supplies no contract. */
211
+ export interface OpenRequest {
212
+ body?: object
213
+ params?: object
214
+ query?: object
215
+ headers?: object
216
+ }
217
+
218
+ /** Addressing and transport controls are never part of an entrypoint's payload contract. */
219
+ export interface CallOptions {
220
+ auth?: Auth
221
+ host?: string
222
+ base?: string | boolean
223
+ unsecure?: boolean
224
+ timeout?: number
225
+ signal?: AbortSignal
226
+ }
227
+
228
+ /** A type-only contract source, optionally paired with an AJV schema. */
229
+ export type Typed<T> = TypeToken & { readonly value?: T }
230
+
231
+ /**
232
+ * A JSON schema carrying the model type it validates. Use `schema<Model>(...)` once beside the
233
+ * model; every protocol that consumes it then infers the model without another generic.
234
+ */
235
+ export type EntrypointSchema<T> = JSONSchemaType<T> & {
236
+ readonly [entrypointSchemaType]: T
237
+ }
238
+
239
+ /** A schema or an explicit type-only source for one request/response value. */
240
+ export type ShapeSource<T> = EntrypointSchema<T> | JSONSchemaType<T> | Typed<T>
241
+
242
+ export interface RequestSources {
243
+ body?: AnyShapeSource
244
+ params?: AnyShapeSource
245
+ query?: AnyShapeSource
246
+ headers?: AnyShapeSource
247
+ }
248
+
249
+ /** An access gate declared by a protocol, including inherited parent declarations. */
250
+ export interface EntrypointGate {
251
+ readonly alias: string
252
+ readonly params: readonly string[]
253
+ }
254
+
255
+ export type RequestFromSources<Sources extends RequestSources> =
256
+ (Sources extends { body: infer Source } ? { body: SourceValue<Source> } : {})
257
+ & (Sources extends { params: infer Source } ? { params: SourceValue<Source> } : {})
258
+ & (Sources extends { query: infer Source } ? { query: SourceValue<Source> } : {})
259
+ & (Sources extends { headers: infer Source } ? { headers: SourceValue<Source> } : {})
260
+
261
+ export interface EntrypointOptions {
262
+ sticky?: boolean
263
+ guards?: string | readonly string[]
264
+ gate?: {
265
+ alias: string
266
+ params?: string | readonly string[]
267
+ }
268
+ }
269
+
270
+ export interface EntrypointResult<Response> {
271
+ value: Response
272
+ outcome: EntrypointOutcome
273
+ }
274
+
275
+ export type CallArguments<Request extends RequestShape> = {} extends Request
276
+ ? [request?: Request & CallOptions]
277
+ : [request: Request & CallOptions]
278
+
279
+ export type UrlArguments<Request extends RequestShape> = {} extends UrlRequest<Request>
280
+ ? [request?: UrlRequest<Request> & CallOptions]
281
+ : [request: UrlRequest<Request> & CallOptions]
282
+
283
+ export interface EntrypointRequestMeta {
284
+ alias: string
285
+ auth?: Auth
286
+ entity?: ResolvedEntity
287
+ path: string
288
+ canceled?: boolean
289
+ cancel?: () => void
290
+ }
291
+
292
+ /**
293
+ * A protocol request at an implementation boundary.
294
+ *
295
+ * Transport metadata and empty request sections remain available to handlers; a declared section
296
+ * then refines that base shape to its protocol contract.
297
+ */
298
+ export type HandlerRequest<Request extends RequestShape> = AbstractRequest & Request & EntrypointRequestMeta
299
+
300
+ /**
301
+ * An immutable shared declaration. Its inherited reference type is what gives a context lookup
302
+ * the exact registered entrypoint type without a consumer-supplied generic.
303
+ */
304
+ export interface EntrypointProtocol<
305
+ Request extends RequestShape = RequestShape,
306
+ Response = OpenValue,
307
+ > extends EntrypointProtocolDeclaration, EntrypointReference<RegisteredEntrypoint<Request, Response>> {
308
+ readonly contract?: EntrypointContract<Request, Response>
309
+ }
310
+
311
+ /** The context-bound counterpart of an immutable protocol declaration. */
312
+ export interface RegisteredEntrypoint<Request extends RequestShape, Response> extends BasicEntrypoint {
313
+ readonly protocol: EntrypointProtocol<Request, Response>
314
+ call: (...args: CallArguments<Request>) => Promise<Response>
315
+ invoke: (...args: CallArguments<Request>) => Promise<EntrypointResult<Response>>
316
+ url: (...args: UrlArguments<Request>) => Promise<string>
317
+ validate: (...args: CallArguments<Request>) => Promise<boolean>
318
+ }
319
+
320
+ export type RequestOf<Protocol extends EntrypointProtocolDeclaration> = Protocol extends EntrypointProtocol<infer Request, infer _Response>
321
+ ? Request
322
+ : OpenRequest
323
+
324
+ export type ResponseOf<Protocol extends EntrypointProtocolDeclaration> = Protocol extends EntrypointProtocol<infer _Request, infer Response>
325
+ ? Response
326
+ : OpenValue
327
+
328
+ export type BodyOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { body: infer Body }
329
+ ? Body
330
+ : OpenValue
331
+
332
+ export type ParamsOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { params: infer Params }
333
+ ? Params
334
+ : object
335
+
336
+ export type QueryOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { query: infer Query }
337
+ ? Query
338
+ : object
339
+
340
+ export type HeadersOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> extends { headers: infer Headers }
341
+ ? Headers
342
+ : object
343
+
344
+ export type CallRequestOf<Protocol extends EntrypointProtocolDeclaration> = RequestOf<Protocol> & CallOptions
345
+
346
+ export interface EntrypointTree {
347
+ readonly [key: string]: EntrypointProtocolDeclaration | EntrypointTree
348
+ }
349
+
350
+ export type FilterHelper = ReturnType<typeof createFilterHelper>
package/src/utils.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Service alias a transport registers under. The default protocol is the web one, so an application
3
+ * that binds nothing keeps talking HTTP.
4
+ */
5
+ export const transportAlias = (protocol: string = 'http') => `transport:${protocol}`