@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,120 @@
|
|
|
1
|
+
import { Controller, type ControllerProperty } from '../lib/Controller.js';
|
|
2
|
+
import { MethodDecorator, DTO } from '@lakutata/core';
|
|
3
|
+
import { ActionOptions } from '../lib/ActionOptions.js';
|
|
4
|
+
import { CLIContext } from '../context/CLIContext.js';
|
|
5
|
+
/**
|
|
6
|
+
* Expose the controller method as a CLI command, run by the CLI adapters of the entrypoint (`commanderCLIEntrypoint`).
|
|
7
|
+
* Without a DTO, the command has no options and its input is accepted as it is.
|
|
8
|
+
* On a command, the CLI adapter (`commanderCLIEntrypoint`) assembles the input from the positional arguments and the
|
|
9
|
+
* options, each value parsed by the type of its property; the middlewares run, the input is validated against the DTO
|
|
10
|
+
* (the defaults applied), the access control runs when `acl` is set, then the method receives the validated input as a
|
|
11
|
+
* plain object.
|
|
12
|
+
* The value returned is written to stdout: a string as it is, a `Uint8Array` as its bytes, `undefined` and `null` as
|
|
13
|
+
* nothing, another value as indented JSON; `Result.file()` and `Result.events()` stream a file or events. An error is
|
|
14
|
+
* written to stderr as `error: <errMsg or message>` and the command ends with the code 1.
|
|
15
|
+
* @param command The command line: its name, optionally followed by positional arguments (`copy <source> [target]`,
|
|
16
|
+
* `<files...>` for several values) given to the input properties of the same names; the words before the name are
|
|
17
|
+
* groups (`package exe <file>`: the command `exe` of the group `package`). The controller's `@Prefix({command})` is
|
|
18
|
+
* prepended to it, joined by ":" (`user` and `get` give `user:get`).
|
|
19
|
+
* @returns The method decorator.
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import {Application, DTO} from 'lakutata'
|
|
23
|
+
* import {buildEntrypoints, Controller} from 'lakutata/com/entrypoint'
|
|
24
|
+
* import {CLIAction} from 'lakutata/decorator/ctrl'
|
|
25
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
26
|
+
* import {commanderCLIEntrypoint} from 'lakutata/adapter/commander'
|
|
27
|
+
*
|
|
28
|
+
* class GreetDTO extends DTO {
|
|
29
|
+
* //The positional argument <name>
|
|
30
|
+
* @Expect(DTO.String().required().description('Who to greet'))
|
|
31
|
+
* public name!: string
|
|
32
|
+
*
|
|
33
|
+
* //The option --times <value>, parsed as a number
|
|
34
|
+
* @Expect(DTO.Number().integer().min(1).optional().default(1).description('How many times'))
|
|
35
|
+
* public times!: number
|
|
36
|
+
*
|
|
37
|
+
* //The flag --shout
|
|
38
|
+
* @Expect(DTO.Boolean().optional().default(false).description('Greet loudly'))
|
|
39
|
+
* public shout!: boolean
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* class GreetController extends Controller {
|
|
43
|
+
* //"app greet Ada --times 2 --shout" prints ["HELLO, ADA", "HELLO, ADA"] as JSON; "app greet Ada --times 0" prints
|
|
44
|
+
* //"error: …" to stderr and ends with the code 1
|
|
45
|
+
* @CLIAction('greet <name>', GreetDTO, {description: 'Greet someone'})
|
|
46
|
+
* public async greet(input: GreetDTO): Promise<string[]> {
|
|
47
|
+
* const text: string = `Hello, ${input.name}`
|
|
48
|
+
* return Array(input.times).fill(input.shout ? text.toUpperCase() : text)
|
|
49
|
+
* }
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* Application.run(() => ({
|
|
53
|
+
* id: 'greet.app',
|
|
54
|
+
* name: 'Greet',
|
|
55
|
+
* components: {
|
|
56
|
+
* entrypoint: buildEntrypoints({
|
|
57
|
+
* controllers: [GreetController],
|
|
58
|
+
* cli: commanderCLIEntrypoint()
|
|
59
|
+
* })
|
|
60
|
+
* },
|
|
61
|
+
* bootstrap: ['entrypoint']
|
|
62
|
+
* }))
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function CLIAction<ClassPrototype extends Controller, Method>(command: string): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
66
|
+
/**
|
|
67
|
+
* Expose the controller method as a CLI command whose options are the properties of a DTO. The CLI adapter assembles
|
|
68
|
+
* the input from the positional arguments and the options; the method receives it validated, as a plain object. The
|
|
69
|
+
* value returned is written to stdout (a string as it is, another value as JSON), an error to stderr as `error:
|
|
70
|
+
* <message>` with the exit code 1.
|
|
71
|
+
* @param command The command line: its name, optionally followed by positional arguments (`copy <source> [target]`,
|
|
72
|
+
* `<files...>` for several values) given to the input properties of the same names; the words before the name are
|
|
73
|
+
* groups (`package exe <file>`: the command `exe` of the group `package`). The controller's `@Prefix({command})` is
|
|
74
|
+
* prepended to it, joined by ":" (`user` and `get` give `user:get`).
|
|
75
|
+
* @param dtoConstructor The DTO class of the input: each of its properties not given by a positional argument is an
|
|
76
|
+
* option `--kebab-case-name` (a flag for a boolean, a repeatable option for an array, JSON for an object), mandatory
|
|
77
|
+
* when it is required without a default; its schema `.description()` is the option's help.
|
|
78
|
+
* @returns The method decorator.
|
|
79
|
+
*/
|
|
80
|
+
export declare function CLIAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(command: string, dtoConstructor: DTOConstructor): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
81
|
+
/**
|
|
82
|
+
* Expose the controller method as a CLI command, with action options; the command has no options and its input is
|
|
83
|
+
* accepted as it is. The value returned is written to stdout (a string as it is, another value as JSON), an error to
|
|
84
|
+
* stderr as `error: <message>` with the exit code 1.
|
|
85
|
+
* @param command The command line: its name, optionally followed by positional arguments (`copy <source> [target]`,
|
|
86
|
+
* `<files...>` for several values) given to the input properties of the same names; the words before the name are
|
|
87
|
+
* groups (`package exe <file>`: the command `exe` of the group `package`). The controller's `@Prefix({command})` is
|
|
88
|
+
* prepended to it, joined by ":" (`user` and `get` give `user:get`).
|
|
89
|
+
* @param actionOptions The action options: `description` is the command's help; `acl` runs the access control rules
|
|
90
|
+
* (false by default); `name` (unique in the CLI actions, `ClassName:method` by default) and `groups` describe the
|
|
91
|
+
* action; `rule` is an access rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the
|
|
92
|
+
* method.
|
|
93
|
+
* @returns The method decorator.
|
|
94
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
95
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
96
|
+
* nor a class extending `Middleware`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function CLIAction<ClassPrototype extends Controller, Method>(command: string, actionOptions: ActionOptions<CLIContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
99
|
+
/**
|
|
100
|
+
* Expose the controller method as a CLI command whose options are the properties of a DTO, with action options. The CLI
|
|
101
|
+
* adapter assembles the input from the positional arguments and the options; the method receives it validated, as a
|
|
102
|
+
* plain object. The value returned is written to stdout (a string as it is, another value as JSON), an error to stderr
|
|
103
|
+
* as `error: <message>` with the exit code 1.
|
|
104
|
+
* @param command The command line: its name, optionally followed by positional arguments (`copy <source> [target]`,
|
|
105
|
+
* `<files...>` for several values) given to the input properties of the same names; the words before the name are
|
|
106
|
+
* groups (`package exe <file>`: the command `exe` of the group `package`). The controller's `@Prefix({command})` is
|
|
107
|
+
* prepended to it, joined by ":" (`user` and `get` give `user:get`).
|
|
108
|
+
* @param dtoConstructor The DTO class of the input: each of its properties not given by a positional argument is an
|
|
109
|
+
* option `--kebab-case-name` (a flag for a boolean, a repeatable option for an array, JSON for an object), mandatory
|
|
110
|
+
* when it is required without a default; its schema `.description()` is the option's help.
|
|
111
|
+
* @param actionOptions The action options: `description` is the command's help; `acl` runs the access control rules
|
|
112
|
+
* (false by default); `name` (unique in the CLI actions, `ClassName:method` by default) and `groups` describe the
|
|
113
|
+
* action; `rule` is an access rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the
|
|
114
|
+
* method.
|
|
115
|
+
* @returns The method decorator.
|
|
116
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
117
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
118
|
+
* nor a class extending `Middleware`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function CLIAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(command: string, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<CLIContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLIAction = CLIAction;
|
|
4
|
+
const ControllerEntrypoint_js_1 = require("../lib/ControllerEntrypoint.js");
|
|
5
|
+
const ActionOptions_js_1 = require("../lib/ActionOptions.js");
|
|
6
|
+
const GetActionDTOAndOptions_js_1 = require("../lib/GetActionDTOAndOptions.js");
|
|
7
|
+
function CLIAction(command, dtoConstructorOrOptions, options) {
|
|
8
|
+
return (target, propertyKey, descriptor) => {
|
|
9
|
+
const [dtoConstructor, actionOptions] = (0, GetActionDTOAndOptions_js_1.getActionDTOAndOptions)(dtoConstructorOrOptions, options);
|
|
10
|
+
(0, ControllerEntrypoint_js_1.registerCLIAction)(command, target, propertyKey, dtoConstructor, ActionOptions_js_1.ActionOptions.validate(actionOptions));
|
|
11
|
+
return descriptor;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { Controller, type ControllerProperty } from '../lib/Controller.js';
|
|
2
|
+
import { MethodDecorator, DTO } from '@lakutata/core';
|
|
3
|
+
import { ActionOptions } from '../lib/ActionOptions.js';
|
|
4
|
+
import { HTTPContext } from '../context/HTTPContext.js';
|
|
5
|
+
/**
|
|
6
|
+
* Expose the controller method as an HTTP action answering a route for an HTTP method, served by the HTTP adapters of
|
|
7
|
+
* the entrypoint (`expressHTTPEntrypoint`, `fastifyHTTPEntrypoint`). Without a DTO, the input is accepted as it is.
|
|
8
|
+
*
|
|
9
|
+
* On a request, the adapter assembles the input: by default, the query string merged with the parsed body (JSON or URL
|
|
10
|
+
* encoded), then the route parameters over them. The middlewares run, the input is validated against the DTO (the
|
|
11
|
+
* defaults applied, the unknown keys removed), the access control runs when `acl` is set, then the method receives the
|
|
12
|
+
* validated input as a plain object, not a DTO instance. The query values and the route parameters are strings and the
|
|
13
|
+
* DTO schemas are strict: convert them with `.strict(false)` (`DTO.Number().strict(false)`).
|
|
14
|
+
*
|
|
15
|
+
* The value returned is answered by the adapter's responder: as JSON by default, with the status 204 for `undefined`;
|
|
16
|
+
* return `Result.status()`, `Result.file()` or `Result.events()` for a status and headers, a file or server-sent
|
|
17
|
+
* events. An error thrown is answered as `{errno, errMsg}` with the first 4xx `statusCode` along its causes (400 for an
|
|
18
|
+
* invalid input), else its own `statusCode`, else 500.
|
|
19
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
20
|
+
* prepended to it.
|
|
21
|
+
* @param method The HTTP method (`'get'`, `'post'`, `'put'`, `'patch'`, `'delete'`, `'head'`, `'options'`), in any
|
|
22
|
+
* case; a method the adapter does not support fails its start.
|
|
23
|
+
* @returns The method decorator.
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import {Application, DTO} from 'lakutata'
|
|
27
|
+
* import {buildEntrypoints, Controller} from 'lakutata/com/entrypoint'
|
|
28
|
+
* import {HTTPAction} from 'lakutata/decorator/ctrl'
|
|
29
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
30
|
+
* import {expressHTTPEntrypoint} from 'lakutata/adapter/express'
|
|
31
|
+
*
|
|
32
|
+
* class SearchDTO extends DTO {
|
|
33
|
+
* @Expect(DTO.String().required())
|
|
34
|
+
* public keyword!: string
|
|
35
|
+
*
|
|
36
|
+
* //A query value is a string: converted to a number
|
|
37
|
+
* @Expect(DTO.Number().integer().min(1).strict(false).optional().default(1))
|
|
38
|
+
* public page!: number
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* class SearchController extends Controller {
|
|
42
|
+
* //GET /search?keyword=lamp&page=2, or POST /search with the body {"keyword": "lamp"}: answered with the JSON
|
|
43
|
+
* //{"keyword": "lamp", "page": 2}; without a keyword, the status 400 and {"errno": "E_INVALID_VALUE", "errMsg": …}
|
|
44
|
+
* @HTTPAction('/search', ['get', 'post'], SearchDTO)
|
|
45
|
+
* public async search(input: SearchDTO): Promise<{ keyword: string, page: number }> {
|
|
46
|
+
* return {keyword: input.keyword, page: input.page}
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* //PURGE /cache, an access-controlled action: answered with the status 204 (no content)
|
|
50
|
+
* @HTTPAction('/cache', 'purge', {acl: true, name: 'Purge the cache'})
|
|
51
|
+
* public async purge(): Promise<void> {
|
|
52
|
+
* }
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* Application.run(() => ({
|
|
56
|
+
* id: 'search.app',
|
|
57
|
+
* name: 'Search',
|
|
58
|
+
* components: {
|
|
59
|
+
* entrypoint: buildEntrypoints({
|
|
60
|
+
* controllers: [SearchController],
|
|
61
|
+
* http: expressHTTPEntrypoint({port: 8080})
|
|
62
|
+
* })
|
|
63
|
+
* },
|
|
64
|
+
* bootstrap: ['entrypoint']
|
|
65
|
+
* }))
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method>(route: string, method: string): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
69
|
+
/**
|
|
70
|
+
* Expose the controller method as an HTTP action answering a route for an HTTP method, its input validated against a
|
|
71
|
+
* DTO. The input is the query string merged with the parsed body, then the route parameters over them (the default of
|
|
72
|
+
* the adapters); the method receives it validated, as a plain object. The value returned is answered as JSON (204 for
|
|
73
|
+
* `undefined`), an error as `{errno, errMsg}` with its status (400 for an invalid input, else 500 by default).
|
|
74
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
75
|
+
* prepended to it.
|
|
76
|
+
* @param method The HTTP method (`'get'`, `'post'`…), in any case.
|
|
77
|
+
* @param dtoConstructor The DTO class validating the input; the query values and the route parameters are strings,
|
|
78
|
+
* convert them with `.strict(false)`.
|
|
79
|
+
* @returns The method decorator.
|
|
80
|
+
*/
|
|
81
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(route: string, method: string, dtoConstructor: DTOConstructor): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
82
|
+
/**
|
|
83
|
+
* Expose the controller method as an HTTP action answering a route for an HTTP method, with action options; the input
|
|
84
|
+
* is accepted as it is. The value returned is answered as JSON (204 for `undefined`), an error as `{errno, errMsg}`
|
|
85
|
+
* with its status (500 by default).
|
|
86
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
87
|
+
* prepended to it.
|
|
88
|
+
* @param method The HTTP method (`'get'`, `'post'`…), in any case.
|
|
89
|
+
* @param actionOptions The action options: `acl` runs the access control rules (false by default); `name` (unique in the
|
|
90
|
+
* HTTP actions, `ClassName:method` by default), `description` and `groups` describe the action; `rule` is an access
|
|
91
|
+
* rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the method.
|
|
92
|
+
* @returns The method decorator.
|
|
93
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
94
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
95
|
+
* nor a class extending `Middleware`.
|
|
96
|
+
*/
|
|
97
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method>(route: string, method: string, actionOptions: ActionOptions<HTTPContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
98
|
+
/**
|
|
99
|
+
* Expose the controller method as an HTTP action answering a route for an HTTP method, its input validated against a
|
|
100
|
+
* DTO, with action options. The input is the query string merged with the parsed body, then the route parameters over
|
|
101
|
+
* them (the default of the adapters); the method receives it validated, as a plain object. The value returned is
|
|
102
|
+
* answered as JSON (204 for `undefined`), an error as `{errno, errMsg}` with its status (400 for an invalid input, else
|
|
103
|
+
* 500 by default).
|
|
104
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
105
|
+
* prepended to it.
|
|
106
|
+
* @param method The HTTP method (`'get'`, `'post'`…), in any case.
|
|
107
|
+
* @param dtoConstructor The DTO class validating the input; the query values and the route parameters are strings,
|
|
108
|
+
* convert them with `.strict(false)`.
|
|
109
|
+
* @param actionOptions The action options: `acl` runs the access control rules (false by default); `name` (unique in the
|
|
110
|
+
* HTTP actions, `ClassName:method` by default), `description` and `groups` describe the action; `rule` is an access
|
|
111
|
+
* rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the method.
|
|
112
|
+
* @returns The method decorator.
|
|
113
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
114
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
115
|
+
* nor a class extending `Middleware`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(route: string, method: string, dtoConstructor: DTOConstructor, actionOptions: ActionOptions<HTTPContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
118
|
+
/**
|
|
119
|
+
* Expose the controller method as an HTTP action answering a route for several HTTP methods; the input is accepted as
|
|
120
|
+
* it is. The input is the query string merged with the parsed body, then the route parameters over them (the default
|
|
121
|
+
* of the adapters). The value returned is answered as JSON (204 for `undefined`), an error as `{errno, errMsg}` with
|
|
122
|
+
* its status (500 by default).
|
|
123
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
124
|
+
* prepended to it.
|
|
125
|
+
* @param methods The HTTP methods (`['get', 'post']`), in any case; the action answers each of them.
|
|
126
|
+
* @returns The method decorator.
|
|
127
|
+
*/
|
|
128
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method>(route: string, methods: string[]): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
129
|
+
/**
|
|
130
|
+
* Expose the controller method as an HTTP action answering a route for several HTTP methods, its input validated
|
|
131
|
+
* against a DTO. The input is the query string merged with the parsed body, then the route parameters over them (the
|
|
132
|
+
* default of the adapters); the method receives it validated, as a plain object. The value returned is answered as
|
|
133
|
+
* JSON (204 for `undefined`), an error as `{errno, errMsg}` with its status (400 for an invalid input, else 500 by
|
|
134
|
+
* default).
|
|
135
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
136
|
+
* prepended to it.
|
|
137
|
+
* @param methods The HTTP methods (`['get', 'post']`), in any case; the action answers each of them.
|
|
138
|
+
* @param dtoConstructor The DTO class validating the input; the query values and the route parameters are strings,
|
|
139
|
+
* convert them with `.strict(false)`.
|
|
140
|
+
* @returns The method decorator.
|
|
141
|
+
*/
|
|
142
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(route: string, methods: string[], dtoConstructor: DTOConstructor): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
143
|
+
/**
|
|
144
|
+
* Expose the controller method as an HTTP action answering a route for several HTTP methods, with action options; the
|
|
145
|
+
* input is accepted as it is. The value returned is answered as JSON (204 for `undefined`), an error as
|
|
146
|
+
* `{errno, errMsg}` with its status (500 by default).
|
|
147
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
148
|
+
* prepended to it.
|
|
149
|
+
* @param methods The HTTP methods (`['get', 'post']`), in any case; the action answers each of them.
|
|
150
|
+
* @param actionOptions The action options: `acl` runs the access control rules (false by default); `name` (unique in the
|
|
151
|
+
* HTTP actions, `ClassName:method` by default), `description` and `groups` describe the action; `rule` is an access
|
|
152
|
+
* rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the method.
|
|
153
|
+
* @returns The method decorator.
|
|
154
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
155
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
156
|
+
* nor a class extending `Middleware`.
|
|
157
|
+
*/
|
|
158
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method>(route: string, methods: string[], actionOptions: ActionOptions<HTTPContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
159
|
+
/**
|
|
160
|
+
* Expose the controller method as an HTTP action answering a route for several HTTP methods, its input validated
|
|
161
|
+
* against a DTO, with action options. The input is the query string merged with the parsed body, then the route
|
|
162
|
+
* parameters over them (the default of the adapters); the method receives it validated, as a plain object. The value
|
|
163
|
+
* returned is answered as JSON (204 for `undefined`), an error as `{errno, errMsg}` with its status (400 for an invalid
|
|
164
|
+
* input, else 500 by default).
|
|
165
|
+
* @param route The route, in the syntax of the HTTP adapter (`/users/:id`); the controller's `@Prefix({route})` is
|
|
166
|
+
* prepended to it.
|
|
167
|
+
* @param methods The HTTP methods (`['get', 'post']`), in any case; the action answers each of them.
|
|
168
|
+
* @param dtoConstructor The DTO class validating the input; the query values and the route parameters are strings,
|
|
169
|
+
* convert them with `.strict(false)`.
|
|
170
|
+
* @param actionOptions The action options: `acl` runs the access control rules (false by default); `name` (unique in the
|
|
171
|
+
* HTTP actions, `ClassName:method` by default), `description` and `groups` describe the action; `rule` is an access
|
|
172
|
+
* rule of the action; `middlewares` run before the ones `@UseMiddlewares` adds to the method.
|
|
173
|
+
* @returns The method decorator.
|
|
174
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
175
|
+
* @throws {InvalidMiddlewareException} When the class is declared, if a middleware of the options is neither a function
|
|
176
|
+
* nor a class extending `Middleware`.
|
|
177
|
+
*/
|
|
178
|
+
export declare function HTTPAction<ClassPrototype extends Controller, Method, DTOConstructor extends typeof DTO = typeof DTO>(route: string, methods: string[], dtoConstructor: DTOConstructor, actionOptions: ActionOptions<HTTPContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HTTPAction = HTTPAction;
|
|
4
|
+
const ControllerEntrypoint_js_1 = require("../lib/ControllerEntrypoint.js");
|
|
5
|
+
const GetActionDTOAndOptions_js_1 = require("../lib/GetActionDTOAndOptions.js");
|
|
6
|
+
function HTTPAction(r, m, dtoConstructorOrOptions, options) {
|
|
7
|
+
return (target, propertyKey, descriptor) => {
|
|
8
|
+
const route = r.toString();
|
|
9
|
+
const methods = Array.isArray(m) ? m : [m];
|
|
10
|
+
const [dtoConstructor, actionOptions] = (0, GetActionDTOAndOptions_js_1.getActionDTOAndOptions)(dtoConstructorOrOptions, options);
|
|
11
|
+
(0, ControllerEntrypoint_js_1.registerHTTPAction)(route, methods, target, propertyKey, dtoConstructor, actionOptions);
|
|
12
|
+
return descriptor;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Controller } from '../lib/Controller.js';
|
|
2
|
+
import { PrefixOptions } from '../lib/Prefix.js';
|
|
3
|
+
/**
|
|
4
|
+
* Prefix the addresses of a controller's actions, and of the controllers extending it unless they declare their own
|
|
5
|
+
* prefixes (a subclass's `@Prefix` replaces its parent's, it does not add to it):
|
|
6
|
+
* - `route` is prepended to the routes of the HTTP actions (`'/users'` and `'/:id'` give `'/users/:id'`);
|
|
7
|
+
* - `command` is prepended to the commands of the CLI actions, joined by ":" (`'user'` and `'get'` give `'user:get'`);
|
|
8
|
+
* - `pattern` is merged into the patterns of the service actions (`{resource: 'user'}` and `{act: 'get'}` give
|
|
9
|
+
* `{resource: 'user', act: 'get'}`).
|
|
10
|
+
*
|
|
11
|
+
* A channel without its prefix keeps the addresses as declared; the scheduled actions have none. The prefixes apply when
|
|
12
|
+
* the entrypoint registers the controller, and the prefixed actions are named after the registered controller, so that
|
|
13
|
+
* the controllers sharing a parent have distinct actions. Several `@Prefix` on a class merge their options.
|
|
14
|
+
* @param options The prefixes: `route`, `command` and `pattern`, each optional; the packages of other channels add
|
|
15
|
+
* their own.
|
|
16
|
+
* @returns The class decorator.
|
|
17
|
+
* @throws {InvalidValueException} When the class is declared, if the options are invalid.
|
|
18
|
+
* @throws {InvalidPrefixException} When the entrypoint initializes, if the pattern prefix sets a key that the pattern
|
|
19
|
+
* of an action sets to another value.
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import {DTO} from 'lakutata'
|
|
23
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
24
|
+
* import {CLIAction, GET, Prefix, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
25
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
26
|
+
*
|
|
27
|
+
* class UserIdDTO extends DTO {
|
|
28
|
+
* @Expect(DTO.String().required())
|
|
29
|
+
* public id!: string
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* @Prefix({route: '/users', command: 'user', pattern: {resource: 'user'}})
|
|
33
|
+
* class UserController extends Controller {
|
|
34
|
+
* //GET /users/:id, the command "user:get <id>" and the message {resource: 'user', act: 'get', id: …}
|
|
35
|
+
* @GET('/:id', UserIdDTO)
|
|
36
|
+
* @CLIAction('get <id>', UserIdDTO)
|
|
37
|
+
* @ServiceAction({act: 'get'}, UserIdDTO)
|
|
38
|
+
* public async get(input: UserIdDTO): Promise<{ id: string }> {
|
|
39
|
+
* return {id: input.id}
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function Prefix<ClassConstructor extends typeof Controller>(options: PrefixOptions): (target: ClassConstructor) => void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Prefix = Prefix;
|
|
4
|
+
const Prefix_js_1 = require("../lib/Prefix.js");
|
|
5
|
+
/**
|
|
6
|
+
* Prefix the addresses of a controller's actions, and of the controllers extending it unless they declare their own
|
|
7
|
+
* prefixes (a subclass's `@Prefix` replaces its parent's, it does not add to it):
|
|
8
|
+
* - `route` is prepended to the routes of the HTTP actions (`'/users'` and `'/:id'` give `'/users/:id'`);
|
|
9
|
+
* - `command` is prepended to the commands of the CLI actions, joined by ":" (`'user'` and `'get'` give `'user:get'`);
|
|
10
|
+
* - `pattern` is merged into the patterns of the service actions (`{resource: 'user'}` and `{act: 'get'}` give
|
|
11
|
+
* `{resource: 'user', act: 'get'}`).
|
|
12
|
+
*
|
|
13
|
+
* A channel without its prefix keeps the addresses as declared; the scheduled actions have none. The prefixes apply when
|
|
14
|
+
* the entrypoint registers the controller, and the prefixed actions are named after the registered controller, so that
|
|
15
|
+
* the controllers sharing a parent have distinct actions. Several `@Prefix` on a class merge their options.
|
|
16
|
+
* @param options The prefixes: `route`, `command` and `pattern`, each optional; the packages of other channels add
|
|
17
|
+
* their own.
|
|
18
|
+
* @returns The class decorator.
|
|
19
|
+
* @throws {InvalidValueException} When the class is declared, if the options are invalid.
|
|
20
|
+
* @throws {InvalidPrefixException} When the entrypoint initializes, if the pattern prefix sets a key that the pattern
|
|
21
|
+
* of an action sets to another value.
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import {DTO} from 'lakutata'
|
|
25
|
+
* import {Controller} from 'lakutata/com/entrypoint'
|
|
26
|
+
* import {CLIAction, GET, Prefix, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
27
|
+
* import {Expect} from 'lakutata/decorator/dto'
|
|
28
|
+
*
|
|
29
|
+
* class UserIdDTO extends DTO {
|
|
30
|
+
* @Expect(DTO.String().required())
|
|
31
|
+
* public id!: string
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* @Prefix({route: '/users', command: 'user', pattern: {resource: 'user'}})
|
|
35
|
+
* class UserController extends Controller {
|
|
36
|
+
* //GET /users/:id, the command "user:get <id>" and the message {resource: 'user', act: 'get', id: …}
|
|
37
|
+
* @GET('/:id', UserIdDTO)
|
|
38
|
+
* @CLIAction('get <id>', UserIdDTO)
|
|
39
|
+
* @ServiceAction({act: 'get'}, UserIdDTO)
|
|
40
|
+
* public async get(input: UserIdDTO): Promise<{ id: string }> {
|
|
41
|
+
* return {id: input.id}
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function Prefix(options) {
|
|
47
|
+
return (target) => (0, Prefix_js_1.setPrefix)(target, options);
|
|
48
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Controller, type ControllerProperty } from '../lib/Controller.js';
|
|
2
|
+
import { MethodDecorator } from '@lakutata/core';
|
|
3
|
+
import { ActionOptions } from '../lib/ActionOptions.js';
|
|
4
|
+
import { ScheduleContext } from '../context/ScheduleContext.js';
|
|
5
|
+
/**
|
|
6
|
+
* When a scheduled action runs (`@Schedule`): every interval (`every`) or at the times of a cron expression (`cron`),
|
|
7
|
+
* with how its runs overlap, start and are shared between the instances of the application.
|
|
8
|
+
*/
|
|
9
|
+
export type ScheduleOptions = ({
|
|
10
|
+
/**
|
|
11
|
+
* The interval between the runs: milliseconds, or a duration text such as `'500ms'`, `'30s'`, `'5m'`, `'1h30m'` or
|
|
12
|
+
* `'1d'`. The first run comes one interval after the application launched; the runs missed while the process was
|
|
13
|
+
* suspended are skipped.
|
|
14
|
+
*/
|
|
15
|
+
every: number | string;
|
|
16
|
+
cron?: never;
|
|
17
|
+
timezone?: never;
|
|
18
|
+
} | {
|
|
19
|
+
/**
|
|
20
|
+
* The times of the runs: a cron expression `'second minute hour day-of-month month day-of-week'` (the second is
|
|
21
|
+
* optional: 5 fields run at second 0), or a macro (`'@hourly'`, `'@daily'`…).
|
|
22
|
+
*/
|
|
23
|
+
cron: string;
|
|
24
|
+
/**
|
|
25
|
+
* The IANA time zone the expression is read in (`'Asia/Shanghai'`).
|
|
26
|
+
* @default the local time zone of the process
|
|
27
|
+
*/
|
|
28
|
+
timezone?: string;
|
|
29
|
+
every?: never;
|
|
30
|
+
}) & {
|
|
31
|
+
/**
|
|
32
|
+
* Start a run while the previous run of the action is still in progress; otherwise the run is skipped.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
overlap?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Also run the action once as soon as the application launched, besides its schedule.
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
immediate?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Run the action in one instance of the application at a time, with the locks of a mutex component
|
|
43
|
+
* (`lakutata/com/mutex`): each run is made by the instance acquiring its lock, the others skip it, and the intervals
|
|
44
|
+
* are aligned on their multiples so that every instance plans the same times. `true` uses the component named
|
|
45
|
+
* `'mutex'`; `{mutex, key}` names the component and the lock (the action name by default). Without the component,
|
|
46
|
+
* the action does not run and the error is logged.
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
exclusive?: boolean | {
|
|
50
|
+
mutex?: string;
|
|
51
|
+
key?: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Run the controller method on a schedule, when the entrypoint has a schedule adapter (`schedule: scheduleEntrypoint()`
|
|
56
|
+
* of `lakutata/com/entrypoint`). The runs start once the application launched and the runs in progress end before it
|
|
57
|
+
* stops. Each run has its own request scope and goes through the middlewares and the access control like a request; the
|
|
58
|
+
* method receives an empty input, and `this.context` is a `ScheduleContext` (its schedule, its planned time and its run
|
|
59
|
+
* number). The value returned is ignored; an error thrown is given to the adapter's `onError`, or logged by the
|
|
60
|
+
* application's `log` component (to the console without it), and the next runs go on.
|
|
61
|
+
* @param schedule A duration text (`'30s'`, `'1h30m'`) for an interval, any other text for a cron expression
|
|
62
|
+
* (`'0 *\/5 * * * *'`, `'@daily'`), or the schedule options.
|
|
63
|
+
* @returns The method decorator.
|
|
64
|
+
* @throws {SyntaxError} When the class is declared, if the interval or the cron expression is invalid.
|
|
65
|
+
* @throws {RangeError} When the class is declared, if the time zone is unknown.
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* import {Application} from 'lakutata'
|
|
69
|
+
* import {buildEntrypoints, Controller, ScheduleContext, scheduleEntrypoint} from 'lakutata/com/entrypoint'
|
|
70
|
+
* import {Schedule} from 'lakutata/decorator/ctrl'
|
|
71
|
+
*
|
|
72
|
+
* class JobController extends Controller {
|
|
73
|
+
* //Every 30 seconds, and once as soon as the application launched
|
|
74
|
+
* @Schedule({every: '30s', immediate: true})
|
|
75
|
+
* public async heartbeat(): Promise<void> {
|
|
76
|
+
* if (this.context instanceof ScheduleContext) console.log(`run ${this.context.run} of ${this.context.schedule}`)
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* //Every 5 minutes, at second 0
|
|
80
|
+
* @Schedule('0 *\/5 * * * *')
|
|
81
|
+
* public async report(): Promise<void> {
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* //At 03:00 every day in Shanghai, by one instance of the application at a time (a mutex component named "mutex")
|
|
85
|
+
* @Schedule({cron: '0 3 * * *', timezone: 'Asia/Shanghai', exclusive: true}, {name: 'Purge the expired sessions'})
|
|
86
|
+
* public async purge(): Promise<void> {
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* Application.run(() => ({
|
|
91
|
+
* id: 'jobs.app',
|
|
92
|
+
* name: 'Jobs',
|
|
93
|
+
* components: {
|
|
94
|
+
* entrypoint: buildEntrypoints({
|
|
95
|
+
* controllers: [JobController],
|
|
96
|
+
* schedule: scheduleEntrypoint({onError: (error: unknown): void => console.error(error)})
|
|
97
|
+
* })
|
|
98
|
+
* },
|
|
99
|
+
* bootstrap: ['entrypoint']
|
|
100
|
+
* }))
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare function Schedule<ClassPrototype extends Controller, Method>(schedule: string | ScheduleOptions): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
104
|
+
/**
|
|
105
|
+
* Run the controller method on a schedule, with action options, when the entrypoint has a schedule adapter
|
|
106
|
+
* (`schedule: scheduleEntrypoint()`). Each run has its own request scope and goes through the middlewares and the access
|
|
107
|
+
* control like a request; the method receives an empty input and `this.context` is a `ScheduleContext`. An error thrown
|
|
108
|
+
* is given to the adapter's `onError`, or logged, and the next runs go on.
|
|
109
|
+
* @param schedule A duration text (`'30s'`, `'1h30m'`) for an interval, any other text for a cron expression
|
|
110
|
+
* (`'0 *\/5 * * * *'`, `'@daily'`), or the schedule options.
|
|
111
|
+
* @param actionOptions The action options: `name` (`ClassName:method` by default) names the action in the logs and is the
|
|
112
|
+
* default lock key of an exclusive schedule; `description` and `groups` describe it; `acl` runs the access control
|
|
113
|
+
* rules (false by default); `rule` is an access rule of the action; `middlewares` run before the ones `@UseMiddlewares`
|
|
114
|
+
* adds to the method.
|
|
115
|
+
* @returns The method decorator.
|
|
116
|
+
* @throws {SyntaxError} When the class is declared, if the interval or the cron expression is invalid.
|
|
117
|
+
* @throws {RangeError} When the class is declared, if the time zone is unknown.
|
|
118
|
+
* @throws {InvalidValueException} When the class is declared, if the action options are invalid.
|
|
119
|
+
*/
|
|
120
|
+
export declare function Schedule<ClassPrototype extends Controller, Method>(schedule: string | ScheduleOptions, actionOptions: ActionOptions<ScheduleContext>): MethodDecorator<ClassPrototype, Method, ControllerProperty<ClassPrototype>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Schedule = Schedule;
|
|
4
|
+
const ControllerEntrypoint_js_1 = require("../lib/ControllerEntrypoint.js");
|
|
5
|
+
const GetActionDTOAndOptions_js_1 = require("../lib/GetActionDTOAndOptions.js");
|
|
6
|
+
const BuiltinChannels_js_1 = require("../channel/BuiltinChannels.js");
|
|
7
|
+
const Cron_js_1 = require("../lib/schedule/Cron.js");
|
|
8
|
+
/**
|
|
9
|
+
* A key for each scheduled action, telling apart the actions of a same schedule
|
|
10
|
+
*/
|
|
11
|
+
let keys = 0;
|
|
12
|
+
/**
|
|
13
|
+
* The address of a schedule
|
|
14
|
+
* @param schedule
|
|
15
|
+
*/
|
|
16
|
+
function ScheduleAddress(schedule) {
|
|
17
|
+
let options;
|
|
18
|
+
if (typeof schedule === 'string') {
|
|
19
|
+
//A text is an interval ("30s") when it is one, a cron expression otherwise
|
|
20
|
+
let every;
|
|
21
|
+
try {
|
|
22
|
+
every = (0, Cron_js_1.parseDuration)(schedule);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
every = undefined;
|
|
26
|
+
}
|
|
27
|
+
options = every === undefined ? { cron: schedule } : { every: schedule };
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
options = schedule;
|
|
31
|
+
}
|
|
32
|
+
const address = {};
|
|
33
|
+
if (options.every !== undefined) {
|
|
34
|
+
address.every = (0, Cron_js_1.parseDuration)(options.every);
|
|
35
|
+
address.schedule = `every ${typeof options.every === 'number' ? `${options.every}ms` : options.every}`;
|
|
36
|
+
}
|
|
37
|
+
else if (options.cron !== undefined) {
|
|
38
|
+
//The expression is checked now, not at the first run
|
|
39
|
+
new Cron_js_1.Cron(options.cron, options.timezone);
|
|
40
|
+
address.cron = options.cron;
|
|
41
|
+
address.schedule = `cron ${options.cron}`;
|
|
42
|
+
if (options.timezone)
|
|
43
|
+
address.timezone = options.timezone;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
throw new SyntaxError('A schedule is an interval (every) or a cron expression (cron)');
|
|
47
|
+
}
|
|
48
|
+
address.overlap = options.overlap === true;
|
|
49
|
+
address.immediate = options.immediate === true;
|
|
50
|
+
if (options.exclusive) {
|
|
51
|
+
address.exclusive = (typeof options.exclusive === 'object' ? options.exclusive.mutex : undefined) ?? 'mutex';
|
|
52
|
+
if (typeof options.exclusive === 'object' && options.exclusive.key)
|
|
53
|
+
address.exclusiveKey = options.exclusive.key;
|
|
54
|
+
}
|
|
55
|
+
address.key = `s${++keys}`;
|
|
56
|
+
return address;
|
|
57
|
+
}
|
|
58
|
+
function Schedule(schedule, actionOptions) {
|
|
59
|
+
return (target, propertyKey, descriptor) => {
|
|
60
|
+
const [dtoConstructor, options] = (0, GetActionDTOAndOptions_js_1.getActionDTOAndOptions)(actionOptions ?? {});
|
|
61
|
+
(0, ControllerEntrypoint_js_1.registerControllerAction)(BuiltinChannels_js_1.ScheduleChannel, target, propertyKey, ScheduleAddress(schedule), dtoConstructor, options);
|
|
62
|
+
return descriptor;
|
|
63
|
+
};
|
|
64
|
+
}
|