@lakutata/entrypoint 3.0.0-beta.0
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/LICENSE +23 -0
- package/README.md +183 -0
- package/THIRD_PARTY_NOTICES.md +206 -0
- package/dist/cjs/Entrypoint.d.ts +868 -0
- package/dist/cjs/Entrypoint.js +998 -0
- package/dist/cjs/adapter/commander/CommanderCLIEntrypoint.d.ts +192 -0
- package/dist/cjs/adapter/commander/CommanderCLIEntrypoint.js +439 -0
- package/dist/cjs/adapter/commander/Prompt.d.ts +22 -0
- package/dist/cjs/adapter/commander/Prompt.js +164 -0
- package/dist/cjs/adapter/commander/Width.d.ts +12 -0
- package/dist/cjs/adapter/commander/Width.js +67 -0
- package/dist/cjs/adapter/electron/ElectronIPCServiceEntrypoint.d.ts +203 -0
- package/dist/cjs/adapter/electron/ElectronIPCServiceEntrypoint.js +249 -0
- package/dist/cjs/adapter/express/ExpressHTTPEntrypoint.d.ts +172 -0
- package/dist/cjs/adapter/express/ExpressHTTPEntrypoint.js +301 -0
- package/dist/cjs/adapter/express/Responders.d.ts +89 -0
- package/dist/cjs/adapter/express/Responders.js +71 -0
- package/dist/cjs/adapter/express/StaticUI.d.ts +83 -0
- package/dist/cjs/adapter/express/StaticUI.js +104 -0
- package/dist/cjs/adapter/fastify/FastifyHTTPEntrypoint.d.ts +156 -0
- package/dist/cjs/adapter/fastify/FastifyHTTPEntrypoint.js +339 -0
- package/dist/cjs/adapter/fastify/Responders.d.ts +88 -0
- package/dist/cjs/adapter/fastify/Responders.js +77 -0
- package/dist/cjs/adapter/http/HTTPServiceEntrypoint.d.ts +117 -0
- package/dist/cjs/adapter/http/HTTPServiceEntrypoint.js +257 -0
- package/dist/cjs/adapter/jsonrpc/JSONRPCProtocol.d.ts +194 -0
- package/dist/cjs/adapter/jsonrpc/JSONRPCProtocol.js +187 -0
- package/dist/cjs/adapter/jsonrpc/JSONRPCServiceEntrypoint.d.ts +154 -0
- package/dist/cjs/adapter/jsonrpc/JSONRPCServiceEntrypoint.js +397 -0
- package/dist/cjs/adapter/schedule/ScheduleEntrypoint.d.ts +86 -0
- package/dist/cjs/adapter/schedule/ScheduleEntrypoint.js +275 -0
- package/dist/cjs/adapter/socket.io/SocketIOServiceEntrypoint.d.ts +138 -0
- package/dist/cjs/adapter/socket.io/SocketIOServiceEntrypoint.js +216 -0
- package/dist/cjs/channel/BuiltinChannels.d.ts +18 -0
- package/dist/cjs/channel/BuiltinChannels.js +128 -0
- package/dist/cjs/channel/Channel.d.ts +196 -0
- package/dist/cjs/channel/Channel.js +106 -0
- package/dist/cjs/channel/EntrypointAdapter.d.ts +195 -0
- package/dist/cjs/channel/EntrypointAdapter.js +43 -0
- package/dist/cjs/context/BaseContext.d.ts +75 -0
- package/dist/cjs/context/BaseContext.js +90 -0
- package/dist/cjs/context/CLIContext.d.ts +38 -0
- package/dist/cjs/context/CLIContext.js +53 -0
- package/dist/cjs/context/HTTPContext.d.ts +52 -0
- package/dist/cjs/context/HTTPContext.js +78 -0
- package/dist/cjs/context/ScheduleContext.d.ts +47 -0
- package/dist/cjs/context/ScheduleContext.js +65 -0
- package/dist/cjs/context/ServiceContext.d.ts +47 -0
- package/dist/cjs/context/ServiceContext.js +62 -0
- package/dist/cjs/decorators/CLIAction.d.ts +120 -0
- package/dist/cjs/decorators/CLIAction.js +13 -0
- package/dist/cjs/decorators/HTTPAction.d.ts +178 -0
- package/dist/cjs/decorators/HTTPAction.js +14 -0
- package/dist/cjs/decorators/Prefix.d.ts +44 -0
- package/dist/cjs/decorators/Prefix.js +48 -0
- package/dist/cjs/decorators/Schedule.d.ts +120 -0
- package/dist/cjs/decorators/Schedule.js +64 -0
- package/dist/cjs/decorators/ServiceAction.d.ts +116 -0
- package/dist/cjs/decorators/ServiceAction.js +12 -0
- package/dist/cjs/decorators/UseMiddlewares.d.ts +52 -0
- package/dist/cjs/decorators/UseMiddlewares.js +58 -0
- package/dist/cjs/decorators/http/DELETE.d.ts +87 -0
- package/dist/cjs/decorators/http/DELETE.js +7 -0
- package/dist/cjs/decorators/http/GET.d.ts +89 -0
- package/dist/cjs/decorators/http/GET.js +7 -0
- package/dist/cjs/decorators/http/HEAD.d.ts +84 -0
- package/dist/cjs/decorators/http/HEAD.js +7 -0
- package/dist/cjs/decorators/http/OPTIONS.d.ts +80 -0
- package/dist/cjs/decorators/http/OPTIONS.js +7 -0
- package/dist/cjs/decorators/http/PATCH.d.ts +90 -0
- package/dist/cjs/decorators/http/PATCH.js +7 -0
- package/dist/cjs/decorators/http/POST.d.ts +91 -0
- package/dist/cjs/decorators/http/POST.js +7 -0
- package/dist/cjs/decorators/http/PUT.d.ts +92 -0
- package/dist/cjs/decorators/http/PUT.js +7 -0
- package/dist/cjs/exceptions/AccessDeniedException.d.ts +10 -0
- package/dist/cjs/exceptions/AccessDeniedException.js +17 -0
- package/dist/cjs/exceptions/ControllerActionNotFoundException.d.ts +9 -0
- package/dist/cjs/exceptions/ControllerActionNotFoundException.js +16 -0
- package/dist/cjs/exceptions/DuplicateActionNameException.d.ts +8 -0
- package/dist/cjs/exceptions/DuplicateActionNameException.js +15 -0
- package/dist/cjs/exceptions/EntrypointStoppedException.d.ts +9 -0
- package/dist/cjs/exceptions/EntrypointStoppedException.js +16 -0
- package/dist/cjs/exceptions/InvalidActionGroupException.d.ts +4 -0
- package/dist/cjs/exceptions/InvalidActionGroupException.js +11 -0
- package/dist/cjs/exceptions/InvalidChannelException.d.ts +8 -0
- package/dist/cjs/exceptions/InvalidChannelException.js +15 -0
- package/dist/cjs/exceptions/InvalidEntrypointAdapterException.d.ts +9 -0
- package/dist/cjs/exceptions/InvalidEntrypointAdapterException.js +16 -0
- package/dist/cjs/exceptions/InvalidMiddlewareException.d.ts +8 -0
- package/dist/cjs/exceptions/InvalidMiddlewareException.js +15 -0
- package/dist/cjs/exceptions/InvalidPrefixException.d.ts +8 -0
- package/dist/cjs/exceptions/InvalidPrefixException.js +15 -0
- package/dist/cjs/exceptions/MiddlewareNextCalledException.d.ts +8 -0
- package/dist/cjs/exceptions/MiddlewareNextCalledException.js +15 -0
- package/dist/cjs/exceptions/RouteNotFoundException.d.ts +9 -0
- package/dist/cjs/exceptions/RouteNotFoundException.js +16 -0
- package/dist/cjs/exceptions/ServiceInvokeException.d.ts +11 -0
- package/dist/cjs/exceptions/ServiceInvokeException.js +14 -0
- package/dist/cjs/exports/CTRLDecorators.d.ts +13 -0
- package/dist/cjs/exports/CTRLDecorators.js +38 -0
- package/dist/cjs/exports/Channel.d.ts +14 -0
- package/dist/cjs/exports/Channel.js +33 -0
- package/dist/cjs/exports/CommanderAdapter.d.ts +1 -0
- package/dist/cjs/exports/CommanderAdapter.js +8 -0
- package/dist/cjs/exports/ElectronAdapter.d.ts +1 -0
- package/dist/cjs/exports/ElectronAdapter.js +9 -0
- package/dist/cjs/exports/Entrypoint.d.ts +24 -0
- package/dist/cjs/exports/Entrypoint.js +55 -0
- package/dist/cjs/exports/ExpressAdapter.d.ts +4 -0
- package/dist/cjs/exports/ExpressAdapter.js +15 -0
- package/dist/cjs/exports/FastifyAdapter.d.ts +4 -0
- package/dist/cjs/exports/FastifyAdapter.js +14 -0
- package/dist/cjs/exports/JSONRPCAdapter.d.ts +2 -0
- package/dist/cjs/exports/JSONRPCAdapter.js +11 -0
- package/dist/cjs/exports/SocketIOAdapter.d.ts +1 -0
- package/dist/cjs/exports/SocketIOAdapter.js +9 -0
- package/dist/cjs/lib/AccessControl.d.ts +118 -0
- package/dist/cjs/lib/AccessControl.js +208 -0
- package/dist/cjs/lib/AccessControlRule.d.ts +91 -0
- package/dist/cjs/lib/AccessControlRule.js +76 -0
- package/dist/cjs/lib/ActionOptions.d.ts +67 -0
- package/dist/cjs/lib/ActionOptions.js +67 -0
- package/dist/cjs/lib/ActionResult.d.ts +28 -0
- package/dist/cjs/lib/ActionResult.js +28 -0
- package/dist/cjs/lib/ApplicationOf.d.ts +6 -0
- package/dist/cjs/lib/ApplicationOf.js +14 -0
- package/dist/cjs/lib/Controller.d.ts +59 -0
- package/dist/cjs/lib/Controller.js +64 -0
- package/dist/cjs/lib/ControllerEntrypoint.d.ts +168 -0
- package/dist/cjs/lib/ControllerEntrypoint.js +239 -0
- package/dist/cjs/lib/GetActionDTOAndOptions.d.ts +29 -0
- package/dist/cjs/lib/GetActionDTOAndOptions.js +49 -0
- package/dist/cjs/lib/HTTPErrors.d.ts +55 -0
- package/dist/cjs/lib/HTTPErrors.js +52 -0
- package/dist/cjs/lib/Middleware.d.ts +146 -0
- package/dist/cjs/lib/Middleware.js +144 -0
- package/dist/cjs/lib/Prefix.d.ts +98 -0
- package/dist/cjs/lib/Prefix.js +151 -0
- package/dist/cjs/lib/Result.d.ts +173 -0
- package/dist/cjs/lib/Result.js +153 -0
- package/dist/cjs/lib/ServiceResponseCodec.d.ts +82 -0
- package/dist/cjs/lib/ServiceResponseCodec.js +117 -0
- package/dist/cjs/lib/StringifyPattern.d.ts +7 -0
- package/dist/cjs/lib/StringifyPattern.js +58 -0
- package/dist/cjs/lib/UnsetValue.d.ts +12 -0
- package/dist/cjs/lib/UnsetValue.js +216 -0
- package/dist/cjs/lib/pattern/GlobPattern.d.ts +34 -0
- package/dist/cjs/lib/pattern/GlobPattern.js +68 -0
- package/dist/cjs/lib/pattern/PatternManager.d.ts +103 -0
- package/dist/cjs/lib/pattern/PatternManager.js +233 -0
- package/dist/cjs/lib/schedule/Cron.d.ts +56 -0
- package/dist/cjs/lib/schedule/Cron.js +282 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/CLIContextParams.d.ts +14 -0
- package/dist/cjs/types/CLIContextParams.js +2 -0
- package/dist/cjs/types/ErrorDescription.d.ts +14 -0
- package/dist/cjs/types/ErrorDescription.js +2 -0
- package/dist/cjs/types/HTTPContextParams.d.ts +27 -0
- package/dist/cjs/types/HTTPContextParams.js +2 -0
- package/dist/cjs/types/ScheduleContextParams.d.ts +21 -0
- package/dist/cjs/types/ScheduleContextParams.js +2 -0
- package/dist/cjs/types/ServiceContextParams.d.ts +16 -0
- package/dist/cjs/types/ServiceContextParams.js +2 -0
- package/dist/esm/Entrypoint.js +985 -0
- package/dist/esm/adapter/commander/CommanderCLIEntrypoint.js +433 -0
- package/dist/esm/adapter/commander/Prompt.js +127 -0
- package/dist/esm/adapter/commander/Width.js +63 -0
- package/dist/esm/adapter/electron/ElectronIPCServiceEntrypoint.js +212 -0
- package/dist/esm/adapter/express/ExpressHTTPEntrypoint.js +295 -0
- package/dist/esm/adapter/express/Responders.js +66 -0
- package/dist/esm/adapter/express/StaticUI.js +96 -0
- package/dist/esm/adapter/fastify/FastifyHTTPEntrypoint.js +333 -0
- package/dist/esm/adapter/fastify/Responders.js +73 -0
- package/dist/esm/adapter/http/HTTPServiceEntrypoint.js +253 -0
- package/dist/esm/adapter/jsonrpc/JSONRPCProtocol.js +182 -0
- package/dist/esm/adapter/jsonrpc/JSONRPCServiceEntrypoint.js +361 -0
- package/dist/esm/adapter/schedule/ScheduleEntrypoint.js +272 -0
- package/dist/esm/adapter/socket.io/SocketIOServiceEntrypoint.js +212 -0
- package/dist/esm/channel/BuiltinChannels.js +125 -0
- package/dist/esm/channel/Channel.js +100 -0
- package/dist/esm/channel/EntrypointAdapter.js +39 -0
- package/dist/esm/context/BaseContext.js +87 -0
- package/dist/esm/context/CLIContext.js +49 -0
- package/dist/esm/context/HTTPContext.js +74 -0
- package/dist/esm/context/ScheduleContext.js +61 -0
- package/dist/esm/context/ServiceContext.js +58 -0
- package/dist/esm/decorators/CLIAction.js +10 -0
- package/dist/esm/decorators/HTTPAction.js +11 -0
- package/dist/esm/decorators/Prefix.js +45 -0
- package/dist/esm/decorators/Schedule.js +61 -0
- package/dist/esm/decorators/ServiceAction.js +9 -0
- package/dist/esm/decorators/UseMiddlewares.js +55 -0
- package/dist/esm/decorators/http/DELETE.js +4 -0
- package/dist/esm/decorators/http/GET.js +4 -0
- package/dist/esm/decorators/http/HEAD.js +4 -0
- package/dist/esm/decorators/http/OPTIONS.js +4 -0
- package/dist/esm/decorators/http/PATCH.js +4 -0
- package/dist/esm/decorators/http/POST.js +4 -0
- package/dist/esm/decorators/http/PUT.js +4 -0
- package/dist/esm/exceptions/AccessDeniedException.js +13 -0
- package/dist/esm/exceptions/ControllerActionNotFoundException.js +12 -0
- package/dist/esm/exceptions/DuplicateActionNameException.js +11 -0
- package/dist/esm/exceptions/EntrypointStoppedException.js +12 -0
- package/dist/esm/exceptions/InvalidActionGroupException.js +7 -0
- package/dist/esm/exceptions/InvalidChannelException.js +11 -0
- package/dist/esm/exceptions/InvalidEntrypointAdapterException.js +12 -0
- package/dist/esm/exceptions/InvalidMiddlewareException.js +11 -0
- package/dist/esm/exceptions/InvalidPrefixException.js +11 -0
- package/dist/esm/exceptions/MiddlewareNextCalledException.js +11 -0
- package/dist/esm/exceptions/RouteNotFoundException.js +12 -0
- package/dist/esm/exceptions/ServiceInvokeException.js +10 -0
- package/dist/esm/exports/CTRLDecorators.js +19 -0
- package/dist/esm/exports/Channel.js +11 -0
- package/dist/esm/exports/CommanderAdapter.js +1 -0
- package/dist/esm/exports/ElectronAdapter.js +1 -0
- package/dist/esm/exports/Entrypoint.js +22 -0
- package/dist/esm/exports/ExpressAdapter.js +3 -0
- package/dist/esm/exports/FastifyAdapter.js +3 -0
- package/dist/esm/exports/JSONRPCAdapter.js +2 -0
- package/dist/esm/exports/SocketIOAdapter.js +1 -0
- package/dist/esm/lib/AccessControl.js +204 -0
- package/dist/esm/lib/AccessControlRule.js +72 -0
- package/dist/esm/lib/ActionOptions.js +63 -0
- package/dist/esm/lib/ActionResult.js +24 -0
- package/dist/esm/lib/ApplicationOf.js +11 -0
- package/dist/esm/lib/Controller.js +61 -0
- package/dist/esm/lib/ControllerEntrypoint.js +229 -0
- package/dist/esm/lib/GetActionDTOAndOptions.js +46 -0
- package/dist/esm/lib/HTTPErrors.js +48 -0
- package/dist/esm/lib/Middleware.js +134 -0
- package/dist/esm/lib/Prefix.js +143 -0
- package/dist/esm/lib/Result.js +147 -0
- package/dist/esm/lib/ServiceResponseCodec.js +113 -0
- package/dist/esm/lib/StringifyPattern.js +55 -0
- package/dist/esm/lib/UnsetValue.js +213 -0
- package/dist/esm/lib/pattern/GlobPattern.js +64 -0
- package/dist/esm/lib/pattern/PatternManager.js +229 -0
- package/dist/esm/lib/schedule/Cron.js +277 -0
- package/dist/esm/types/CLIContextParams.js +1 -0
- package/dist/esm/types/ErrorDescription.js +1 -0
- package/dist/esm/types/HTTPContextParams.js +1 -0
- package/dist/esm/types/ScheduleContextParams.js +1 -0
- package/dist/esm/types/ServiceContextParams.js +1 -0
- package/dist/types/Entrypoint.d.ts +868 -0
- package/dist/types/adapter/commander/CommanderCLIEntrypoint.d.ts +192 -0
- package/dist/types/adapter/commander/Prompt.d.ts +22 -0
- package/dist/types/adapter/commander/Width.d.ts +12 -0
- package/dist/types/adapter/electron/ElectronIPCServiceEntrypoint.d.ts +203 -0
- package/dist/types/adapter/express/ExpressHTTPEntrypoint.d.ts +172 -0
- package/dist/types/adapter/express/Responders.d.ts +89 -0
- package/dist/types/adapter/express/StaticUI.d.ts +83 -0
- package/dist/types/adapter/fastify/FastifyHTTPEntrypoint.d.ts +156 -0
- package/dist/types/adapter/fastify/Responders.d.ts +88 -0
- package/dist/types/adapter/http/HTTPServiceEntrypoint.d.ts +117 -0
- package/dist/types/adapter/jsonrpc/JSONRPCProtocol.d.ts +194 -0
- package/dist/types/adapter/jsonrpc/JSONRPCServiceEntrypoint.d.ts +154 -0
- package/dist/types/adapter/schedule/ScheduleEntrypoint.d.ts +86 -0
- package/dist/types/adapter/socket.io/SocketIOServiceEntrypoint.d.ts +138 -0
- package/dist/types/channel/BuiltinChannels.d.ts +18 -0
- package/dist/types/channel/Channel.d.ts +196 -0
- package/dist/types/channel/EntrypointAdapter.d.ts +195 -0
- package/dist/types/context/BaseContext.d.ts +75 -0
- package/dist/types/context/CLIContext.d.ts +38 -0
- package/dist/types/context/HTTPContext.d.ts +52 -0
- package/dist/types/context/ScheduleContext.d.ts +47 -0
- package/dist/types/context/ServiceContext.d.ts +47 -0
- package/dist/types/decorators/CLIAction.d.ts +120 -0
- package/dist/types/decorators/HTTPAction.d.ts +178 -0
- package/dist/types/decorators/Prefix.d.ts +44 -0
- package/dist/types/decorators/Schedule.d.ts +120 -0
- package/dist/types/decorators/ServiceAction.d.ts +116 -0
- package/dist/types/decorators/UseMiddlewares.d.ts +52 -0
- package/dist/types/decorators/http/DELETE.d.ts +87 -0
- package/dist/types/decorators/http/GET.d.ts +89 -0
- package/dist/types/decorators/http/HEAD.d.ts +84 -0
- package/dist/types/decorators/http/OPTIONS.d.ts +80 -0
- package/dist/types/decorators/http/PATCH.d.ts +90 -0
- package/dist/types/decorators/http/POST.d.ts +91 -0
- package/dist/types/decorators/http/PUT.d.ts +92 -0
- package/dist/types/exceptions/AccessDeniedException.d.ts +10 -0
- package/dist/types/exceptions/ControllerActionNotFoundException.d.ts +9 -0
- package/dist/types/exceptions/DuplicateActionNameException.d.ts +8 -0
- package/dist/types/exceptions/EntrypointStoppedException.d.ts +9 -0
- package/dist/types/exceptions/InvalidActionGroupException.d.ts +4 -0
- package/dist/types/exceptions/InvalidChannelException.d.ts +8 -0
- package/dist/types/exceptions/InvalidEntrypointAdapterException.d.ts +9 -0
- package/dist/types/exceptions/InvalidMiddlewareException.d.ts +8 -0
- package/dist/types/exceptions/InvalidPrefixException.d.ts +8 -0
- package/dist/types/exceptions/MiddlewareNextCalledException.d.ts +8 -0
- package/dist/types/exceptions/RouteNotFoundException.d.ts +9 -0
- package/dist/types/exceptions/ServiceInvokeException.d.ts +11 -0
- package/dist/types/exports/CTRLDecorators.d.ts +13 -0
- package/dist/types/exports/Channel.d.ts +14 -0
- package/dist/types/exports/CommanderAdapter.d.ts +1 -0
- package/dist/types/exports/ElectronAdapter.d.ts +1 -0
- package/dist/types/exports/Entrypoint.d.ts +24 -0
- package/dist/types/exports/ExpressAdapter.d.ts +4 -0
- package/dist/types/exports/FastifyAdapter.d.ts +4 -0
- package/dist/types/exports/JSONRPCAdapter.d.ts +2 -0
- package/dist/types/exports/SocketIOAdapter.d.ts +1 -0
- package/dist/types/lib/AccessControl.d.ts +118 -0
- package/dist/types/lib/AccessControlRule.d.ts +91 -0
- package/dist/types/lib/ActionOptions.d.ts +67 -0
- package/dist/types/lib/ActionResult.d.ts +28 -0
- package/dist/types/lib/ApplicationOf.d.ts +6 -0
- package/dist/types/lib/Controller.d.ts +59 -0
- package/dist/types/lib/ControllerEntrypoint.d.ts +168 -0
- package/dist/types/lib/GetActionDTOAndOptions.d.ts +29 -0
- package/dist/types/lib/HTTPErrors.d.ts +55 -0
- package/dist/types/lib/Middleware.d.ts +146 -0
- package/dist/types/lib/Prefix.d.ts +98 -0
- package/dist/types/lib/Result.d.ts +173 -0
- package/dist/types/lib/ServiceResponseCodec.d.ts +82 -0
- package/dist/types/lib/StringifyPattern.d.ts +7 -0
- package/dist/types/lib/UnsetValue.d.ts +12 -0
- package/dist/types/lib/pattern/GlobPattern.d.ts +34 -0
- package/dist/types/lib/pattern/PatternManager.d.ts +103 -0
- package/dist/types/lib/schedule/Cron.d.ts +56 -0
- package/dist/types/types/CLIContextParams.d.ts +14 -0
- package/dist/types/types/ErrorDescription.d.ts +14 -0
- package/dist/types/types/HTTPContextParams.d.ts +27 -0
- package/dist/types/types/ScheduleContextParams.d.ts +21 -0
- package/dist/types/types/ServiceContextParams.d.ts +16 -0
- package/package.json +152 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Controller, type ControllerProperty } from './Controller.js';
|
|
2
|
+
import { IBaseObjectConstructor, ActionPattern, JSONSchema, DTO, Component } from '@lakutata/core';
|
|
3
|
+
import { ActionOptions } from './ActionOptions.js';
|
|
4
|
+
import { CLIContext } from '../context/CLIContext.js';
|
|
5
|
+
import { ServiceContext } from '../context/ServiceContext.js';
|
|
6
|
+
import { HTTPContext } from '../context/HTTPContext.js';
|
|
7
|
+
import type { AccessControlRuleHandler } from './AccessControlRule.js';
|
|
8
|
+
import { MiddlewareDefinition } from './Middleware.js';
|
|
9
|
+
import { ChannelDefinition } from '../channel/Channel.js';
|
|
10
|
+
export type ActionPatternMap = Map<ActionPattern, ActionDetails>;
|
|
11
|
+
/**
|
|
12
|
+
* A registered controller action: its address in its channel, its controller and method, its input DTO and its
|
|
13
|
+
* options. The channels read it from {@link ChannelEntry.details}.
|
|
14
|
+
*/
|
|
15
|
+
export type ActionDetails<ClassPrototype extends Controller = Controller, DTOConstructor extends typeof DTO = typeof DTO> = {
|
|
16
|
+
/**
|
|
17
|
+
* The action's address in its channel (`{route, method}`, `{command}`, a service pattern…), with its
|
|
18
|
+
* controller prefix once bound to an entrypoint.
|
|
19
|
+
*/
|
|
20
|
+
pattern: ActionPattern;
|
|
21
|
+
/**
|
|
22
|
+
* The controller class serving the action: the registered controller, which may be a subclass of the class
|
|
23
|
+
* declaring the action.
|
|
24
|
+
*/
|
|
25
|
+
constructor: IBaseObjectConstructor<ClassPrototype>;
|
|
26
|
+
/**
|
|
27
|
+
* The controller method running the action.
|
|
28
|
+
*/
|
|
29
|
+
method: string | number | symbol;
|
|
30
|
+
/**
|
|
31
|
+
* The DTO validating the action's input.
|
|
32
|
+
*/
|
|
33
|
+
dtoConstructor: DTOConstructor;
|
|
34
|
+
/**
|
|
35
|
+
* The JSON schema of the action's input (its DTO).
|
|
36
|
+
*/
|
|
37
|
+
jsonSchema: JSONSchema;
|
|
38
|
+
/**
|
|
39
|
+
* The middlewares of the action's `middlewares` option.
|
|
40
|
+
*/
|
|
41
|
+
middlewares: MiddlewareDefinition[];
|
|
42
|
+
/**
|
|
43
|
+
* Get the action's options and identity, as given to the access control rules (`targetAction`).
|
|
44
|
+
* @returns The action's identity and options.
|
|
45
|
+
*/
|
|
46
|
+
getActionInfo: () => ActionInfo;
|
|
47
|
+
} & ActionInfo;
|
|
48
|
+
/**
|
|
49
|
+
* A controller action's identity and options.
|
|
50
|
+
*/
|
|
51
|
+
export type ActionInfo = {
|
|
52
|
+
/**
|
|
53
|
+
* The action's id: a UUID derived from the controller, the method and the address, stable across restarts.
|
|
54
|
+
*/
|
|
55
|
+
id: string;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the action is checked by the access control rules (its `acl` option).
|
|
58
|
+
*/
|
|
59
|
+
acl: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The action's controller class and method, as `ControllerClass:method`.
|
|
62
|
+
*/
|
|
63
|
+
action: string;
|
|
64
|
+
/**
|
|
65
|
+
* The action's name: its `name` option, `ControllerClass:method` by default.
|
|
66
|
+
*/
|
|
67
|
+
name: string;
|
|
68
|
+
/**
|
|
69
|
+
* The action's description: its `description` option, empty by default.
|
|
70
|
+
*/
|
|
71
|
+
description: string;
|
|
72
|
+
/**
|
|
73
|
+
* The ids of the action's groups (its `groups` option).
|
|
74
|
+
*/
|
|
75
|
+
groups: string[];
|
|
76
|
+
/**
|
|
77
|
+
* The action's own access rule (its `rule` option).
|
|
78
|
+
*/
|
|
79
|
+
rule?: AccessControlRuleHandler<any>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* The channels of the actions of a controller, its parent classes included
|
|
83
|
+
* @param target
|
|
84
|
+
*/
|
|
85
|
+
export declare function getControllerChannels(target: IBaseObjectConstructor<Controller>): string[];
|
|
86
|
+
/**
|
|
87
|
+
* Register an action of a controller on a channel
|
|
88
|
+
* @param channel
|
|
89
|
+
* @param target
|
|
90
|
+
* @param actionPattern
|
|
91
|
+
* @param details
|
|
92
|
+
* @constructor
|
|
93
|
+
*/
|
|
94
|
+
export declare function registerChannelAction(channel: ChannelDefinition, target: IBaseObjectConstructor<Controller>, actionPattern: ActionPattern, details: ActionDetails): void;
|
|
95
|
+
/**
|
|
96
|
+
* Register a controller method as an action of a channel, for the decorators of the packages providing a channel
|
|
97
|
+
* (the built-in `@HTTPAction`, `@CLIAction` and `@ServiceAction` call it). The action is served by the controller class
|
|
98
|
+
* and its subclasses registered in an entrypoint. Registering the same address again for the class replaces the
|
|
99
|
+
* previous action.
|
|
100
|
+
* @param channel The channel's definition (see {@link defineChannel}).
|
|
101
|
+
* @param controllerPrototype The prototype of the controller class (the decorator's target).
|
|
102
|
+
* @param propertyKey The name of the method running the action.
|
|
103
|
+
* @param actionPattern The action's address, checked by the channel's `validate`; at most 2 levels of nesting.
|
|
104
|
+
* @param dtoConstructor The DTO validating the action's input (`FlexibleDTO` to accept any input).
|
|
105
|
+
* @param actionOptions The action's options (name, description, groups, access control, middlewares); give them
|
|
106
|
+
* validated (as {@link getActionDTOAndOptions} returns them).
|
|
107
|
+
* @throws {InvalidActionPatternDepthException} When the address is nested more than 2 levels deep.
|
|
108
|
+
* @throws {InvalidMiddlewareException} When a middleware of the options is neither a function nor a `Middleware` subclass.
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* import {DTO} from 'lakutata'
|
|
112
|
+
* import {Controller, type ControllerProperty} from 'lakutata/com/entrypoint'
|
|
113
|
+
* import {getActionDTOAndOptions, getChannel, registerControllerAction, type ActionOptions} from '@lakutata/entrypoint/channel'
|
|
114
|
+
*
|
|
115
|
+
* //A decorator declaring the actions of a "queue" channel defined by its package
|
|
116
|
+
* export function OnMessage(topic: string, dtoOrOptions?: typeof DTO | ActionOptions<any>, options?: ActionOptions<any>) {
|
|
117
|
+
* return <ClassPrototype extends Controller>(target: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>): void => {
|
|
118
|
+
* const [dtoConstructor, actionOptions] = getActionDTOAndOptions(dtoOrOptions, options)
|
|
119
|
+
* registerControllerAction(getChannel('queue'), target, propertyKey, {topic: topic}, dtoConstructor, actionOptions)
|
|
120
|
+
* }
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export declare function registerControllerAction<ClassPrototype extends Controller, DTOConstructor extends typeof DTO = typeof DTO>(channel: ChannelDefinition, controllerPrototype: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>, actionPattern: ActionPattern, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<any>): void;
|
|
125
|
+
/**
|
|
126
|
+
* Bind controller to component
|
|
127
|
+
* @param component
|
|
128
|
+
* @param controllerConstructor
|
|
129
|
+
* @constructor
|
|
130
|
+
*/
|
|
131
|
+
export declare function bindControllerToComponent(component: Component, controllerConstructor: IBaseObjectConstructor<Controller>): void;
|
|
132
|
+
/**
|
|
133
|
+
* Get module controller action map
|
|
134
|
+
* @constructor
|
|
135
|
+
* @param component
|
|
136
|
+
*/
|
|
137
|
+
export declare function getComponentControllerActionMap(component: Component): Map<string, ActionPatternMap>;
|
|
138
|
+
/**
|
|
139
|
+
* Register http action
|
|
140
|
+
* @param route
|
|
141
|
+
* @param methods
|
|
142
|
+
* @param controllerPrototype
|
|
143
|
+
* @param propertyKey
|
|
144
|
+
* @param dtoConstructor
|
|
145
|
+
* @param actionOptions
|
|
146
|
+
* @constructor
|
|
147
|
+
*/
|
|
148
|
+
export declare function registerHTTPAction<ClassPrototype extends Controller, DTOConstructor extends typeof DTO = typeof DTO>(route: string, methods: string[], controllerPrototype: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<HTTPContext>): void;
|
|
149
|
+
/**
|
|
150
|
+
* Register cli action
|
|
151
|
+
* @param command
|
|
152
|
+
* @param controllerPrototype
|
|
153
|
+
* @param propertyKey
|
|
154
|
+
* @param dtoConstructor
|
|
155
|
+
* @param actionOptions
|
|
156
|
+
* @constructor
|
|
157
|
+
*/
|
|
158
|
+
export declare function registerCLIAction<ClassPrototype extends Controller, DTOConstructor extends typeof DTO = typeof DTO>(command: string, controllerPrototype: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<CLIContext>): void;
|
|
159
|
+
/**
|
|
160
|
+
* Register service action
|
|
161
|
+
* @param pattern
|
|
162
|
+
* @param controllerPrototype
|
|
163
|
+
* @param propertyKey
|
|
164
|
+
* @param dtoConstructor
|
|
165
|
+
* @param actionOptions
|
|
166
|
+
* @constructor
|
|
167
|
+
*/
|
|
168
|
+
export declare function registerServiceAction<ClassPrototype extends Controller, DTOConstructor extends typeof DTO = typeof DTO>(pattern: ActionPattern, controllerPrototype: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<ServiceContext>): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DTO } from '@lakutata/core';
|
|
2
|
+
import { ActionOptions } from './ActionOptions.js';
|
|
3
|
+
import { FlexibleDTO } from '@lakutata/core/dtos';
|
|
4
|
+
/**
|
|
5
|
+
* Sort out the optional arguments of an action decorator (`(dto?)`, `(options?)` or `(dto, options)`): a function is
|
|
6
|
+
* the DTO, an object the options. The options are validated, their defaults applied.
|
|
7
|
+
* @param dtoConstructorOrOptions The DTO validating the action's input, or the action's options.
|
|
8
|
+
* @param options The action's options, when the first argument is the DTO.
|
|
9
|
+
* @returns The DTO (`FlexibleDTO`, accepting any input, when none is given) and the validated options.
|
|
10
|
+
* @throws {Error} When the options are invalid (the validation error of {@link ActionOptions}).
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import {DTO} from 'lakutata'
|
|
14
|
+
* import {FlexibleDTO} from 'lakutata/dtos'
|
|
15
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
16
|
+
* import {getActionDTOAndOptions} from '@lakutata/entrypoint/channel'
|
|
17
|
+
*
|
|
18
|
+
* class SendDTO extends DTO {
|
|
19
|
+
* @Expect(DTO.String().required())
|
|
20
|
+
* public text: string
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* const [dto, options] = getActionDTOAndOptions(SendDTO, {name: 'send'})
|
|
24
|
+
* console.log(dto === SendDTO, options.groups) //true []
|
|
25
|
+
* const [anyInput] = getActionDTOAndOptions({acl: true})
|
|
26
|
+
* console.log(anyInput === FlexibleDTO) //true
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function getActionDTOAndOptions<DTOConstructor extends typeof DTO = typeof DTO>(dtoConstructorOrOptions?: DTOConstructor | ActionOptions<any>, options?: ActionOptions<any>): [DTOConstructor | typeof FlexibleDTO, ActionOptions<any>];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ErrorDescription } from '../types/ErrorDescription.js';
|
|
2
|
+
/**
|
|
3
|
+
* Where an error answered by an HTTP adapter comes from, given to the `error` of its responder: `'action'` when the
|
|
4
|
+
* request reached an action and its dispatch failed (the entrypoint's middlewares, the validation of the input, the
|
|
5
|
+
* access control, the action itself); `'request'` when it failed before (a middleware of the web framework such as an
|
|
6
|
+
* authenticator, a hook of fastify, a body too large) or matched no route.
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import type {Request, Response} from 'express'
|
|
10
|
+
* import {describeError, type ExpressResponder, type HTTPErrorOrigin, statusOfError} from 'lakutata/adapter/express'
|
|
11
|
+
*
|
|
12
|
+
* //The errors of the actions answered with 200, the others with their status
|
|
13
|
+
* export const responder: ExpressResponder = {
|
|
14
|
+
* success: (response: Response, data: unknown): void => void response.json({data: data}),
|
|
15
|
+
* error: (response: Response, error: unknown, _request: Request, origin?: HTTPErrorOrigin): void => {
|
|
16
|
+
* response.status(origin === 'action' ? 200 : statusOfError(error)).json(describeError(error))
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export type HTTPErrorOrigin = 'action' | 'request';
|
|
22
|
+
/**
|
|
23
|
+
* Find the HTTP status of an error, read from its `statusCode` or `status`: the first client error (4xx) found on the
|
|
24
|
+
* error or along its `cause` chain, else the error's own status when it is between 400 and 599, else 500. A validation
|
|
25
|
+
* failure, wrapped in an exception whose cause is the 400 validation error, thus gives 400.
|
|
26
|
+
* @param error The error, any value.
|
|
27
|
+
* @returns The HTTP status, from 400 to 599.
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import {statusOfError} from 'lakutata/adapter/express'
|
|
31
|
+
*
|
|
32
|
+
* class NotFound extends Error {
|
|
33
|
+
* public readonly statusCode: number = 404
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* console.log(statusOfError(new NotFound('No such order'))) //404
|
|
37
|
+
* console.log(statusOfError(new Error('Failed', {cause: new NotFound('No such order')}))) //404
|
|
38
|
+
* console.log(statusOfError(new Error('Boom'))) //500
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function statusOfError(error: unknown): number;
|
|
42
|
+
/**
|
|
43
|
+
* Describe an error as the JSON responders send it: its `errno` (or `code`, `E_UNKNOWN` without either) and its
|
|
44
|
+
* `errMsg` (or `message`, or the error converted to a string).
|
|
45
|
+
* @param error The error, any value.
|
|
46
|
+
* @returns The error's number and message.
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* import {describeError, type ErrorDescription} from 'lakutata/adapter/express'
|
|
50
|
+
*
|
|
51
|
+
* const description: ErrorDescription = describeError(new Error('Boom'))
|
|
52
|
+
* console.log(description) //{errno: 'E_UNKNOWN', errMsg: 'Boom'}
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function describeError(error: unknown): ErrorDescription;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { Container, Provider, type IBaseObjectConstructor } from '@lakutata/core';
|
|
2
|
+
import type { CLIContext } from '../context/CLIContext.js';
|
|
3
|
+
import type { HTTPContext } from '../context/HTTPContext.js';
|
|
4
|
+
import type { ServiceContext } from '../context/ServiceContext.js';
|
|
5
|
+
import type { CLIActionInfo, HTTPActionInfo, ServiceActionInfo } from '../Entrypoint.js';
|
|
6
|
+
import type { BaseContext } from '../context/BaseContext.js';
|
|
7
|
+
import type { ChannelActionInfo } from '../channel/EntrypointAdapter.js';
|
|
8
|
+
/**
|
|
9
|
+
* A request to a controller action, as the middlewares receive it.
|
|
10
|
+
*/
|
|
11
|
+
export interface ActionInvocation {
|
|
12
|
+
/**
|
|
13
|
+
* The request's context; its `data` is the action's input before validation (a middleware may change it).
|
|
14
|
+
*/
|
|
15
|
+
readonly context: CLIContext | HTTPContext | ServiceContext | BaseContext;
|
|
16
|
+
/**
|
|
17
|
+
* The requested action's description.
|
|
18
|
+
*/
|
|
19
|
+
readonly action: HTTPActionInfo | CLIActionInfo | ServiceActionInfo | ChannelActionInfo;
|
|
20
|
+
/**
|
|
21
|
+
* The parameters taken from the request's address (such as route parameters), merged over the data into the
|
|
22
|
+
* input.
|
|
23
|
+
*/
|
|
24
|
+
readonly params?: Record<string, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* The request's container, destroyed when the request ends: the controller and the middleware classes are
|
|
27
|
+
* created in it.
|
|
28
|
+
*/
|
|
29
|
+
readonly container: Container;
|
|
30
|
+
/**
|
|
31
|
+
* Aborts when the request is aborted (its client gone, the entrypoint stopping).
|
|
32
|
+
*/
|
|
33
|
+
readonly signal?: AbortSignal;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Run the rest of the pipeline: the next middlewares, then the input validation, the access control and the action.
|
|
37
|
+
* It may be called once per middleware; a second call rejects with a `MiddlewareNextCalledException`.
|
|
38
|
+
* @returns The action's result, as the next middlewares return it.
|
|
39
|
+
*/
|
|
40
|
+
export type Next = () => Promise<unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* A middleware function: it runs around the rest of the pipeline (see {@link Middleware.handle}).
|
|
43
|
+
* @param invocation The request.
|
|
44
|
+
* @param next Runs the rest of the pipeline.
|
|
45
|
+
* @returns The result given to the previous middleware (finally, to the adapter).
|
|
46
|
+
*/
|
|
47
|
+
export type MiddlewareHandler = (invocation: ActionInvocation, next: Next) => Promise<unknown>;
|
|
48
|
+
/**
|
|
49
|
+
* A middleware class: it runs around the actions, created in each request's container (its dependencies are
|
|
50
|
+
* injected). Give it, or a {@link MiddlewareHandler} function, to the entrypoint's `middlewares` option (every
|
|
51
|
+
* action), an adapter's `middlewares` option (its requests), `@UseMiddlewares` (a controller class or a method) or an
|
|
52
|
+
* action's `middlewares` option. They run in that order: the entrypoint's, the adapter's, the controller parents'
|
|
53
|
+
* then the controller's, the action option's, then the method's.
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* import {Application} from 'lakutata'
|
|
57
|
+
* import {buildEntrypoints, Controller, Middleware, type ActionInvocation, type Next} from 'lakutata/com/entrypoint'
|
|
58
|
+
* import {GET, UseMiddlewares} from 'lakutata/decorator/ctrl'
|
|
59
|
+
*
|
|
60
|
+
* //Log the duration of each request
|
|
61
|
+
* class Timing extends Middleware {
|
|
62
|
+
* public async handle(invocation: ActionInvocation, next: Next): Promise<unknown> {
|
|
63
|
+
* const start: number = Date.now()
|
|
64
|
+
* try {
|
|
65
|
+
* return await next()
|
|
66
|
+
* } finally {
|
|
67
|
+
* console.log(`${invocation.action.name}: ${Date.now() - start}ms`)
|
|
68
|
+
* }
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* @UseMiddlewares(async (invocation: ActionInvocation, next: Next): Promise<unknown> => {
|
|
73
|
+
* //Short-circuit: the action does not run
|
|
74
|
+
* if (invocation.context.data.maintenance) return {error: 'maintenance'}
|
|
75
|
+
* return next()
|
|
76
|
+
* })
|
|
77
|
+
* class StatusController extends Controller {
|
|
78
|
+
* @GET('/status')
|
|
79
|
+
* public async status(): Promise<string> {
|
|
80
|
+
* return 'ok'
|
|
81
|
+
* }
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* Application.run(() => ({
|
|
85
|
+
* id: 'status.app',
|
|
86
|
+
* name: 'Status',
|
|
87
|
+
* components: {
|
|
88
|
+
* entrypoint: buildEntrypoints({
|
|
89
|
+
* controllers: [StatusController],
|
|
90
|
+
* middlewares: [Timing]
|
|
91
|
+
* })
|
|
92
|
+
* }
|
|
93
|
+
* }))
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare abstract class Middleware extends Provider {
|
|
97
|
+
/**
|
|
98
|
+
* Handle a request: call `next()` to continue the pipeline and return its result (changed or not), or return
|
|
99
|
+
* without calling it to answer instead of the action. A thrown error fails the request.
|
|
100
|
+
* @param invocation The request.
|
|
101
|
+
* @param next Runs the rest of the pipeline; once at most.
|
|
102
|
+
* @returns The result given to the previous middleware (finally, to the adapter).
|
|
103
|
+
*/
|
|
104
|
+
abstract handle(invocation: ActionInvocation, next: Next): Promise<unknown>;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A middleware: a {@link Middleware} subclass, created in each request's container, or a {@link MiddlewareHandler}
|
|
108
|
+
* function. Any other value (a class not extending `Middleware` included) fails with an `InvalidMiddlewareException`.
|
|
109
|
+
*/
|
|
110
|
+
export type MiddlewareDefinition = IBaseObjectConstructor<Middleware> | MiddlewareHandler;
|
|
111
|
+
export type InvocationRunner = (invocation: ActionInvocation) => Promise<unknown>;
|
|
112
|
+
/**
|
|
113
|
+
* Whether a middleware is a middleware class
|
|
114
|
+
* @param middleware
|
|
115
|
+
*/
|
|
116
|
+
export declare function isMiddlewareClass(middleware: MiddlewareDefinition): middleware is IBaseObjectConstructor<Middleware>;
|
|
117
|
+
/**
|
|
118
|
+
* Check middleware definitions: middleware classes or functions
|
|
119
|
+
* @param middlewares
|
|
120
|
+
*/
|
|
121
|
+
export declare function validateMiddlewares(middlewares: unknown[]): MiddlewareDefinition[];
|
|
122
|
+
/**
|
|
123
|
+
* Add middlewares to a controller class or an action method, the middlewares of each decorator run in their order,
|
|
124
|
+
* the decorators from top to bottom
|
|
125
|
+
* @param target
|
|
126
|
+
* @param propertyKey
|
|
127
|
+
* @param middlewares
|
|
128
|
+
*/
|
|
129
|
+
export declare function addMiddlewares(target: object, propertyKey: string | symbol | undefined, middlewares: MiddlewareDefinition[]): void;
|
|
130
|
+
/**
|
|
131
|
+
* The middlewares of a controller class, the ones of its parent classes first
|
|
132
|
+
* @param controller
|
|
133
|
+
*/
|
|
134
|
+
export declare function getClassMiddlewares(controller: Function): MiddlewareDefinition[];
|
|
135
|
+
/**
|
|
136
|
+
* The middlewares of an action method, declared on the method in the class hierarchy
|
|
137
|
+
* @param controller
|
|
138
|
+
* @param method
|
|
139
|
+
*/
|
|
140
|
+
export declare function getMethodMiddlewares(controller: Function, method: string | symbol): MiddlewareDefinition[];
|
|
141
|
+
/**
|
|
142
|
+
* Compose middlewares around the innermost runner
|
|
143
|
+
* @param middlewares
|
|
144
|
+
* @param innermost
|
|
145
|
+
*/
|
|
146
|
+
export declare function composeMiddlewares(middlewares: MiddlewareDefinition[], innermost: InvocationRunner): InvocationRunner;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { DTO, type ActionPattern } from '@lakutata/core';
|
|
2
|
+
/**
|
|
3
|
+
* A controller's action prefixes, given to `@Prefix`. The packages of the other channels add their own prefix keys
|
|
4
|
+
* (declaration merging); the keys are kept even when not declared here.
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
8
|
+
* import {CLIAction, GET, Prefix, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
9
|
+
*
|
|
10
|
+
* //GET /users/:id, the command user:get, the pattern {resource: 'user', act: 'get'}
|
|
11
|
+
* @Prefix({route: '/users', command: 'user', pattern: {resource: 'user'}})
|
|
12
|
+
* class UserController extends Controller {
|
|
13
|
+
* @GET('/:id')
|
|
14
|
+
* @CLIAction('get')
|
|
15
|
+
* @ServiceAction({act: 'get'})
|
|
16
|
+
* public async get(input: {id: string}): Promise<{id: string}> {
|
|
17
|
+
* return {id: input.id}
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class PrefixOptions extends DTO {
|
|
23
|
+
/**
|
|
24
|
+
* The path prepended to the HTTP actions' routes, the slashes between them normalized (`/users` + `/:id` =
|
|
25
|
+
* `/users/:id`).
|
|
26
|
+
*/
|
|
27
|
+
route?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The command prepended to the CLI actions' commands, joined by `:` (`user` + `get` = `user:get`; an empty
|
|
30
|
+
* command gives the prefix alone).
|
|
31
|
+
*/
|
|
32
|
+
command?: string;
|
|
33
|
+
/**
|
|
34
|
+
* The pattern merged into the service actions' patterns, deeply (`{resource: 'user'}` + `{act: 'get'}` =
|
|
35
|
+
* `{resource: 'user', act: 'get'}`); a key the prefix and the pattern set to different values fails the
|
|
36
|
+
* entrypoint's initialization with an `InvalidPrefixException`.
|
|
37
|
+
*/
|
|
38
|
+
pattern?: ActionPattern;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set a controller class's prefixes, merged over the ones already set on the class (by the decorators of the other
|
|
42
|
+
* channels). Used by `@Prefix` and by the prefix decorators of the packages providing a channel.
|
|
43
|
+
* @param controller The controller class.
|
|
44
|
+
* @param options The prefixes to set.
|
|
45
|
+
* @throws {Error} When the merged prefixes are invalid (the validation error of {@link PrefixOptions}).
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
49
|
+
* import {setPrefix} from '@lakutata/entrypoint/channel'
|
|
50
|
+
*
|
|
51
|
+
* //A decorator of a "queue" channel prefixing the topics of a controller
|
|
52
|
+
* export function TopicPrefix(topic: string) {
|
|
53
|
+
* return (target: typeof Controller): void => setPrefix(target, {topic: topic})
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function setPrefix(controller: Function, options: PrefixOptions): void;
|
|
58
|
+
/**
|
|
59
|
+
* Get a controller's prefixes: the ones of the class, or else of its nearest parent class declaring them (they are not
|
|
60
|
+
* merged across the hierarchy).
|
|
61
|
+
* @param controller The controller class.
|
|
62
|
+
* @returns The prefixes, `undefined` when neither the class nor its parents declare any.
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
66
|
+
* import {Prefix} from 'lakutata/decorator/ctrl'
|
|
67
|
+
* import {getPrefix} from '@lakutata/entrypoint/channel'
|
|
68
|
+
*
|
|
69
|
+
* @Prefix({route: '/users'})
|
|
70
|
+
* class UserController extends Controller {
|
|
71
|
+
* }
|
|
72
|
+
*
|
|
73
|
+
* class AdminController extends UserController {
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* console.log(getPrefix(AdminController)?.route) //'/users'
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function getPrefix(controller: Function): PrefixOptions | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Join a route prefix and a route
|
|
82
|
+
* @param prefix
|
|
83
|
+
* @param route
|
|
84
|
+
*/
|
|
85
|
+
export declare function prefixRoute(prefix: string, route: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Join a command prefix and a command
|
|
88
|
+
* @param prefix
|
|
89
|
+
* @param command
|
|
90
|
+
*/
|
|
91
|
+
export declare function prefixCommand(prefix: string, command: string): string;
|
|
92
|
+
/**
|
|
93
|
+
* Merge a pattern prefix into a pattern, a key cannot have different values
|
|
94
|
+
* @param prefix
|
|
95
|
+
* @param pattern
|
|
96
|
+
* @param path
|
|
97
|
+
*/
|
|
98
|
+
export declare function prefixPattern(prefix: ActionPattern, pattern: ActionPattern, path?: string): ActionPattern;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
import { ActionResult } from './ActionResult.js';
|
|
3
|
+
/**
|
|
4
|
+
* A result with a status and headers: the HTTP adapters set them on the response and send the data with their
|
|
5
|
+
* responder; the CLI adapter outputs the data. Build it with `Result.status()`.
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import {Controller, Result, type StatusResult} from 'lakutata/com/entrypoint'
|
|
9
|
+
* import {POST} from 'lakutata/decorator/ctrl'
|
|
10
|
+
*
|
|
11
|
+
* class OrderController extends Controller {
|
|
12
|
+
* //201 Created, with the location of the order
|
|
13
|
+
* @POST('/orders')
|
|
14
|
+
* public async create(): Promise<StatusResult> {
|
|
15
|
+
* return Result.status(201, {id: 42}, {Location: '/orders/42'})
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class StatusResult extends ActionResult {
|
|
21
|
+
readonly status: number;
|
|
22
|
+
protected readonly payload?: unknown | undefined;
|
|
23
|
+
readonly headers: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a result with a status and headers.
|
|
26
|
+
* @param status The HTTP status.
|
|
27
|
+
* @param payload The data sent.
|
|
28
|
+
* @param headers The response headers.
|
|
29
|
+
*/
|
|
30
|
+
constructor(status: number, payload?: unknown | undefined, headers?: Record<string, string>);
|
|
31
|
+
/**
|
|
32
|
+
* The data sent with the status.
|
|
33
|
+
*/
|
|
34
|
+
get data(): unknown;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* How a {@link FileResult} is sent.
|
|
38
|
+
*/
|
|
39
|
+
export type FileResultOptions = {
|
|
40
|
+
/**
|
|
41
|
+
* The content type, inferred from the file's or the attachment's name when omitted.
|
|
42
|
+
*/
|
|
43
|
+
contentType?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The name to send the file under, as an attachment (`Content-Disposition: attachment`); it is displayed inline
|
|
46
|
+
* when omitted.
|
|
47
|
+
*/
|
|
48
|
+
filename?: string;
|
|
49
|
+
/**
|
|
50
|
+
* The content's entity tag, sent quoted in `ETag`: a request whose `If-None-Match` matches it gets a 304 response
|
|
51
|
+
* without content.
|
|
52
|
+
*/
|
|
53
|
+
etag?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Other response headers.
|
|
56
|
+
*/
|
|
57
|
+
headers?: Record<string, string>;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A file: a path, a buffer or a stream. The HTTP adapters send it with its options; the CLI adapter writes its
|
|
61
|
+
* content to stdout. Build it with `Result.file()`.
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import {Readable} from 'node:stream'
|
|
65
|
+
* import {Controller, Result, type FileResult} from 'lakutata/com/entrypoint'
|
|
66
|
+
* import {GET} from 'lakutata/decorator/ctrl'
|
|
67
|
+
*
|
|
68
|
+
* class ReportController extends Controller {
|
|
69
|
+
* //A file on disk, downloaded as report.pdf
|
|
70
|
+
* @GET('/report')
|
|
71
|
+
* public async report(): Promise<FileResult> {
|
|
72
|
+
* return Result.file('./reports/latest.pdf', {filename: 'report.pdf', etag: 'v1'})
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* //A stream, with its content type
|
|
76
|
+
* @GET('/export')
|
|
77
|
+
* public async export(): Promise<FileResult> {
|
|
78
|
+
* return Result.file(Readable.from(['id,name\n', '1,Ada\n']), {contentType: 'text/csv'})
|
|
79
|
+
* }
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare class FileResult extends ActionResult {
|
|
84
|
+
readonly source: string | Buffer | Readable;
|
|
85
|
+
readonly options: FileResultOptions;
|
|
86
|
+
/**
|
|
87
|
+
* Create a file result.
|
|
88
|
+
* @param source The file's path (resolved from the working directory), its content, or a stream of its content.
|
|
89
|
+
* @param options How the file is sent.
|
|
90
|
+
*/
|
|
91
|
+
constructor(source: string | Buffer | Readable, options?: FileResultOptions);
|
|
92
|
+
/**
|
|
93
|
+
* The file's source.
|
|
94
|
+
*/
|
|
95
|
+
get data(): unknown;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Send an event of a stream; nothing is sent once the client has left.
|
|
99
|
+
* @param data The event's data, serialized to JSON unless it is a string.
|
|
100
|
+
* @param event The event's name; the clients' default event (`message`) when omitted.
|
|
101
|
+
* @param id The event's id, which the client sends back as `Last-Event-ID` when it reconnects.
|
|
102
|
+
*/
|
|
103
|
+
export type SendEvent = (data: unknown, event?: string, id?: string) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Produce the events of a stream. The stream ends when the producer settles (an error ends it too, without other
|
|
106
|
+
* notice); when the client leaves, the signal aborts and the producer should return.
|
|
107
|
+
* @param send Sends an event.
|
|
108
|
+
* @param signal Aborts when the client leaves or the adapter stops.
|
|
109
|
+
*/
|
|
110
|
+
export type EventsProducer = (send: SendEvent, signal: AbortSignal) => Promise<void> | void;
|
|
111
|
+
/**
|
|
112
|
+
* A stream of events: Server-Sent Events for the HTTP adapters, each event's data written as a line by the CLI
|
|
113
|
+
* adapter. Build it with `Result.events()`.
|
|
114
|
+
*
|
|
115
|
+
* The producer runs after the action returned, once the request's container is destroyed: it must only use objects
|
|
116
|
+
* living longer than the request (the components), not the controller's request-scoped dependencies.
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* import {Controller, Result, type EventsResult} from 'lakutata/com/entrypoint'
|
|
120
|
+
* import {GET} from 'lakutata/decorator/ctrl'
|
|
121
|
+
*
|
|
122
|
+
* class ClockController extends Controller {
|
|
123
|
+
* //The time every second until the client leaves
|
|
124
|
+
* @GET('/clock')
|
|
125
|
+
* public async clock(): Promise<EventsResult> {
|
|
126
|
+
* return Result.events(async (send, signal): Promise<void> => {
|
|
127
|
+
* while (!signal.aborted) {
|
|
128
|
+
* send({now: new Date().toISOString()}, 'tick')
|
|
129
|
+
* await new Promise((resolve): unknown => setTimeout(resolve, 1000))
|
|
130
|
+
* }
|
|
131
|
+
* })
|
|
132
|
+
* }
|
|
133
|
+
* }
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare class EventsResult extends ActionResult {
|
|
137
|
+
readonly producer: EventsProducer;
|
|
138
|
+
/**
|
|
139
|
+
* Create an event stream result.
|
|
140
|
+
* @param producer Produces the events.
|
|
141
|
+
*/
|
|
142
|
+
constructor(producer: EventsProducer);
|
|
143
|
+
/**
|
|
144
|
+
* Always `undefined`: an event stream has no data of its own.
|
|
145
|
+
*/
|
|
146
|
+
get data(): unknown;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Build the results an action returns to describe its output beyond its data.
|
|
150
|
+
*/
|
|
151
|
+
export declare const Result: {
|
|
152
|
+
/**
|
|
153
|
+
* Build a result with a status and headers.
|
|
154
|
+
* @param status The HTTP status.
|
|
155
|
+
* @param data The data sent.
|
|
156
|
+
* @param headers The response headers.
|
|
157
|
+
* @returns The {@link StatusResult}.
|
|
158
|
+
*/
|
|
159
|
+
status: (status: number, data?: unknown, headers?: Record<string, string>) => StatusResult;
|
|
160
|
+
/**
|
|
161
|
+
* Build a file result.
|
|
162
|
+
* @param source The file's path (resolved from the working directory), its content, or a stream of its content.
|
|
163
|
+
* @param options How the file is sent.
|
|
164
|
+
* @returns The {@link FileResult}.
|
|
165
|
+
*/
|
|
166
|
+
file: (source: string | Buffer | Readable, options?: FileResultOptions) => FileResult;
|
|
167
|
+
/**
|
|
168
|
+
* Build an event stream result (Server-Sent Events for HTTP).
|
|
169
|
+
* @param producer Produces the events, after the action returned.
|
|
170
|
+
* @returns The {@link EventsResult}.
|
|
171
|
+
*/
|
|
172
|
+
events: (producer: EventsProducer) => EventsResult;
|
|
173
|
+
};
|