@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,117 @@
|
|
|
1
|
+
import { type IncomingMessage, type Server } from 'node:http';
|
|
2
|
+
import type { EntrypointAdapter } from '../../channel/EntrypointAdapter.js';
|
|
3
|
+
import type { MiddlewareDefinition } from '../../lib/Middleware.js';
|
|
4
|
+
import { ServiceContext } from '../../context/ServiceContext.js';
|
|
5
|
+
/**
|
|
6
|
+
* The options of {@link httpServiceEntrypoint}.
|
|
7
|
+
*/
|
|
8
|
+
export type HTTPServiceEntrypointOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* The adapter name, to tell apart several service adapters of one entrypoint.
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The port the server listens on; 0 picks a random free port. The entrypoint fails to start when the port is in use.
|
|
15
|
+
* @default 3000
|
|
16
|
+
*/
|
|
17
|
+
port?: number;
|
|
18
|
+
/**
|
|
19
|
+
* The host or address the server listens on.
|
|
20
|
+
* @default all the interfaces
|
|
21
|
+
*/
|
|
22
|
+
host?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The path receiving the requests (POST). The event stream is served on `events` under it (`/api` → `/api/events`).
|
|
25
|
+
* @default '/'
|
|
26
|
+
*/
|
|
27
|
+
path?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The largest request body, in bytes; a larger one is answered with 413 and an error response.
|
|
30
|
+
* @default 10485760 (10 MiB)
|
|
31
|
+
*/
|
|
32
|
+
limit?: number;
|
|
33
|
+
/**
|
|
34
|
+
* The middlewares of this adapter's actions, run after the entrypoint's global middlewares.
|
|
35
|
+
*/
|
|
36
|
+
middlewares?: MiddlewareDefinition[];
|
|
37
|
+
/**
|
|
38
|
+
* Run once the server listens, with the server (to read the port picked for port 0). A failure fails the entrypoint
|
|
39
|
+
* start.
|
|
40
|
+
*/
|
|
41
|
+
listening?: (server: Server) => void | Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Get the HTTP request carrying a service action's request, when {@link httpServiceEntrypoint} serves it (to read its
|
|
45
|
+
* headers, its remote address…).
|
|
46
|
+
* @param context The service action's context (`this.context` in a controller).
|
|
47
|
+
* @returns The Node.js HTTP request, or `undefined` when another adapter serves the request.
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* import {Controller, httpRequestOfContext, ServiceContext} from 'lakutata/com/entrypoint'
|
|
51
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
52
|
+
*
|
|
53
|
+
* class WhoAmIController extends Controller {
|
|
54
|
+
* @ServiceAction({cmd: 'whoami'})
|
|
55
|
+
* public async whoami(): Promise<string | undefined> {
|
|
56
|
+
* return httpRequestOfContext(this.context as ServiceContext)?.socket.remoteAddress
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function httpRequestOfContext(context: ServiceContext): IncomingMessage | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Create a service adapter of an entrypoint served over plain HTTP, handy to call the service actions from tools such
|
|
64
|
+
* as curl or Postman during development. It needs no optional dependency.
|
|
65
|
+
*
|
|
66
|
+
* A request is a `POST` to the path whose JSON body holds the action's pattern and input (`{"cmd": "echo", "text":
|
|
67
|
+
* "hi"}`). The response is always 200 with the body `{success, error, payload}` (see `ServiceResponseCodec`): `payload`
|
|
68
|
+
* is the result, or `error` the whole error object when the action failed (no matching action, validation…). A body that
|
|
69
|
+
* is not JSON or exceeds `limit` is answered with 400 and an error body; any other method or path with 404. The CORS
|
|
70
|
+
* headers allow any origin.
|
|
71
|
+
*
|
|
72
|
+
* The events pushed to the clients (`Entrypoint.notify`, `Entrypoint.broadcast`) are streamed as Server-Sent Events by
|
|
73
|
+
* `GET <path>/events`: each event's name is the SSE event, its arguments the JSON array of its data. A client gives its
|
|
74
|
+
* id in the `id` header or the `id` query parameter (at most 200 characters), the same on its requests so that they
|
|
75
|
+
* carry it as `ServiceContext.clientId`; without one, the stream assigns a random id, sent first as the `client` event.
|
|
76
|
+
* The streams receive a keep-alive comment every 15 seconds.
|
|
77
|
+
*
|
|
78
|
+
* When a client disconnects before its response, the action's abort signal fires. When the entrypoint stops, the new
|
|
79
|
+
* requests are answered with an `EntrypointStoppedException` error; once the requests in progress end, the event
|
|
80
|
+
* streams are closed and the server shuts down.
|
|
81
|
+
* @param options The adapter options; by default it listens on port 3000 of all the interfaces, on the path `/`.
|
|
82
|
+
* @returns The adapter, to give to the `service` option of `buildEntrypoints`.
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* import {Application} from 'lakutata'
|
|
86
|
+
* import {buildEntrypoints, Controller, httpServiceEntrypoint} from 'lakutata/com/entrypoint'
|
|
87
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
88
|
+
*
|
|
89
|
+
* class EchoController extends Controller {
|
|
90
|
+
* @ServiceAction({cmd: 'echo'})
|
|
91
|
+
* public async echo(input: {text: string}): Promise<string> {
|
|
92
|
+
* return input.text
|
|
93
|
+
* }
|
|
94
|
+
* }
|
|
95
|
+
*
|
|
96
|
+
* Application.run({
|
|
97
|
+
* id: 'echo.service',
|
|
98
|
+
* name: 'Echo',
|
|
99
|
+
* components: {
|
|
100
|
+
* entrypoint: buildEntrypoints({
|
|
101
|
+
* controllers: [EchoController],
|
|
102
|
+
* service: httpServiceEntrypoint({port: 3000, path: '/rpc'})
|
|
103
|
+
* })
|
|
104
|
+
* }
|
|
105
|
+
* })
|
|
106
|
+
*
|
|
107
|
+
* //A client: the response is {"success": true, "error": null, "payload": "hi"}
|
|
108
|
+
* const response: Response = await fetch('http://localhost:3000/rpc', {
|
|
109
|
+
* method: 'POST',
|
|
110
|
+
* headers: {'Content-Type': 'application/json', 'id': 'client-1'},
|
|
111
|
+
* body: JSON.stringify({cmd: 'echo', text: 'hi'})
|
|
112
|
+
* })
|
|
113
|
+
* console.log(await response.json())
|
|
114
|
+
* //The events pushed to client-1: GET http://localhost:3000/rpc/events?id=client-1 (text/event-stream)
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare function httpServiceEntrypoint(options?: HTTPServiceEntrypointOptions): EntrypointAdapter<ServiceContext>;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.httpRequestOfContext = httpRequestOfContext;
|
|
4
|
+
exports.httpServiceEntrypoint = httpServiceEntrypoint;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const node_http_1 = require("node:http");
|
|
7
|
+
const ServiceContext_js_1 = require("../../context/ServiceContext.js");
|
|
8
|
+
const BuiltinChannels_js_1 = require("../../channel/BuiltinChannels.js");
|
|
9
|
+
const ServiceResponseCodec_js_1 = require("../../lib/ServiceResponseCodec.js");
|
|
10
|
+
const EntrypointStoppedException_js_1 = require("../../exceptions/EntrypointStoppedException.js");
|
|
11
|
+
/**
|
|
12
|
+
* Get the HTTP request carrying a service action's request, when {@link httpServiceEntrypoint} serves it (to read its
|
|
13
|
+
* headers, its remote address…).
|
|
14
|
+
* @param context The service action's context (`this.context` in a controller).
|
|
15
|
+
* @returns The Node.js HTTP request, or `undefined` when another adapter serves the request.
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import {Controller, httpRequestOfContext, ServiceContext} from 'lakutata/com/entrypoint'
|
|
19
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
20
|
+
*
|
|
21
|
+
* class WhoAmIController extends Controller {
|
|
22
|
+
* @ServiceAction({cmd: 'whoami'})
|
|
23
|
+
* public async whoami(): Promise<string | undefined> {
|
|
24
|
+
* return httpRequestOfContext(this.context as ServiceContext)?.socket.remoteAddress
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function httpRequestOfContext(context) {
|
|
30
|
+
return context.request;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The headers of the responses: the tools of the browsers may call the adapter (the development of the applications)
|
|
34
|
+
*/
|
|
35
|
+
const CORS_HEADERS = {
|
|
36
|
+
'Access-Control-Allow-Origin': '*',
|
|
37
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
38
|
+
'Access-Control-Allow-Headers': 'Content-Type, id'
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The id of the client of a request: its header id, its query id
|
|
42
|
+
* @param request
|
|
43
|
+
* @param url
|
|
44
|
+
*/
|
|
45
|
+
function clientIdOf(request, url) {
|
|
46
|
+
const given = request.headers.id ?? url.searchParams.get('id');
|
|
47
|
+
const id = Array.isArray(given) ? given[0] : given ?? undefined;
|
|
48
|
+
return id && id.length <= 200 ? id : undefined;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Write a response of JSON
|
|
52
|
+
* @param response
|
|
53
|
+
* @param status
|
|
54
|
+
* @param body
|
|
55
|
+
*/
|
|
56
|
+
function reply(response, status, body) {
|
|
57
|
+
if (response.headersSent || response.writableEnded)
|
|
58
|
+
return;
|
|
59
|
+
response.writeHead(status, { ...CORS_HEADERS, 'Content-Type': 'application/json; charset=utf-8' }).end(JSON.stringify(body));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The body of a request, up to a limit
|
|
63
|
+
* @param request
|
|
64
|
+
* @param limit
|
|
65
|
+
*/
|
|
66
|
+
async function readBody(request, limit) {
|
|
67
|
+
const chunks = [];
|
|
68
|
+
let size = 0;
|
|
69
|
+
for await (const chunk of request) {
|
|
70
|
+
size += chunk.length;
|
|
71
|
+
if (size > limit)
|
|
72
|
+
throw Object.assign(new Error(`The body of the request is larger than ${limit} bytes`), { statusCode: 413 });
|
|
73
|
+
chunks.push(chunk);
|
|
74
|
+
}
|
|
75
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create a service adapter of an entrypoint served over plain HTTP, handy to call the service actions from tools such
|
|
79
|
+
* as curl or Postman during development. It needs no optional dependency.
|
|
80
|
+
*
|
|
81
|
+
* A request is a `POST` to the path whose JSON body holds the action's pattern and input (`{"cmd": "echo", "text":
|
|
82
|
+
* "hi"}`). The response is always 200 with the body `{success, error, payload}` (see `ServiceResponseCodec`): `payload`
|
|
83
|
+
* is the result, or `error` the whole error object when the action failed (no matching action, validation…). A body that
|
|
84
|
+
* is not JSON or exceeds `limit` is answered with 400 and an error body; any other method or path with 404. The CORS
|
|
85
|
+
* headers allow any origin.
|
|
86
|
+
*
|
|
87
|
+
* The events pushed to the clients (`Entrypoint.notify`, `Entrypoint.broadcast`) are streamed as Server-Sent Events by
|
|
88
|
+
* `GET <path>/events`: each event's name is the SSE event, its arguments the JSON array of its data. A client gives its
|
|
89
|
+
* id in the `id` header or the `id` query parameter (at most 200 characters), the same on its requests so that they
|
|
90
|
+
* carry it as `ServiceContext.clientId`; without one, the stream assigns a random id, sent first as the `client` event.
|
|
91
|
+
* The streams receive a keep-alive comment every 15 seconds.
|
|
92
|
+
*
|
|
93
|
+
* When a client disconnects before its response, the action's abort signal fires. When the entrypoint stops, the new
|
|
94
|
+
* requests are answered with an `EntrypointStoppedException` error; once the requests in progress end, the event
|
|
95
|
+
* streams are closed and the server shuts down.
|
|
96
|
+
* @param options The adapter options; by default it listens on port 3000 of all the interfaces, on the path `/`.
|
|
97
|
+
* @returns The adapter, to give to the `service` option of `buildEntrypoints`.
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* import {Application} from 'lakutata'
|
|
101
|
+
* import {buildEntrypoints, Controller, httpServiceEntrypoint} from 'lakutata/com/entrypoint'
|
|
102
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
103
|
+
*
|
|
104
|
+
* class EchoController extends Controller {
|
|
105
|
+
* @ServiceAction({cmd: 'echo'})
|
|
106
|
+
* public async echo(input: {text: string}): Promise<string> {
|
|
107
|
+
* return input.text
|
|
108
|
+
* }
|
|
109
|
+
* }
|
|
110
|
+
*
|
|
111
|
+
* Application.run({
|
|
112
|
+
* id: 'echo.service',
|
|
113
|
+
* name: 'Echo',
|
|
114
|
+
* components: {
|
|
115
|
+
* entrypoint: buildEntrypoints({
|
|
116
|
+
* controllers: [EchoController],
|
|
117
|
+
* service: httpServiceEntrypoint({port: 3000, path: '/rpc'})
|
|
118
|
+
* })
|
|
119
|
+
* }
|
|
120
|
+
* })
|
|
121
|
+
*
|
|
122
|
+
* //A client: the response is {"success": true, "error": null, "payload": "hi"}
|
|
123
|
+
* const response: Response = await fetch('http://localhost:3000/rpc', {
|
|
124
|
+
* method: 'POST',
|
|
125
|
+
* headers: {'Content-Type': 'application/json', 'id': 'client-1'},
|
|
126
|
+
* body: JSON.stringify({cmd: 'echo', text: 'hi'})
|
|
127
|
+
* })
|
|
128
|
+
* console.log(await response.json())
|
|
129
|
+
* //The events pushed to client-1: GET http://localhost:3000/rpc/events?id=client-1 (text/event-stream)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
function httpServiceEntrypoint(options = {}) {
|
|
133
|
+
const base = (options.path ?? '/').replace(/\/+$/, '');
|
|
134
|
+
const requestPath = base || '/';
|
|
135
|
+
const eventsPath = `${base}/events`;
|
|
136
|
+
const limit = options.limit ?? 10 * 1024 * 1024;
|
|
137
|
+
let server;
|
|
138
|
+
let stopping = false;
|
|
139
|
+
let keepAlive;
|
|
140
|
+
//The event streams of each client (a client may listen several times)
|
|
141
|
+
const clients = new Map();
|
|
142
|
+
/**
|
|
143
|
+
* Write an event to a stream
|
|
144
|
+
* @param stream
|
|
145
|
+
* @param event
|
|
146
|
+
* @param args
|
|
147
|
+
*/
|
|
148
|
+
const write = (stream, event, args) => {
|
|
149
|
+
stream.write(`event: ${event.replace(/[\r\n]+/g, ' ')}\ndata: ${JSON.stringify(args)}\n\n`);
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Stream the events of a client
|
|
153
|
+
* @param request
|
|
154
|
+
* @param response
|
|
155
|
+
* @param url
|
|
156
|
+
*/
|
|
157
|
+
const listen = (request, response, url) => {
|
|
158
|
+
const clientId = clientIdOf(request, url) ?? (0, node_crypto_1.randomUUID)();
|
|
159
|
+
response.writeHead(200, { ...CORS_HEADERS, 'Content-Type': 'text/event-stream; charset=utf-8', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
|
|
160
|
+
//Its id, given to the requests of the client (their header id)
|
|
161
|
+
write(response, 'client', [clientId]);
|
|
162
|
+
if (!clients.has(clientId))
|
|
163
|
+
clients.set(clientId, new Set());
|
|
164
|
+
clients.get(clientId).add(response);
|
|
165
|
+
request.once('close', () => {
|
|
166
|
+
clients.get(clientId)?.delete(response);
|
|
167
|
+
if (!clients.get(clientId)?.size)
|
|
168
|
+
clients.delete(clientId);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Answer a request of an action
|
|
173
|
+
* @param runtime
|
|
174
|
+
* @param request
|
|
175
|
+
* @param response
|
|
176
|
+
* @param url
|
|
177
|
+
*/
|
|
178
|
+
const invoke = async (runtime, request, response, url) => {
|
|
179
|
+
if (stopping)
|
|
180
|
+
return reply(response, 200, ServiceResponseCodec_js_1.ServiceResponseCodec.encodeError(new EntrypointStoppedException_js_1.EntrypointStoppedException('The entrypoint is stopping')));
|
|
181
|
+
//Aborted when its client leaves before its response
|
|
182
|
+
const aborted = new AbortController();
|
|
183
|
+
response.once('close', () => {
|
|
184
|
+
if (!response.writableFinished)
|
|
185
|
+
aborted.abort();
|
|
186
|
+
});
|
|
187
|
+
let data;
|
|
188
|
+
try {
|
|
189
|
+
const body = await readBody(request, limit);
|
|
190
|
+
data = body ? JSON.parse(body) : {};
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
//413 for a body larger than the limit, 400 for a body which is not JSON
|
|
194
|
+
return reply(response, error.statusCode ?? 400, ServiceResponseCodec_js_1.ServiceResponseCodec.encodeError(error instanceof SyntaxError ? new Error('The body of the request is not JSON') : error));
|
|
195
|
+
}
|
|
196
|
+
let result;
|
|
197
|
+
try {
|
|
198
|
+
const context = new ServiceContext_js_1.ServiceContext({ data: data && typeof data === 'object' ? data : {}, request: request, clientId: clientIdOf(request, url) });
|
|
199
|
+
result = ServiceResponseCodec_js_1.ServiceResponseCodec.encode(await runtime.dispatch(context, { signal: aborted.signal }), false);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
result = ServiceResponseCodec_js_1.ServiceResponseCodec.encodeError(error);
|
|
203
|
+
}
|
|
204
|
+
reply(response, 200, result);
|
|
205
|
+
};
|
|
206
|
+
return {
|
|
207
|
+
channel: 'service',
|
|
208
|
+
definition: BuiltinChannels_js_1.ServiceChannel,
|
|
209
|
+
name: options.name,
|
|
210
|
+
middlewares: options.middlewares,
|
|
211
|
+
start: async (runtime) => {
|
|
212
|
+
server = (0, node_http_1.createServer)((request, response) => {
|
|
213
|
+
const url = new URL(request.url ?? '/', 'http://localhost');
|
|
214
|
+
if (request.method === 'OPTIONS')
|
|
215
|
+
return void response.writeHead(204, CORS_HEADERS).end();
|
|
216
|
+
if (request.method === 'GET' && url.pathname === eventsPath)
|
|
217
|
+
return listen(request, response, url);
|
|
218
|
+
if (request.method === 'POST' && url.pathname === requestPath)
|
|
219
|
+
return void invoke(runtime, request, response, url);
|
|
220
|
+
reply(response, 404, { success: false, error: { message: `POST ${requestPath} invokes the actions, GET ${eventsPath} streams their events` }, payload: null });
|
|
221
|
+
});
|
|
222
|
+
//The event streams kept open by the proxies
|
|
223
|
+
keepAlive = setInterval(() => clients.forEach((streams) => streams.forEach((stream) => stream.write(': keep-alive\n\n'))), 15000);
|
|
224
|
+
keepAlive.unref();
|
|
225
|
+
await new Promise((resolve, reject) => {
|
|
226
|
+
server.once('error', reject).listen(options.port ?? 3000, options.host, () => {
|
|
227
|
+
server.off('error', reject);
|
|
228
|
+
resolve();
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
await options.listening?.(server);
|
|
232
|
+
},
|
|
233
|
+
stop: () => {
|
|
234
|
+
//The new requests are refused, the requests in progress end
|
|
235
|
+
stopping = true;
|
|
236
|
+
},
|
|
237
|
+
close: async () => {
|
|
238
|
+
clearInterval(keepAlive);
|
|
239
|
+
clients.forEach((streams) => streams.forEach((stream) => stream.end()));
|
|
240
|
+
clients.clear();
|
|
241
|
+
if (!server)
|
|
242
|
+
return;
|
|
243
|
+
const closing = new Promise((resolve) => void server.close(() => resolve()));
|
|
244
|
+
server.closeAllConnections();
|
|
245
|
+
await closing;
|
|
246
|
+
},
|
|
247
|
+
notify: (clientId, event, args) => {
|
|
248
|
+
const streams = clients.get(clientId);
|
|
249
|
+
streams?.forEach((stream) => write(stream, event, args));
|
|
250
|
+
return !!streams?.size;
|
|
251
|
+
},
|
|
252
|
+
broadcast: (event, args) => {
|
|
253
|
+
clients.forEach((streams) => streams.forEach((stream) => write(stream, event, args)));
|
|
254
|
+
return clients.size;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { ChannelRuntime } from '../../channel/EntrypointAdapter.js';
|
|
2
|
+
import { ServiceContext } from '../../context/ServiceContext.js';
|
|
3
|
+
/**
|
|
4
|
+
* The error codes of the JSON-RPC 2.0 responses sent by {@link jsonRPCServiceEntrypoint}.
|
|
5
|
+
*/
|
|
6
|
+
export declare const JSONRPCErrorCode: {
|
|
7
|
+
/**
|
|
8
|
+
* The message is not valid JSON.
|
|
9
|
+
*/
|
|
10
|
+
readonly PARSE_ERROR: -32700;
|
|
11
|
+
/**
|
|
12
|
+
* The message is not a JSON-RPC 2.0 request (or is an empty batch, or the HTTP request is not a `POST` to the path).
|
|
13
|
+
*/
|
|
14
|
+
readonly INVALID_REQUEST: -32600;
|
|
15
|
+
/**
|
|
16
|
+
* No service action matches the request (`ControllerActionNotFoundException`).
|
|
17
|
+
*/
|
|
18
|
+
readonly METHOD_NOT_FOUND: -32601;
|
|
19
|
+
/**
|
|
20
|
+
* The params are given by position without the `positionalParams` option, or fail the action's input validation
|
|
21
|
+
* (`InvalidValueException`).
|
|
22
|
+
*/
|
|
23
|
+
readonly INVALID_PARAMS: -32602;
|
|
24
|
+
/**
|
|
25
|
+
* Reserved by the specification for the internal errors; the adapter does not send it.
|
|
26
|
+
*/
|
|
27
|
+
readonly INTERNAL_ERROR: -32603;
|
|
28
|
+
/**
|
|
29
|
+
* Any other error thrown by an action (in the server error range, -32000 to -32099), with the whole error object as
|
|
30
|
+
* the error's `data`.
|
|
31
|
+
*/
|
|
32
|
+
readonly SERVER_ERROR: -32000;
|
|
33
|
+
/**
|
|
34
|
+
* The entrypoint is stopping and refuses the new requests (`EntrypointStoppedException`).
|
|
35
|
+
*/
|
|
36
|
+
readonly STOPPING: -32001;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* A JSON-RPC 2.0 request, as a client sends it. Without an `id`, it is a notification: the action runs but no response
|
|
40
|
+
* is sent.
|
|
41
|
+
*/
|
|
42
|
+
export type JSONRPCRequest = {
|
|
43
|
+
/**
|
|
44
|
+
* The protocol version, always `'2.0'`.
|
|
45
|
+
*/
|
|
46
|
+
jsonrpc: '2.0';
|
|
47
|
+
/**
|
|
48
|
+
* The method, mapped to the service action's pattern (see `JSONRPCMappingOptions`).
|
|
49
|
+
*/
|
|
50
|
+
method: string;
|
|
51
|
+
/**
|
|
52
|
+
* The params: by name (an object, merged into the action's input), or by position (an array, accepted only with the
|
|
53
|
+
* `positionalParams` option).
|
|
54
|
+
*/
|
|
55
|
+
params?: Record<string, unknown> | unknown[];
|
|
56
|
+
/**
|
|
57
|
+
* The request id, echoed in its response; omitted for a notification.
|
|
58
|
+
*/
|
|
59
|
+
id?: string | number | null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* A JSON-RPC 2.0 response, as the adapter sends it: either `result` or `error`.
|
|
63
|
+
*/
|
|
64
|
+
export type JSONRPCResponse = {
|
|
65
|
+
/**
|
|
66
|
+
* The protocol version, always `'2.0'`.
|
|
67
|
+
*/
|
|
68
|
+
jsonrpc: '2.0';
|
|
69
|
+
/**
|
|
70
|
+
* The id of the request answered; `null` when it could not be read (a parse error, an invalid request).
|
|
71
|
+
*/
|
|
72
|
+
id: string | number | null;
|
|
73
|
+
/**
|
|
74
|
+
* The action's result, `null` when it returned nothing.
|
|
75
|
+
*/
|
|
76
|
+
result?: unknown;
|
|
77
|
+
/**
|
|
78
|
+
* The error: its code (see {@link JSONRPCErrorCode}), its message, and for an action's error the whole error object as
|
|
79
|
+
* `data`.
|
|
80
|
+
*/
|
|
81
|
+
error?: {
|
|
82
|
+
code: number;
|
|
83
|
+
message: string;
|
|
84
|
+
data?: unknown;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* How {@link jsonRPCServiceEntrypoint} maps a JSON-RPC request to a service action's pattern and input.
|
|
89
|
+
*/
|
|
90
|
+
export type JSONRPCMappingOptions = {
|
|
91
|
+
/**
|
|
92
|
+
* The pattern field receiving the request's method: with `'method'`, `{"method": "user.get", "params": {"id": 1}}`
|
|
93
|
+
* is dispatched as `{method: 'user.get', id: 1}`, the action declared with `@ServiceAction({method: 'user.get'})`.
|
|
94
|
+
* @default 'method'
|
|
95
|
+
*/
|
|
96
|
+
methodField?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Build the pattern and the input of a request's action from its method and its params, replacing `methodField` and
|
|
99
|
+
* `positionalParams`. A thrown error answers the request with `INVALID_PARAMS`.
|
|
100
|
+
*/
|
|
101
|
+
toPattern?: (method: string, params: Record<string, unknown> | unknown[] | undefined) => Record<string, unknown>;
|
|
102
|
+
/**
|
|
103
|
+
* The input field receiving the params given by position (an array): with `'args'`, `{"method": "sum", "params":
|
|
104
|
+
* [1, 2]}` is dispatched as `{method: 'sum', args: [1, 2]}`.
|
|
105
|
+
* @default none: the params by position are refused with `INVALID_PARAMS`
|
|
106
|
+
*/
|
|
107
|
+
positionalParams?: string;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* The JSON-RPC request behind a service action's request, as {@link jsonRPCRequestOfContext} returns it.
|
|
111
|
+
*/
|
|
112
|
+
export type JSONRPCRequestInfo = {
|
|
113
|
+
/**
|
|
114
|
+
* The request's method.
|
|
115
|
+
*/
|
|
116
|
+
method: string;
|
|
117
|
+
/**
|
|
118
|
+
* The request's id; `undefined` for a notification (no response is sent).
|
|
119
|
+
*/
|
|
120
|
+
id: string | number | null | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* The transport the request came through.
|
|
123
|
+
*/
|
|
124
|
+
transport: 'http' | 'websocket' | 'stdio';
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Get the JSON-RPC request behind a service action's request, when {@link jsonRPCServiceEntrypoint} serves it (to
|
|
128
|
+
* tell a notification from a request, or read the transport).
|
|
129
|
+
* @param context The service action's context (`this.context` in a controller).
|
|
130
|
+
* @returns The request's method, id and transport, or `undefined` when another adapter serves the request.
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* import {Controller, ServiceContext} from 'lakutata/com/entrypoint'
|
|
134
|
+
* import {ServiceAction} from 'lakutata/decorator/ctrl'
|
|
135
|
+
* import {jsonRPCRequestOfContext, type JSONRPCRequestInfo} from 'lakutata/adapter/jsonrpc'
|
|
136
|
+
*
|
|
137
|
+
* class LogController extends Controller {
|
|
138
|
+
* //{"jsonrpc": "2.0", "method": "log.write", "params": {"line": "started"}}: a notification, no id
|
|
139
|
+
* @ServiceAction({method: 'log.write'})
|
|
140
|
+
* public async write(input: {line: string}): Promise<void> {
|
|
141
|
+
* const request: JSONRPCRequestInfo | undefined = jsonRPCRequestOfContext(this.context as ServiceContext)
|
|
142
|
+
* console.log(`${request?.transport}: ${input.line}`)
|
|
143
|
+
* }
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function jsonRPCRequestOfContext(context: ServiceContext): JSONRPCRequestInfo | undefined;
|
|
148
|
+
/**
|
|
149
|
+
* The context of a dispatch of a request
|
|
150
|
+
*/
|
|
151
|
+
export type JSONRPCDispatch = {
|
|
152
|
+
runtime: ChannelRuntime<ServiceContext>;
|
|
153
|
+
transport: JSONRPCRequestInfo['transport'];
|
|
154
|
+
clientId?: string;
|
|
155
|
+
/**
|
|
156
|
+
* The properties added to the contexts (the request of HTTP, the socket)
|
|
157
|
+
*/
|
|
158
|
+
extra?: Record<string, unknown>;
|
|
159
|
+
signal?: AbortSignal;
|
|
160
|
+
stopping: () => boolean;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* The requests of JSON-RPC 2.0 dispatched to the service actions: the single ones, the batches, the notifications (no
|
|
164
|
+
* response); their methods given to the patterns of the actions
|
|
165
|
+
*/
|
|
166
|
+
export declare class JSONRPCProtocol {
|
|
167
|
+
protected readonly options: JSONRPCMappingOptions;
|
|
168
|
+
constructor(options?: JSONRPCMappingOptions);
|
|
169
|
+
/**
|
|
170
|
+
* The pattern and the input of the action of a request
|
|
171
|
+
* @param request
|
|
172
|
+
* @protected
|
|
173
|
+
*/
|
|
174
|
+
protected pattern(request: JSONRPCRequest): Record<string, unknown>;
|
|
175
|
+
/**
|
|
176
|
+
* The response of a request (none for a notification)
|
|
177
|
+
* @param request
|
|
178
|
+
* @param dispatch
|
|
179
|
+
* @protected
|
|
180
|
+
*/
|
|
181
|
+
protected one(request: unknown, dispatch: JSONRPCDispatch): Promise<JSONRPCResponse | undefined>;
|
|
182
|
+
/**
|
|
183
|
+
* The response of a message (a request, a batch): undefined when there is none (notifications)
|
|
184
|
+
* @param message its text
|
|
185
|
+
* @param dispatch
|
|
186
|
+
*/
|
|
187
|
+
handle(message: string, dispatch: JSONRPCDispatch): Promise<JSONRPCResponse | JSONRPCResponse[] | undefined>;
|
|
188
|
+
/**
|
|
189
|
+
* A notification sent to a client (an event pushed)
|
|
190
|
+
* @param event
|
|
191
|
+
* @param args
|
|
192
|
+
*/
|
|
193
|
+
static notification(event: string, args: unknown[]): string;
|
|
194
|
+
}
|