@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,100 @@
|
|
|
1
|
+
import { InvalidChannelException } from '../exceptions/InvalidChannelException.js';
|
|
2
|
+
const channels = new Map();
|
|
3
|
+
/**
|
|
4
|
+
* Define a channel. A package providing a channel defines it when it is loaded; defining the same definition object
|
|
5
|
+
* again does nothing.
|
|
6
|
+
* @param definition The channel's definition.
|
|
7
|
+
* @returns The same definition.
|
|
8
|
+
* @throws {InvalidChannelException} When another definition already has the name.
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import {Controller, ControllerActionNotFoundException, type BaseContext, type ControllerProperty} from 'lakutata/com/entrypoint'
|
|
12
|
+
* import {defineChannel, registerControllerAction, type ChannelEntry} from '@lakutata/entrypoint/channel'
|
|
13
|
+
* import {FlexibleDTO} from 'lakutata/dtos'
|
|
14
|
+
*
|
|
15
|
+
* //A channel of the messages of a queue, addressed by their topic
|
|
16
|
+
* export const QueueChannel = defineChannel({
|
|
17
|
+
* name: 'queue',
|
|
18
|
+
* kind: 'delivery',
|
|
19
|
+
* contextType: 'QUEUE',
|
|
20
|
+
* identify: (address): string => address.topic,
|
|
21
|
+
* describe: (address): Record<string, unknown> => ({topic: address.topic}),
|
|
22
|
+
* createMatcher: (entries: ChannelEntry[]) => ({
|
|
23
|
+
* match: (context: BaseContext) => {
|
|
24
|
+
* const entry: ChannelEntry | undefined = entries.find(candidate => candidate.details.pattern.topic === context.topic)
|
|
25
|
+
* return entry ? {entry: entry} : undefined
|
|
26
|
+
* }
|
|
27
|
+
* }),
|
|
28
|
+
* notFound: (context: BaseContext): Error => new ControllerActionNotFoundException('No action handles the topic {topic}', {topic: context.topic})
|
|
29
|
+
* })
|
|
30
|
+
*
|
|
31
|
+
* //The decorator declaring the actions of the channel
|
|
32
|
+
* export function OnMessage(topic: string) {
|
|
33
|
+
* return <ClassPrototype extends Controller>(target: ClassPrototype, propertyKey: ControllerProperty<ClassPrototype>): void => {
|
|
34
|
+
* registerControllerAction(QueueChannel, target, propertyKey, {topic: topic}, FlexibleDTO, {})
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function defineChannel(definition) {
|
|
40
|
+
const defined = channels.get(definition.name);
|
|
41
|
+
if (defined && defined !== definition)
|
|
42
|
+
throw new InvalidChannelException('The channel "{0}" is already defined', [definition.name]);
|
|
43
|
+
channels.set(definition.name, definition);
|
|
44
|
+
return definition;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get a defined channel.
|
|
48
|
+
* @param name The channel's name.
|
|
49
|
+
* @returns The channel's definition.
|
|
50
|
+
* @throws {InvalidChannelException} When no channel has the name.
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import {getChannel, type ChannelDefinition} from '@lakutata/entrypoint/channel'
|
|
54
|
+
*
|
|
55
|
+
* const http: ChannelDefinition = getChannel('http')
|
|
56
|
+
* console.log(http.kind, http.contextType) //request HTTP
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function getChannel(name) {
|
|
60
|
+
const definition = channels.get(name);
|
|
61
|
+
if (!definition)
|
|
62
|
+
throw new InvalidChannelException('The channel "{0}" is not defined', [name]);
|
|
63
|
+
return definition;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Whether a channel is defined.
|
|
67
|
+
* @param name The channel's name.
|
|
68
|
+
* @returns `true` when a channel has the name.
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* import {hasChannel} from '@lakutata/entrypoint/channel'
|
|
72
|
+
*
|
|
73
|
+
* console.log(hasChannel('schedule')) //true
|
|
74
|
+
* console.log(hasChannel('queue')) //false until a package defines it
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export function hasChannel(name) {
|
|
78
|
+
return channels.has(name);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Find the channel whose requests have a context type.
|
|
82
|
+
* @param contextType The `type` of a request context (`HTTP`, `CLI`…).
|
|
83
|
+
* @returns The first channel defined with the context type, `undefined` when there is none.
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import {ContextType, type BaseContext} from 'lakutata/com/entrypoint'
|
|
87
|
+
* import {getChannelByContextType} from '@lakutata/entrypoint/channel'
|
|
88
|
+
*
|
|
89
|
+
* declare const context: BaseContext
|
|
90
|
+
*
|
|
91
|
+
* console.log(getChannelByContextType(ContextType.SERVICE)?.name) //service
|
|
92
|
+
* console.log(getChannelByContextType(context.type)?.name)
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function getChannelByContextType(contextType) {
|
|
96
|
+
for (const definition of channels.values())
|
|
97
|
+
if (definition.contextType === contextType)
|
|
98
|
+
return definition;
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a value is an adapter: an object with a string `channel` and a `start` function.
|
|
3
|
+
* @param value The value to check.
|
|
4
|
+
* @returns `true` when the value is an adapter.
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import {expressHTTPEntrypoint} from 'lakutata/adapter/express'
|
|
8
|
+
* import {isEntrypointAdapter} from '@lakutata/entrypoint/channel'
|
|
9
|
+
*
|
|
10
|
+
* console.log(isEntrypointAdapter(expressHTTPEntrypoint())) //true
|
|
11
|
+
* console.log(isEntrypointAdapter({channel: 'http'})) //false: no start function
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export function isEntrypointAdapter(value) {
|
|
15
|
+
return !!value && typeof value === 'object' && typeof value.channel === 'string' && typeof value.start === 'function';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Map the commands of CLI actions to the JSON schemas of their input, as a CLI adapter builds its commands from.
|
|
19
|
+
* @param actions The CLI channel's actions ({@link ChannelRuntime.actions} of a CLI adapter).
|
|
20
|
+
* @returns Each command mapped to its input's JSON schema; an action without command is mapped under `undefined`.
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import {type CLIContext, type EntrypointAdapter} from 'lakutata/com/entrypoint'
|
|
24
|
+
* import {commandMap} from '@lakutata/entrypoint/channel'
|
|
25
|
+
*
|
|
26
|
+
* //A CLI adapter printing the commands and their options
|
|
27
|
+
* export const HelpCLIEntrypoint: EntrypointAdapter<CLIContext> = {
|
|
28
|
+
* channel: 'cli',
|
|
29
|
+
* start: (runtime): void => {
|
|
30
|
+
* for (const [command, schema] of commandMap(runtime.actions)) {
|
|
31
|
+
* console.log(command, Object.keys(schema.properties ?? {}).join(' '))
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function commandMap(actions) {
|
|
38
|
+
return new Map(actions.map((action) => [action.command, action.jsonSchema]));
|
|
39
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { DTO } from '@lakutata/core';
|
|
11
|
+
import { Expect, IndexSignature } from '@lakutata/core/decorator/dto';
|
|
12
|
+
/**
|
|
13
|
+
* The kinds of the request contexts of the built-in channels, held by `BaseContext.type`.
|
|
14
|
+
*/
|
|
15
|
+
export var ContextType;
|
|
16
|
+
(function (ContextType) {
|
|
17
|
+
/**
|
|
18
|
+
* A command of a CLI adapter (`CLIContext`).
|
|
19
|
+
*/
|
|
20
|
+
ContextType["CLI"] = "CLI";
|
|
21
|
+
/**
|
|
22
|
+
* A request of an HTTP adapter (`HTTPContext`).
|
|
23
|
+
*/
|
|
24
|
+
ContextType["HTTP"] = "HTTP";
|
|
25
|
+
/**
|
|
26
|
+
* A message of a service adapter: Socket.IO, JSON-RPC, Electron IPC, HTTP service (`ServiceContext`).
|
|
27
|
+
*/
|
|
28
|
+
ContextType["SERVICE"] = "SERVICE";
|
|
29
|
+
/**
|
|
30
|
+
* A run of a scheduled action (`ScheduleContext`).
|
|
31
|
+
*/
|
|
32
|
+
ContextType["SCHEDULE"] = "SCHEDULE";
|
|
33
|
+
})(ContextType || (ContextType = {}));
|
|
34
|
+
/**
|
|
35
|
+
* The context of a request: what an adapter knows about it, given to the controller (`this.context`), the middlewares
|
|
36
|
+
* (`invocation.context`) and the access control rules. Each channel has its subclass (`HTTPContext`, `CLIContext`,
|
|
37
|
+
* `ServiceContext`, `ScheduleContext`); test it with `instanceof` in an action serving several channels. A context is
|
|
38
|
+
* a DTO: its properties are validated when it is created and when they change; it also holds the extra properties
|
|
39
|
+
* given by its adapter (the Socket.IO socket, the JSON-RPC request), read by the adapters' helpers
|
|
40
|
+
* (`socketOfContext`…). The adapters create the contexts: an application only reads them.
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import {Controller, CLIContext, HTTPContext, ServiceContext} from 'lakutata/com/entrypoint'
|
|
44
|
+
* import {CLIAction, GET, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
45
|
+
*
|
|
46
|
+
* class VersionController extends Controller {
|
|
47
|
+
* //One action for the three channels: the context tells them apart
|
|
48
|
+
* @GET('/version')
|
|
49
|
+
* @CLIAction('version')
|
|
50
|
+
* @ServiceAction({act: 'version'})
|
|
51
|
+
* public async version(): Promise<{ version: string, via: string }> {
|
|
52
|
+
* let via: string = this.context.type
|
|
53
|
+
* if (this.context instanceof HTTPContext) via = `${this.context.method.toUpperCase()} ${this.context.route}`
|
|
54
|
+
* if (this.context instanceof CLIContext) via = `the command ${this.context.command}`
|
|
55
|
+
* if (this.context instanceof ServiceContext) via = `the client ${this.context.clientId ?? 'unknown'}`
|
|
56
|
+
* return {version: '1.0.0', via: via}
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
let BaseContext = class BaseContext extends DTO {
|
|
62
|
+
/**
|
|
63
|
+
* Create a context, validating its properties.
|
|
64
|
+
* @param params The properties of the context: its `type`, its `data`, and those of its channel.
|
|
65
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
66
|
+
*/
|
|
67
|
+
constructor(params) {
|
|
68
|
+
super(params);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
__decorate([
|
|
72
|
+
Expect(DTO.String().required()),
|
|
73
|
+
__metadata("design:type", String)
|
|
74
|
+
], BaseContext.prototype, "type", void 0);
|
|
75
|
+
__decorate([
|
|
76
|
+
Expect(DTO.Object().pattern(DTO.String(), DTO.Any()).required()),
|
|
77
|
+
__metadata("design:type", Object)
|
|
78
|
+
], BaseContext.prototype, "data", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
Expect(DTO.String().optional()),
|
|
81
|
+
__metadata("design:type", String)
|
|
82
|
+
], BaseContext.prototype, "locale", void 0);
|
|
83
|
+
BaseContext = __decorate([
|
|
84
|
+
IndexSignature(DTO.Any()),
|
|
85
|
+
__metadata("design:paramtypes", [Object])
|
|
86
|
+
], BaseContext);
|
|
87
|
+
export { BaseContext };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { BaseContext, ContextType } from './BaseContext.js';
|
|
11
|
+
import { Expect } from '@lakutata/core/decorator/dto';
|
|
12
|
+
import { DTO } from '@lakutata/core';
|
|
13
|
+
/**
|
|
14
|
+
* The context of a command run by a CLI adapter (`commanderCLIEntrypoint`): `this.context` of a controller action
|
|
15
|
+
* declared with `@CLIAction`, when it runs as a command. Its `data` holds the positional arguments and the options of
|
|
16
|
+
* the command, before their validation.
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import {Controller, CLIContext} from 'lakutata/com/entrypoint'
|
|
20
|
+
* import {CLIAction} from 'lakutata/decorator/ctrl'
|
|
21
|
+
*
|
|
22
|
+
* class CacheController extends Controller {
|
|
23
|
+
* //"app cache clear" prints "cache clear: done"
|
|
24
|
+
* @CLIAction('cache clear')
|
|
25
|
+
* public async clear(): Promise<string> {
|
|
26
|
+
* const command: string = this.context instanceof CLIContext ? this.context.command : 'unknown'
|
|
27
|
+
* return `${command}: done`
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class CLIContext extends BaseContext {
|
|
33
|
+
/**
|
|
34
|
+
* Create the context of a command, validating its properties.
|
|
35
|
+
* @param params The command and its data.
|
|
36
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
37
|
+
*/
|
|
38
|
+
constructor(params) {
|
|
39
|
+
super(params);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
__decorate([
|
|
43
|
+
Expect(DTO.String().valid(ContextType.CLI).default(ContextType.CLI)),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], CLIContext.prototype, "type", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
Expect(DTO.String().required()),
|
|
48
|
+
__metadata("design:type", String)
|
|
49
|
+
], CLIContext.prototype, "command", void 0);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { DTO } from '@lakutata/core';
|
|
11
|
+
import { Expect } from '@lakutata/core/decorator/dto';
|
|
12
|
+
import { BaseContext, ContextType } from './BaseContext.js';
|
|
13
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
14
|
+
/**
|
|
15
|
+
* The context of a request served by an HTTP adapter (`expressHTTPEntrypoint`, `fastifyHTTPEntrypoint`):
|
|
16
|
+
* `this.context` of a controller action declared with `@HTTPAction` or `@GET`…, when it runs for an HTTP request. It
|
|
17
|
+
* gives the Node.js request and response, to read or set headers; once an action has sent the response itself (its
|
|
18
|
+
* headers sent), the adapter writes neither its value nor its error.
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import {Controller, HTTPContext} from 'lakutata/com/entrypoint'
|
|
22
|
+
* import {GET} from 'lakutata/decorator/ctrl'
|
|
23
|
+
*
|
|
24
|
+
* class AgentController extends Controller {
|
|
25
|
+
* //GET /agent: answered with the header Cache-Control and the JSON {"agent": "curl/8.0", "route": "/agent"}
|
|
26
|
+
* @GET('/agent')
|
|
27
|
+
* public async agent(): Promise<{ agent: string, route: string }> {
|
|
28
|
+
* if (!(this.context instanceof HTTPContext)) return {agent: '', route: ''}
|
|
29
|
+
* this.context.response.setHeader('Cache-Control', 'no-store')
|
|
30
|
+
* return {agent: this.context.request.headers['user-agent'] ?? '', route: this.context.route}
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export class HTTPContext extends BaseContext {
|
|
36
|
+
/**
|
|
37
|
+
* Create the context of an HTTP request, validating its properties.
|
|
38
|
+
* @param params The route, the method, the request, the response and the data of the request.
|
|
39
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
40
|
+
*/
|
|
41
|
+
constructor(params) {
|
|
42
|
+
super(params);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
__decorate([
|
|
46
|
+
Expect(DTO.String().valid(ContextType.HTTP).default(ContextType.HTTP)),
|
|
47
|
+
__metadata("design:type", String)
|
|
48
|
+
], HTTPContext.prototype, "type", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
Expect(DTO.String().required()),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], HTTPContext.prototype, "route", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
Expect(DTO.String().required()),
|
|
55
|
+
__metadata("design:type", String)
|
|
56
|
+
], HTTPContext.prototype, "method", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
Expect(DTO.InstanceOf(IncomingMessage)),
|
|
59
|
+
__metadata("design:type", IncomingMessage
|
|
60
|
+
/**
|
|
61
|
+
* The Node.js response (the raw reply of Fastify, the Express response).
|
|
62
|
+
*/
|
|
63
|
+
)
|
|
64
|
+
], HTTPContext.prototype, "request", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
Expect(DTO.InstanceOf(ServerResponse)),
|
|
67
|
+
__metadata("design:type", ServerResponse
|
|
68
|
+
/**
|
|
69
|
+
* Create the context of an HTTP request, validating its properties.
|
|
70
|
+
* @param params The route, the method, the request, the response and the data of the request.
|
|
71
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
72
|
+
*/
|
|
73
|
+
)
|
|
74
|
+
], HTTPContext.prototype, "response", void 0);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { BaseContext, ContextType } from './BaseContext.js';
|
|
11
|
+
import { Expect } from '@lakutata/core/decorator/dto';
|
|
12
|
+
import { DTO } from '@lakutata/core';
|
|
13
|
+
/**
|
|
14
|
+
* The context of a run of a scheduled action (`scheduleEntrypoint`): `this.context` of a controller action declared
|
|
15
|
+
* with `@Schedule`, when the schedule runs it. Its `data` is an empty object.
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import {Controller, ScheduleContext} from 'lakutata/com/entrypoint'
|
|
19
|
+
* import {Schedule} from 'lakutata/decorator/ctrl'
|
|
20
|
+
*
|
|
21
|
+
* class ReportController extends Controller {
|
|
22
|
+
* //Every hour: logs "run 1 of every 1h, planned at …", then "run 2…"
|
|
23
|
+
* @Schedule('1h')
|
|
24
|
+
* public async hourly(): Promise<void> {
|
|
25
|
+
* if (!(this.context instanceof ScheduleContext)) return
|
|
26
|
+
* const delay: number = Date.now() - this.context.scheduledAt.getTime()
|
|
27
|
+
* console.log(`run ${this.context.run} of ${this.context.schedule}, planned at ${this.context.scheduledAt.toISOString()} (${delay}ms late)`)
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class ScheduleContext extends BaseContext {
|
|
33
|
+
/**
|
|
34
|
+
* Create the context of a scheduled run, validating its properties.
|
|
35
|
+
* @param params The schedule, the planned time, the run number and the data of the run.
|
|
36
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
37
|
+
*/
|
|
38
|
+
constructor(params) {
|
|
39
|
+
super(params);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
__decorate([
|
|
43
|
+
Expect(DTO.String().valid(ContextType.SCHEDULE).default(ContextType.SCHEDULE)),
|
|
44
|
+
__metadata("design:type", String)
|
|
45
|
+
], ScheduleContext.prototype, "type", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
Expect(DTO.String().required()),
|
|
48
|
+
__metadata("design:type", String)
|
|
49
|
+
], ScheduleContext.prototype, "schedule", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
Expect(DTO.Date().required()),
|
|
52
|
+
__metadata("design:type", Date
|
|
53
|
+
/**
|
|
54
|
+
* The number of the run in this process, from 1, counting the runs started (not the skipped ones).
|
|
55
|
+
*/
|
|
56
|
+
)
|
|
57
|
+
], ScheduleContext.prototype, "scheduledAt", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
Expect(DTO.Number().integer().min(1).required()),
|
|
60
|
+
__metadata("design:type", Number)
|
|
61
|
+
], ScheduleContext.prototype, "run", void 0);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { cloneDeep } from '@lakutata/utils';
|
|
11
|
+
import { DTO } from '@lakutata/core';
|
|
12
|
+
import { Expect } from '@lakutata/core/decorator/dto';
|
|
13
|
+
import { BaseContext, ContextType } from './BaseContext.js';
|
|
14
|
+
/**
|
|
15
|
+
* The context of a message received by a service adapter (`socketIOServiceEntrypoint`, `jsonRPCServiceEntrypoint`,
|
|
16
|
+
* `electronIPCServiceEntrypoint`, `httpServiceEntrypoint`): `this.context` of a controller action declared with
|
|
17
|
+
* `@ServiceAction`, when it runs for a message. Its `input` is the whole message, matched against the actions'
|
|
18
|
+
* patterns; its `data` is the message without the keys of the matched pattern. The adapters' helpers give the
|
|
19
|
+
* transport objects (`socketOfContext`, `httpRequestOfContext`, `ipcEventOfContext`, `jsonRPCRequestOfContext`).
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import {Controller, ServiceContext} from 'lakutata/com/entrypoint'
|
|
23
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
24
|
+
*
|
|
25
|
+
* class ChatController extends Controller {
|
|
26
|
+
* //The message {act: 'join', room: 'lobby'}: answered with the payload {room: 'lobby', client: <the client id>}
|
|
27
|
+
* @ServiceAction({act: 'join'})
|
|
28
|
+
* public async join(input: { room: string }): Promise<{ room: string, client?: string }> {
|
|
29
|
+
* const client: string | undefined = this.context instanceof ServiceContext ? this.context.clientId : undefined
|
|
30
|
+
* return {room: input.room, client: client}
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export class ServiceContext extends BaseContext {
|
|
36
|
+
/**
|
|
37
|
+
* Create the context of a service message, validating its properties; `input` is set to a copy of `data`.
|
|
38
|
+
* @param params The message (`data`), its client id, and the adapter's extra properties.
|
|
39
|
+
* @throws {InvalidValueException} When a property is invalid or a required one is missing.
|
|
40
|
+
*/
|
|
41
|
+
constructor(params) {
|
|
42
|
+
//A deep copy: the pattern keys removed from the data once matched, nested ones included, stay in the input
|
|
43
|
+
params = { ...params, input: cloneDeep(params.data ?? {}) };
|
|
44
|
+
super(params);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
__decorate([
|
|
48
|
+
Expect(DTO.String().valid(ContextType.SERVICE).default(ContextType.SERVICE)),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], ServiceContext.prototype, "type", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
Expect(DTO.Object().pattern(DTO.String(), DTO.Any()).required()),
|
|
53
|
+
__metadata("design:type", Object)
|
|
54
|
+
], ServiceContext.prototype, "input", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
Expect(DTO.String().optional()),
|
|
57
|
+
__metadata("design:type", String)
|
|
58
|
+
], ServiceContext.prototype, "clientId", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { registerCLIAction } from '../lib/ControllerEntrypoint.js';
|
|
2
|
+
import { ActionOptions } from '../lib/ActionOptions.js';
|
|
3
|
+
import { getActionDTOAndOptions } from '../lib/GetActionDTOAndOptions.js';
|
|
4
|
+
export function CLIAction(command, dtoConstructorOrOptions, options) {
|
|
5
|
+
return (target, propertyKey, descriptor) => {
|
|
6
|
+
const [dtoConstructor, actionOptions] = getActionDTOAndOptions(dtoConstructorOrOptions, options);
|
|
7
|
+
registerCLIAction(command, target, propertyKey, dtoConstructor, ActionOptions.validate(actionOptions));
|
|
8
|
+
return descriptor;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { registerHTTPAction } from '../lib/ControllerEntrypoint.js';
|
|
2
|
+
import { getActionDTOAndOptions } from '../lib/GetActionDTOAndOptions.js';
|
|
3
|
+
export function HTTPAction(r, m, dtoConstructorOrOptions, options) {
|
|
4
|
+
return (target, propertyKey, descriptor) => {
|
|
5
|
+
const route = r.toString();
|
|
6
|
+
const methods = Array.isArray(m) ? m : [m];
|
|
7
|
+
const [dtoConstructor, actionOptions] = getActionDTOAndOptions(dtoConstructorOrOptions, options);
|
|
8
|
+
registerHTTPAction(route, methods, target, propertyKey, dtoConstructor, actionOptions);
|
|
9
|
+
return descriptor;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { setPrefix } from '../lib/Prefix.js';
|
|
2
|
+
/**
|
|
3
|
+
* Prefix the addresses of a controller's actions, and of the controllers extending it unless they declare their own
|
|
4
|
+
* prefixes (a subclass's `@Prefix` replaces its parent's, it does not add to it):
|
|
5
|
+
* - `route` is prepended to the routes of the HTTP actions (`'/users'` and `'/:id'` give `'/users/:id'`);
|
|
6
|
+
* - `command` is prepended to the commands of the CLI actions, joined by ":" (`'user'` and `'get'` give `'user:get'`);
|
|
7
|
+
* - `pattern` is merged into the patterns of the service actions (`{resource: 'user'}` and `{act: 'get'}` give
|
|
8
|
+
* `{resource: 'user', act: 'get'}`).
|
|
9
|
+
*
|
|
10
|
+
* A channel without its prefix keeps the addresses as declared; the scheduled actions have none. The prefixes apply when
|
|
11
|
+
* the entrypoint registers the controller, and the prefixed actions are named after the registered controller, so that
|
|
12
|
+
* the controllers sharing a parent have distinct actions. Several `@Prefix` on a class merge their options.
|
|
13
|
+
* @param options The prefixes: `route`, `command` and `pattern`, each optional; the packages of other channels add
|
|
14
|
+
* their own.
|
|
15
|
+
* @returns The class decorator.
|
|
16
|
+
* @throws {InvalidValueException} When the class is declared, if the options are invalid.
|
|
17
|
+
* @throws {InvalidPrefixException} When the entrypoint initializes, if the pattern prefix sets a key that the pattern
|
|
18
|
+
* of an action sets to another value.
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import {DTO} from 'lakutata'
|
|
22
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
23
|
+
* import {CLIAction, GET, Prefix, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
24
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
25
|
+
*
|
|
26
|
+
* class UserIdDTO extends DTO {
|
|
27
|
+
* @Expect(DTO.String().required())
|
|
28
|
+
* public id!: string
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* @Prefix({route: '/users', command: 'user', pattern: {resource: 'user'}})
|
|
32
|
+
* class UserController extends Controller {
|
|
33
|
+
* //GET /users/:id, the command "user:get <id>" and the message {resource: 'user', act: 'get', id: …}
|
|
34
|
+
* @GET('/:id', UserIdDTO)
|
|
35
|
+
* @CLIAction('get <id>', UserIdDTO)
|
|
36
|
+
* @ServiceAction({act: 'get'}, UserIdDTO)
|
|
37
|
+
* public async get(input: UserIdDTO): Promise<{ id: string }> {
|
|
38
|
+
* return {id: input.id}
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function Prefix(options) {
|
|
44
|
+
return (target) => setPrefix(target, options);
|
|
45
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { registerControllerAction } from '../lib/ControllerEntrypoint.js';
|
|
2
|
+
import { getActionDTOAndOptions } from '../lib/GetActionDTOAndOptions.js';
|
|
3
|
+
import { ScheduleChannel } from '../channel/BuiltinChannels.js';
|
|
4
|
+
import { Cron, parseDuration } from '../lib/schedule/Cron.js';
|
|
5
|
+
/**
|
|
6
|
+
* A key for each scheduled action, telling apart the actions of a same schedule
|
|
7
|
+
*/
|
|
8
|
+
let keys = 0;
|
|
9
|
+
/**
|
|
10
|
+
* The address of a schedule
|
|
11
|
+
* @param schedule
|
|
12
|
+
*/
|
|
13
|
+
function ScheduleAddress(schedule) {
|
|
14
|
+
let options;
|
|
15
|
+
if (typeof schedule === 'string') {
|
|
16
|
+
//A text is an interval ("30s") when it is one, a cron expression otherwise
|
|
17
|
+
let every;
|
|
18
|
+
try {
|
|
19
|
+
every = parseDuration(schedule);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
every = undefined;
|
|
23
|
+
}
|
|
24
|
+
options = every === undefined ? { cron: schedule } : { every: schedule };
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
options = schedule;
|
|
28
|
+
}
|
|
29
|
+
const address = {};
|
|
30
|
+
if (options.every !== undefined) {
|
|
31
|
+
address.every = parseDuration(options.every);
|
|
32
|
+
address.schedule = `every ${typeof options.every === 'number' ? `${options.every}ms` : options.every}`;
|
|
33
|
+
}
|
|
34
|
+
else if (options.cron !== undefined) {
|
|
35
|
+
//The expression is checked now, not at the first run
|
|
36
|
+
new Cron(options.cron, options.timezone);
|
|
37
|
+
address.cron = options.cron;
|
|
38
|
+
address.schedule = `cron ${options.cron}`;
|
|
39
|
+
if (options.timezone)
|
|
40
|
+
address.timezone = options.timezone;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new SyntaxError('A schedule is an interval (every) or a cron expression (cron)');
|
|
44
|
+
}
|
|
45
|
+
address.overlap = options.overlap === true;
|
|
46
|
+
address.immediate = options.immediate === true;
|
|
47
|
+
if (options.exclusive) {
|
|
48
|
+
address.exclusive = (typeof options.exclusive === 'object' ? options.exclusive.mutex : undefined) ?? 'mutex';
|
|
49
|
+
if (typeof options.exclusive === 'object' && options.exclusive.key)
|
|
50
|
+
address.exclusiveKey = options.exclusive.key;
|
|
51
|
+
}
|
|
52
|
+
address.key = `s${++keys}`;
|
|
53
|
+
return address;
|
|
54
|
+
}
|
|
55
|
+
export function Schedule(schedule, actionOptions) {
|
|
56
|
+
return (target, propertyKey, descriptor) => {
|
|
57
|
+
const [dtoConstructor, options] = getActionDTOAndOptions(actionOptions ?? {});
|
|
58
|
+
registerControllerAction(ScheduleChannel, target, propertyKey, ScheduleAddress(schedule), dtoConstructor, options);
|
|
59
|
+
return descriptor;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { registerServiceAction } from '../lib/ControllerEntrypoint.js';
|
|
2
|
+
import { getActionDTOAndOptions } from '../lib/GetActionDTOAndOptions.js';
|
|
3
|
+
export function ServiceAction(pattern, dtoConstructorOrOptions, options) {
|
|
4
|
+
return (target, propertyKey, descriptor) => {
|
|
5
|
+
const [dtoConstructor, actionOptions] = getActionDTOAndOptions(dtoConstructorOrOptions, options);
|
|
6
|
+
registerServiceAction(pattern, target, propertyKey, dtoConstructor, actionOptions);
|
|
7
|
+
return descriptor;
|
|
8
|
+
};
|
|
9
|
+
}
|