lakutata 3.0.0 → 3.1.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/README.md +50 -30
- package/README.zh-CN.md +130 -0
- package/dist/cjs/exports/QueueComponent.d.ts +1 -0
- package/dist/cjs/exports/QueueComponent.js +20 -0
- package/dist/esm/exports/QueueComponent.js +1 -0
- package/dist/types/exports/QueueComponent.d.ts +1 -0
- package/doc/en/Application.md +107 -0
- package/doc/en/CLI.md +274 -0
- package/doc/en/Cache.md +379 -0
- package/doc/en/Command.md +110 -0
- package/doc/en/ContainerdIntegration.md +17 -16
- package/doc/en/Controllers.md +256 -0
- package/doc/en/DBus.md +291 -0
- package/doc/en/DTOValidation.md +72 -43
- package/doc/en/Database.md +188 -0
- package/doc/en/DatabaseDrivers.md +287 -0
- package/doc/en/Decorator.md +52 -40
- package/doc/en/DockerIntegration.md +7 -6
- package/doc/en/Entities.md +240 -0
- package/doc/en/Entrypoint.md +216 -0
- package/doc/en/Exceptions.md +174 -0
- package/doc/en/GRPC.md +251 -0
- package/doc/en/GettingStarted.md +165 -0
- package/doc/en/HTTP.md +507 -0
- package/doc/en/HelperFunctions.md +11 -11
- package/doc/en/I18n.md +119 -115
- package/doc/en/Injection.md +144 -0
- package/doc/en/Installers.md +280 -0
- package/doc/en/Logger.md +206 -0
- package/doc/en/MCP.md +293 -0
- package/doc/en/Middlewares.md +213 -0
- package/doc/en/Migrations.md +202 -0
- package/doc/en/MongoEmbedded.md +149 -0
- package/doc/en/Monitor.md +164 -0
- package/doc/en/Mutex.md +27 -25
- package/doc/en/NATS.md +246 -0
- package/doc/en/NativeAddons.md +212 -0
- package/doc/en/Objects.md +143 -0
- package/doc/en/Overview.md +62 -85
- package/doc/en/Packaging.md +193 -0
- package/doc/en/ProjectStructure.md +124 -0
- package/doc/en/Queue.md +269 -0
- package/doc/en/Schedules.md +217 -0
- package/doc/en/Security.md +10 -9
- package/doc/en/ServiceCalls.md +504 -0
- package/doc/en/Time.md +19 -20
- package/doc/en/UpgradingFrom1.md +435 -0
- package/doc/en/UpgradingFrom2.md +315 -0
- package/doc/en/Workspaces.md +189 -0
- package/doc/en/examples/BackgroundJobs.md +677 -0
- package/doc/en/examples/CommandLineTool.md +664 -0
- package/doc/en/examples/DesktopApp.md +809 -0
- package/doc/en/examples/DeviceService.md +607 -0
- package/doc/en/examples/MCPServer.md +653 -0
- package/doc/en/examples/README.md +16 -0
- package/doc/en/examples/RestAPI.md +490 -0
- package/doc/en/examples/ServiceCalls.md +829 -0
- package/doc/en/examples/WebApp.md +568 -0
- package/doc/zh/Application.md +75 -0
- package/doc/zh/CLI.md +250 -0
- package/doc/zh/Cache.md +328 -0
- package/doc/zh/Command.md +78 -0
- package/doc/zh/ContainerdIntegration.md +9 -9
- package/doc/zh/Controllers.md +228 -0
- package/doc/zh/DBus.md +257 -0
- package/doc/zh/DTOValidation.md +49 -19
- package/doc/zh/Database.md +175 -0
- package/doc/zh/DatabaseDrivers.md +261 -0
- package/doc/zh/Decorator.md +25 -18
- package/doc/zh/DockerIntegration.md +6 -6
- package/doc/zh/Entities.md +224 -0
- package/doc/zh/Entrypoint.md +193 -0
- package/doc/zh/Exceptions.md +158 -0
- package/doc/zh/GRPC.md +226 -0
- package/doc/zh/GettingStarted.md +148 -0
- package/doc/zh/HTTP.md +445 -0
- package/doc/zh/HelperFunctions.md +2 -2
- package/doc/zh/I18n.md +26 -26
- package/doc/zh/Injection.md +129 -0
- package/doc/zh/Installers.md +232 -0
- package/doc/zh/Logger.md +188 -0
- package/doc/zh/MCP.md +265 -0
- package/doc/zh/Middlewares.md +198 -0
- package/doc/zh/Migrations.md +178 -0
- package/doc/zh/MongoEmbedded.md +118 -0
- package/doc/zh/Monitor.md +145 -0
- package/doc/zh/Mutex.md +10 -10
- package/doc/zh/NATS.md +207 -0
- package/doc/zh/NativeAddons.md +180 -0
- package/doc/zh/Objects.md +119 -0
- package/doc/zh/Overview.md +46 -71
- package/doc/zh/Packaging.md +154 -0
- package/doc/zh/ProjectStructure.md +102 -0
- package/doc/zh/Queue.md +214 -0
- package/doc/zh/Schedules.md +193 -0
- package/doc/zh/Security.md +6 -6
- package/doc/zh/ServiceCalls.md +459 -0
- package/doc/zh/Time.md +2 -2
- package/doc/zh/UpgradingFrom1.md +347 -0
- package/doc/zh/UpgradingFrom2.md +230 -0
- package/doc/zh/Workspaces.md +150 -0
- package/doc/zh/examples/BackgroundJobs.md +618 -0
- package/doc/zh/examples/CommandLineTool.md +618 -0
- package/doc/zh/examples/DesktopApp.md +748 -0
- package/doc/zh/examples/DeviceService.md +546 -0
- package/doc/zh/examples/MCPServer.md +604 -0
- package/doc/zh/examples/README.md +14 -0
- package/doc/zh/examples/RestAPI.md +458 -0
- package/doc/zh/examples/ServiceCalls.md +765 -0
- package/doc/zh/examples/WebApp.md +520 -0
- package/package.json +46 -17
- package/doc/en/ActionPattern.md +0 -408
- package/doc/en/Core.md +0 -312
- package/doc/en/ORMIntegration.md +0 -341
- package/doc/zh/ActionPattern.md +0 -334
- package/doc/zh/Core.md +0 -256
- package/doc/zh/ORMIntegration.md +0 -319
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
</div>
|
|
6
6
|
|
|
@@ -14,18 +14,19 @@
|
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
+
English | [中文](README.zh-CN.md)
|
|
17
18
|
|
|
18
19
|
# lakutata
|
|
19
20
|
|
|
20
|
-
An IoC-based application framework for Node.js and TypeScript
|
|
21
|
-
desktop (Electron) applications and embedded devices. An application is a tree of objects
|
|
22
|
-
|
|
23
|
-
(Commander), service RPC (HTTP, Socket.IO, JSON-RPC 2.0, gRPC, NATS, Electron IPC)
|
|
24
|
-
can
|
|
21
|
+
An IoC-based application framework for Node.js and TypeScript, with one programming model for web services, CLI tools,
|
|
22
|
+
desktop (Electron) applications and embedded devices. An application is a tree of objects (components, providers,
|
|
23
|
+
controllers) that a container creates. DTOs validate their options and inputs, and transports expose the controllers:
|
|
24
|
+
HTTP (Express, Fastify), CLI (Commander), service RPC (HTTP, Socket.IO, JSON-RPC 2.0, gRPC, NATS, Electron IPC),
|
|
25
|
+
schedules and message queues. One controller method can serve all of them at once.
|
|
25
26
|
|
|
26
|
-
This package is the framework: it re-exports the `@lakutata/*` packages under the subpaths listed below
|
|
27
|
-
|
|
28
|
-
with examples
|
|
27
|
+
This package is the framework itself: it re-exports the `@lakutata/*` packages under the subpaths listed below and
|
|
28
|
+
presets two components in every application, `log` and `entrypoint`. The typings of each subpath document every
|
|
29
|
+
declaration with examples, and each `@lakutata/*` package has its own README.
|
|
29
30
|
|
|
30
31
|
## Installation
|
|
31
32
|
|
|
@@ -34,19 +35,27 @@ npx @lakutata/cli create --name my-app # a new project from a template (web, s
|
|
|
34
35
|
npm install lakutata # or the framework in an existing project
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
Node.js 22
|
|
38
|
-
`
|
|
38
|
+
The framework needs Node.js `^22.13.0 || >=24.11.0`: 22.13 or a later 22.x, or 24.11 and later (not 23). Projects
|
|
39
|
+
use ES modules (`"type": "module"`), as the templates do; the package also ships CommonJS builds. The TypeScript
|
|
40
|
+
options that the framework needs are published as `lakutata/tsconfig.json`:
|
|
39
41
|
|
|
40
42
|
```json
|
|
41
43
|
{
|
|
42
44
|
"extends": "lakutata/tsconfig.json",
|
|
43
|
-
"compilerOptions": {
|
|
45
|
+
"compilerOptions": {
|
|
46
|
+
"rootDir": "src",
|
|
47
|
+
"outDir": "build"
|
|
48
|
+
},
|
|
49
|
+
"include": ["src"]
|
|
44
50
|
}
|
|
45
51
|
```
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
Keep `include`: the published options compile JavaScript files too (`allowJs`), so without it a configuration file at
|
|
54
|
+
the root of the project (`eslint.config.js`, `vite.config.ts`) breaks the build.
|
|
55
|
+
|
|
56
|
+
The transports and integrations rely on optional peer dependencies, which you install only when you use them: `express`
|
|
57
|
+
or `fastify`, `commander`, `socket.io`, `ws`, the database drivers (`pg`, `mysql2`, `better-sqlite3`…) and the cache
|
|
58
|
+
stores (`redis`…). Each package's README lists its own.
|
|
50
59
|
|
|
51
60
|
## Usage
|
|
52
61
|
|
|
@@ -90,45 +99,56 @@ Application
|
|
|
90
99
|
|
|
91
100
|
| Subpath | Package | What it provides |
|
|
92
101
|
|---|---|---|
|
|
93
|
-
| `lakutata` | `@lakutata/core` | `Application`, `
|
|
94
|
-
| `lakutata/decorator/di` | `@lakutata/core` | `@Inject`, `@Configurable`, `@Autoload`, `@Singleton`, `@Scoped`, `@Transient` |
|
|
102
|
+
| `lakutata` | `@lakutata/core` | `Application`, `Component`, `Provider`, `BaseObject`, `Container`, `DTO`, `Exception`, `Time`, `isPackaged`, `resourcesPath`, the validation schemas and messages |
|
|
103
|
+
| `lakutata/decorator/di` | `@lakutata/core` | `@Inject`, `@Configurable`, `@Autoload`, `@Lifetime`, `@Singleton`, `@Scoped`, `@Transient` |
|
|
95
104
|
| `lakutata/decorator/dto` | `@lakutata/core` | `@Expect`, `@Accept`, `@Return`, `@IndexSignature` |
|
|
96
105
|
| `lakutata/decorator/asst` | `@lakutata/core` | `@Before`, `@After` |
|
|
97
106
|
| `lakutata/dtos` | `@lakutata/core` | `PaginationSearchDTO`, `PaginationResultDTO`, `paginator`, `FlexibleDTO`, the JSON Schema conversion |
|
|
98
107
|
| `lakutata/com/entrypoint` | `@lakutata/entrypoint` | `Entrypoint`, `buildEntrypoints`, `Controller`, the contexts, the results, the access control, the middlewares, `httpServiceEntrypoint`, `scheduleEntrypoint` |
|
|
99
108
|
| `lakutata/decorator/ctrl` | `@lakutata/entrypoint` | `@HTTPAction`, `@GET`…`@OPTIONS`, `@CLIAction`, `@ServiceAction`, `@Schedule`, `@Prefix`, `@UseMiddlewares` |
|
|
100
|
-
| `lakutata/adapter/express`, `lakutata/adapter/fastify` | `@lakutata/entrypoint` | The HTTP transports, `staticUI` |
|
|
109
|
+
| `lakutata/adapter/express`, `lakutata/adapter/fastify` | `@lakutata/entrypoint` | The HTTP transports, `staticUI` (Express only) |
|
|
101
110
|
| `lakutata/adapter/commander` | `@lakutata/entrypoint` | The CLI transport |
|
|
102
111
|
| `lakutata/adapter/socket.io`, `lakutata/adapter/jsonrpc`, `lakutata/adapter/electron` | `@lakutata/entrypoint` | The service transports |
|
|
103
|
-
| `lakutata/com/logger` | `@lakutata/logger` | The `Logger` component
|
|
112
|
+
| `lakutata/com/logger` | `@lakutata/logger` | The `Logger` component preset as `log` (pino-compatible JSON lines) |
|
|
104
113
|
| `lakutata/orm`, `lakutata/decorator/orm` | `@lakutata/orm` | TypeORM, its decorators |
|
|
105
114
|
| `lakutata/com/database`, `lakutata/provider/database` | `@lakutata/orm` | The `Database` component and provider, the migration commands |
|
|
106
115
|
| `lakutata/com/cacher` | `@lakutata/cache` | The `Cacher` component: memory, file, Redis, Memcached, MongoDB, SQLite, PostgreSQL, MySQL stores |
|
|
107
116
|
| `lakutata/com/mutex` | `@lakutata/mutex` | The `Mutex` component, `@Synchronized` |
|
|
117
|
+
| `lakutata/com/queue` | `@lakutata/queue` | The `Queue` component, `@QueueAction`, `queueEntrypoint`: message queues in memory, Redis (BullMQ), NATS JetStream, RabbitMQ or Kafka |
|
|
108
118
|
| `lakutata/com/i18n` | `@lakutata/i18n` | The `I18n` component, the `Translator`, the language middleware |
|
|
109
119
|
| `lakutata/com/docker` | `@lakutata/docker` | The `Docker` component |
|
|
110
120
|
| `lakutata/com/containerd` | `@lakutata/containerd` | The `Containerd` component (containerd without Docker, BuildKit builds) |
|
|
111
121
|
| `lakutata/com/monitor` | `@lakutata/monitor` | The CPU, memory, event loop and HTTP monitors |
|
|
112
122
|
| `lakutata/security`, `lakutata/provider/passwordHash` | `@lakutata/security` | Hashing, ciphers, signatures, the `PasswordHash` provider |
|
|
113
123
|
| `lakutata/utils` | `@lakutata/utils` | The helpers (strings, objects, arrays, time, files, globs, encodings, guards) |
|
|
114
|
-
| `lakutata/tsconfig.json` | | The compiler options
|
|
124
|
+
| `lakutata/tsconfig.json` | | The compiler options for applications |
|
|
115
125
|
|
|
116
|
-
|
|
117
|
-
`@lakutata/grpc` (gRPC client, server and service transport), `@lakutata/nats` (NATS component and
|
|
118
|
-
`@lakutata/dbus` (D-Bus)
|
|
126
|
+
Not part of this package: `@lakutata/cli` (the `lakutata` command for projects, bundles, executables, installers and
|
|
127
|
+
migrations), `@lakutata/grpc` (a gRPC client, server and service transport), `@lakutata/nats` (a NATS component and
|
|
128
|
+
service transport), `@lakutata/dbus` (D-Bus) and `@lakutata/mcp` (the Model Context Protocol).
|
|
119
129
|
|
|
120
130
|
## Errors
|
|
121
131
|
|
|
122
|
-
The framework's exceptions extend `Exception` (from `lakutata`)
|
|
123
|
-
and name, and a `statusCode` the HTTP transports
|
|
124
|
-
access, 404 for a missing route or action, 409
|
|
132
|
+
The framework's exceptions extend `Exception` (from `lakutata`). Each one has an `errno` (`E_…`), a `message`, the
|
|
133
|
+
application's id and name, and a `statusCode` that the HTTP transports use as the response status: 500 by default, 400
|
|
134
|
+
for invalid input, 403 when access is denied, 404 for a missing route or action, 409 when a lock is not acquired, and so
|
|
135
|
+
on. Each package's README lists its exceptions.
|
|
125
136
|
|
|
126
137
|
## See also
|
|
127
138
|
|
|
128
|
-
- The
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
- The website, [lakutata.com](https://lakutata.com): the guides, the examples and the API reference, in English and in
|
|
140
|
+
Chinese.
|
|
141
|
+
- The guides, in this package: `doc/en` (English) and `doc/zh` (Chinese): `Overview.md`, `GettingStarted.md`,
|
|
142
|
+
`ProjectStructure.md`, `UpgradingFrom2.md`, `UpgradingFrom1.md`, `Application.md`, `Objects.md`, `Injection.md`,
|
|
143
|
+
`DTOValidation.md`, `Exceptions.md`, `Logger.md`, `Decorator.md`, `Time.md`, `HelperFunctions.md`, `Controllers.md`,
|
|
144
|
+
`Entrypoint.md`, `Middlewares.md`, `HTTP.md`, `CLI.md`, `ServiceCalls.md`, `GRPC.md`, `NATS.md`, `Schedules.md`,
|
|
145
|
+
`Queue.md`, `Database.md`, `DatabaseDrivers.md`, `MongoEmbedded.md`, `Entities.md`, `Migrations.md`, `Cache.md`,
|
|
146
|
+
`Mutex.md`, `I18n.md`, `DockerIntegration.md`, `ContainerdIntegration.md`, `Monitor.md`, `Security.md`, `DBus.md`,
|
|
147
|
+
`MCP.md`, `Command.md`, `Workspaces.md`, `NativeAddons.md`, `Packaging.md`, `Installers.md`; and the examples, in
|
|
148
|
+
`doc/en/examples` and `doc/zh/examples`: whole applications built from the templates.
|
|
149
|
+
- `@lakutata/cli`: creating, building and packaging applications.
|
|
150
|
+
- The official Agent Skill for AI coding assistants that work on lakutata projects:
|
|
151
|
+
[lakutata.com/skill](https://lakutata.com/skill/).
|
|
132
152
|
|
|
133
153
|
## License
|
|
134
154
|
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+
)
|
|
10
|
+
)
|
|
11
|
+
)
|
|
12
|
+
)
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
[English](README.md) | 中文
|
|
18
|
+
|
|
19
|
+
# lakutata
|
|
20
|
+
|
|
21
|
+
一个基于 IoC 的 Node.js 和 TypeScript 应用框架,让 Web 服务、命令行工具、桌面(Electron)应用和嵌入式设备共用同一套编程模型。应用是一棵由容器创建的对象树(组件、提供者、控制器)。DTO 校验对象的选项和输入,各种传输方式把控制器暴露出去:HTTP(Express、Fastify)、CLI(Commander)、服务调用(HTTP、Socket.IO、JSON-RPC 2.0、gRPC、NATS、Electron IPC)、定时任务和消息队列。同一个控制器方法可以同时通过所有这些方式调用。
|
|
22
|
+
|
|
23
|
+
这个包就是框架本身:它通过下面列出的子路径重新导出各个 `@lakutata/*` 包,并为每个应用预置两个组件:`log` 和 `entrypoint`。各子路径的类型声明中,每一项都附有说明和示例,每个 `@lakutata/*` 包也都有自己的 README。
|
|
24
|
+
|
|
25
|
+
## 安装
|
|
26
|
+
|
|
27
|
+
```shell
|
|
28
|
+
npx @lakutata/cli create --name my-app # 用模板创建新项目(Web、服务、CLI、Electron……)
|
|
29
|
+
npm install lakutata # 或者在已有项目中安装框架
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
框架需要 Node.js `^22.13.0 || >=24.11.0`:22.13 或更高的 22.x 版本,或者 24.11 及以上(不支持 23)。项目使用 ES 模块(`"type": "module"`),模板也是如此;这个包也提供 CommonJS 版本。框架需要的 TypeScript 选项发布为 `lakutata/tsconfig.json`:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"extends": "lakutata/tsconfig.json",
|
|
37
|
+
"compilerOptions": {
|
|
38
|
+
"rootDir": "src",
|
|
39
|
+
"outDir": "build"
|
|
40
|
+
},
|
|
41
|
+
"include": ["src"]
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
请保留 `include`:发布的选项也会编译 JavaScript 文件(`allowJs`),没有它的话,项目根目录下的配置文件(`eslint.config.js`、`vite.config.ts`)会让构建失败。
|
|
46
|
+
|
|
47
|
+
传输方式和各项集成所需的 peer 依赖都是可选的,用到时才需要安装:`express` 或 `fastify`、`commander`、`socket.io`、`ws`、数据库驱动(`pg`、`mysql2`、`better-sqlite3`……)以及缓存存储(`redis`……)。各个包的 README 列出了各自需要的依赖。
|
|
48
|
+
|
|
49
|
+
## 用法
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import {Application, DTO, type ILogger} from 'lakutata'
|
|
53
|
+
import {buildEntrypoints, Controller} from 'lakutata/com/entrypoint'
|
|
54
|
+
import {GET, ServiceAction} from 'lakutata/decorator/ctrl'
|
|
55
|
+
import {Expect} from 'lakutata/decorator/dto'
|
|
56
|
+
import {expressHTTPEntrypoint} from 'lakutata/adapter/express'
|
|
57
|
+
|
|
58
|
+
class GreetDTO extends DTO {
|
|
59
|
+
@Expect(DTO.String().optional().default('world'))
|
|
60
|
+
public name: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class GreetController extends Controller {
|
|
64
|
+
//GET /greet?name=you,以及服务动作 {cmd: 'greet', name: 'you'}
|
|
65
|
+
@GET('/greet', GreetDTO)
|
|
66
|
+
@ServiceAction({cmd: 'greet'}, GreetDTO)
|
|
67
|
+
public async greet(input: GreetDTO): Promise<{ message: string }> {
|
|
68
|
+
return {message: `Hello, ${input.name}!`}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Application
|
|
73
|
+
.run(() => ({
|
|
74
|
+
id: 'com.example.greeter',
|
|
75
|
+
name: 'Greeter',
|
|
76
|
+
components: {
|
|
77
|
+
entrypoint: buildEntrypoints({
|
|
78
|
+
controllers: [GreetController],
|
|
79
|
+
http: expressHTTPEntrypoint({port: 8080})
|
|
80
|
+
})
|
|
81
|
+
},
|
|
82
|
+
bootstrap: ['entrypoint']
|
|
83
|
+
}))
|
|
84
|
+
.onLaunched((app: Application, log: ILogger): void => log.info('%s started', app.appName))
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## API
|
|
88
|
+
|
|
89
|
+
| 子路径 | 包 | 提供什么 |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `lakutata` | `@lakutata/core` | `Application`、`Component`、`Provider`、`BaseObject`、`Container`、`DTO`、`Exception`、`Time`、`isPackaged`、`resourcesPath`、校验规则和校验消息 |
|
|
92
|
+
| `lakutata/decorator/di` | `@lakutata/core` | `@Inject`、`@Configurable`、`@Autoload`、`@Lifetime`、`@Singleton`、`@Scoped`、`@Transient` |
|
|
93
|
+
| `lakutata/decorator/dto` | `@lakutata/core` | `@Expect`、`@Accept`、`@Return`、`@IndexSignature` |
|
|
94
|
+
| `lakutata/decorator/asst` | `@lakutata/core` | `@Before`、`@After` |
|
|
95
|
+
| `lakutata/dtos` | `@lakutata/core` | `PaginationSearchDTO`、`PaginationResultDTO`、`paginator`、`FlexibleDTO`、JSON Schema 转换 |
|
|
96
|
+
| `lakutata/com/entrypoint` | `@lakutata/entrypoint` | `Entrypoint`、`buildEntrypoints`、`Controller`、各种上下文、各种结果、访问控制、中间件、`httpServiceEntrypoint`、`scheduleEntrypoint` |
|
|
97
|
+
| `lakutata/decorator/ctrl` | `@lakutata/entrypoint` | `@HTTPAction`、`@GET`…`@OPTIONS`、`@CLIAction`、`@ServiceAction`、`@Schedule`、`@Prefix`、`@UseMiddlewares` |
|
|
98
|
+
| `lakutata/adapter/express`、`lakutata/adapter/fastify` | `@lakutata/entrypoint` | HTTP 传输、`staticUI`(仅 Express) |
|
|
99
|
+
| `lakutata/adapter/commander` | `@lakutata/entrypoint` | CLI 传输 |
|
|
100
|
+
| `lakutata/adapter/socket.io`、`lakutata/adapter/jsonrpc`、`lakutata/adapter/electron` | `@lakutata/entrypoint` | 服务传输 |
|
|
101
|
+
| `lakutata/com/logger` | `@lakutata/logger` | `Logger` 组件,预置为 `log`(输出与 pino 兼容的 JSON 行) |
|
|
102
|
+
| `lakutata/orm`、`lakutata/decorator/orm` | `@lakutata/orm` | TypeORM 及其装饰器 |
|
|
103
|
+
| `lakutata/com/database`、`lakutata/provider/database` | `@lakutata/orm` | `Database` 组件和提供者、迁移命令 |
|
|
104
|
+
| `lakutata/com/cacher` | `@lakutata/cache` | `Cacher` 组件:存储可以是内存、文件、Redis、Memcached、MongoDB、SQLite、PostgreSQL、MySQL |
|
|
105
|
+
| `lakutata/com/mutex` | `@lakutata/mutex` | `Mutex` 组件、`@Synchronized` |
|
|
106
|
+
| `lakutata/com/queue` | `@lakutata/queue` | `Queue` 组件、`@QueueAction`、`queueEntrypoint`:基于内存、Redis(BullMQ)、NATS JetStream、RabbitMQ 或 Kafka 的消息队列 |
|
|
107
|
+
| `lakutata/com/i18n` | `@lakutata/i18n` | `I18n` 组件、`Translator`、语言中间件 |
|
|
108
|
+
| `lakutata/com/docker` | `@lakutata/docker` | `Docker` 组件 |
|
|
109
|
+
| `lakutata/com/containerd` | `@lakutata/containerd` | `Containerd` 组件(不依赖 Docker 的 containerd,用 BuildKit 构建镜像) |
|
|
110
|
+
| `lakutata/com/monitor` | `@lakutata/monitor` | CPU、内存、事件循环和 HTTP 监控器 |
|
|
111
|
+
| `lakutata/security`、`lakutata/provider/passwordHash` | `@lakutata/security` | 哈希、加解密、签名、`PasswordHash` 提供者 |
|
|
112
|
+
| `lakutata/utils` | `@lakutata/utils` | 辅助函数(字符串、对象、数组、时间、文件、glob、编码、类型守卫) |
|
|
113
|
+
| `lakutata/tsconfig.json` | | 应用的编译选项 |
|
|
114
|
+
|
|
115
|
+
不在本包中的:`@lakutata/cli`(`lakutata` 命令:创建项目,制作单文件包、可执行文件和安装包,执行迁移)、`@lakutata/grpc`(gRPC 客户端、服务端和服务传输)、`@lakutata/nats`(NATS 组件和服务传输)、`@lakutata/dbus`(D-Bus)和 `@lakutata/mcp`(模型上下文协议)。
|
|
116
|
+
|
|
117
|
+
## 错误
|
|
118
|
+
|
|
119
|
+
框架的异常都继承自 `Exception`(来自 `lakutata`)。每个异常都有 `errno`(`E_…`)、`message`、应用的 ID 和名称,以及 `statusCode`,HTTP 传输把它用作响应的状态码:默认是 500,输入无效时是 400,访问被拒绝时是 403,路由或动作不存在时是 404,没有拿到锁时是 409,等等。各个包的 README 列出了各自的异常。
|
|
120
|
+
|
|
121
|
+
## 另见
|
|
122
|
+
|
|
123
|
+
- 网站 <https://lakutata.com/zh/>:指南、示例和 API 参考,中英文都有。
|
|
124
|
+
- 指南在这个包的 `doc/zh`(中文)和 `doc/en`(英文)中:`Overview.md`、`GettingStarted.md`、`ProjectStructure.md`、`UpgradingFrom2.md`、`UpgradingFrom1.md`、`Application.md`、`Objects.md`、`Injection.md`、`DTOValidation.md`、`Exceptions.md`、`Logger.md`、`Decorator.md`、`Time.md`、`HelperFunctions.md`、`Controllers.md`、`Entrypoint.md`、`Middlewares.md`、`HTTP.md`、`CLI.md`、`ServiceCalls.md`、`GRPC.md`、`NATS.md`、`Schedules.md`、`Queue.md`、`Database.md`、`DatabaseDrivers.md`、`MongoEmbedded.md`、`Entities.md`、`Migrations.md`、`Cache.md`、`Mutex.md`、`I18n.md`、`DockerIntegration.md`、`ContainerdIntegration.md`、`Monitor.md`、`Security.md`、`DBus.md`、`MCP.md`、`Command.md`、`Workspaces.md`、`NativeAddons.md`、`Packaging.md`、`Installers.md`;示例在 `doc/zh/examples` 和 `doc/en/examples` 中:从模板构建的完整应用。
|
|
125
|
+
- `@lakutata/cli`:创建、构建和打包应用。
|
|
126
|
+
- 官方 Agent Skill(智能体技能),供 AI 编程助手在 lakutata 项目中使用:<https://lakutata.com/zh/skill/>。
|
|
127
|
+
|
|
128
|
+
## 许可证
|
|
129
|
+
|
|
130
|
+
Lakutata 使用 [MIT 许可证](LICENSE)。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@lakutata/queue';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("@lakutata/queue"), exports);
|
|
18
|
+
|
|
19
|
+
//The default of the entry: the entry itself (scripts/package-build/cjs-package.mjs)
|
|
20
|
+
if (!Object.prototype.hasOwnProperty.call(exports, 'default')) Object.defineProperty(exports, 'default', {value: exports})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@lakutata/queue';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@lakutata/queue';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Lakutata Application
|
|
2
|
+
|
|
3
|
+
The **application** is the root object of a Lakutata program. `Application.run()` creates it in a new root container,
|
|
4
|
+
registers the objects it declares, runs its bootstrap steps, and ends it gracefully on a shutdown signal. This page
|
|
5
|
+
covers its options, the fluent API, the lifecycle, the mode and packed applications. The objects it creates are
|
|
6
|
+
described in [Objects](Objects.md), and how they obtain one another in [Injection](Injection.md).
|
|
7
|
+
|
|
8
|
+
## 1. Options
|
|
9
|
+
|
|
10
|
+
`Application.run(options)` — or `run(() => options)`, a function called at launch that may be async — takes these
|
|
11
|
+
options:
|
|
12
|
+
|
|
13
|
+
| Option | Meaning |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `id`, `name` | Required. The ID (also the `process.title`) and the name of the application (`app.appId`, `app.appName`) |
|
|
16
|
+
| `timezone` | An IANA time zone, or `'auto'` (default) for the system's; written to `TZ` |
|
|
17
|
+
| `mode` | `'development'` or `'production'`, when the environment gives none (see section 4) |
|
|
18
|
+
| `shutdownSignals` | The signals that end the application gracefully (default `['SIGTERM', 'SIGINT']`), or `false` |
|
|
19
|
+
| `components`, `providers` | The components and providers by name: `{class, ...options}` |
|
|
20
|
+
| `objects` | Other objects: `{named: {...}, anonymous: [...]}` |
|
|
21
|
+
| `bootstrap` | The steps run in order at launch: a name, a symbol or a class (the object is created), or an async function that receives the application |
|
|
22
|
+
| `checkOptions` | Check the options of the declared objects at launch (default `true`) |
|
|
23
|
+
|
|
24
|
+
A declaration without `class` adds options to an object of the same name that the framework presets: the `lakutata`
|
|
25
|
+
package presets `log` (the `Logger`) and `entrypoint` (the `Entrypoint`), so `log: {level: 'debug'}` sets the level of
|
|
26
|
+
the preset logger. `Application.preset(options)` presets objects for every application in the process.
|
|
27
|
+
|
|
28
|
+
## 2. The fluent API
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import {Application, type ApplicationExitReason, type ILogger} from 'lakutata'
|
|
32
|
+
|
|
33
|
+
Application
|
|
34
|
+
//Environment variables, set at launch before the options function runs
|
|
35
|
+
.env({TZ_NAME: 'Asia/Shanghai'})
|
|
36
|
+
//Path aliases: '@data' in a path passed to path.resolve() or app.alias.resolve(); the directory is created when missing
|
|
37
|
+
.alias({'@data': './data'}, true)
|
|
38
|
+
.run(() => ({
|
|
39
|
+
id: 'com.example.app',
|
|
40
|
+
name: 'Example',
|
|
41
|
+
components: {}
|
|
42
|
+
}))
|
|
43
|
+
//Called once the bootstrap has completed (not awaited)
|
|
44
|
+
.onLaunched((app: Application, log: ILogger): void => log.info('%s launched in %s mode', app.appName, app.mode()))
|
|
45
|
+
//Called and awaited when the application exits, before its objects are destroyed
|
|
46
|
+
.onDone(async (app: Application, log: ILogger, reason: ApplicationExitReason): Promise<void> => {
|
|
47
|
+
log.info('%s done (exit code %d%s)', app.appName, reason.code, reason.signal ? `, ${reason.signal}` : '')
|
|
48
|
+
})
|
|
49
|
+
//An uncaught exception in the process; the application keeps running
|
|
50
|
+
.onUncaughtException((error: Error, log: ILogger): void => log.warn(error.message))
|
|
51
|
+
//The launch failed: the returned number is the exit code (1 when none)
|
|
52
|
+
.onFatalException((error: Error, log: ILogger): number => {
|
|
53
|
+
log.error('Launch failed: %s', error.message)
|
|
54
|
+
return 100
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`app.exit(code)` ends the application gracefully with that exit code; `app.exit(true)` ends the process immediately with
|
|
59
|
+
exit code 2, skipping the done handlers and the teardown.
|
|
60
|
+
|
|
61
|
+
## 3. The lifecycle
|
|
62
|
+
|
|
63
|
+
1. The environment variables are set and the aliases registered (`@runtime` is the working directory).
|
|
64
|
+
2. The options are read and validated; the ID, the time zone and the mode are applied.
|
|
65
|
+
3. The application is created in a new root container: its objects are registered and its `bootstrap` runs in order.
|
|
66
|
+
4. The `launched()` hooks of the objects and the `onLaunched` handlers run.
|
|
67
|
+
|
|
68
|
+
- **Launch failure**: when the application cannot launch (invalid options, an object that fails to initialize, a
|
|
69
|
+
bootstrap step that fails), the `onFatalException` handler decides the exit code (1 when it returns none). Without a
|
|
70
|
+
handler, the error is logged and the process exits with code 1, as Node.js does on an uncaught exception, so whatever
|
|
71
|
+
runs it (Docker restart policies, Kubernetes, systemd, CI) knows it failed; objects already created (a listening
|
|
72
|
+
server, a connection) do not keep the process alive.
|
|
73
|
+
- **Shutdown signals**: on `SIGTERM` (`docker stop`, Kubernetes rolling updates, systemd) and `SIGINT` (Ctrl+C), the
|
|
74
|
+
application ends gracefully. The `onDone` handlers run first, while the application is still fully working (their
|
|
75
|
+
third argument says why it is exiting: `{code: 0, signal: 'SIGTERM'}`, or `{code}` after `app.exit(code)`). Then the
|
|
76
|
+
entrypoints stop accepting requests and let the running ones finish, the objects are destroyed, and the process exits
|
|
77
|
+
with code 0. A second signal (if the shutdown hangs), or a signal received while the application is still launching,
|
|
78
|
+
ends the process at once with code 128 + the signal number (143 for `SIGTERM`, 130 for `SIGINT`). The
|
|
79
|
+
`shutdownSignals` option accepts other signals (`['SIGTERM', 'SIGINT', 'SIGHUP']`), or `false` to leave them to
|
|
80
|
+
Node.js.
|
|
81
|
+
- **Nothing left to do**: when nothing keeps the process busy any more (no server, connection or timer), the application
|
|
82
|
+
ends gracefully, as with `app.exit(0)`: the `onDone` handlers run, the objects are destroyed, and the process exits
|
|
83
|
+
with the code it has (`process.exitCode`, 0 by default). A script can therefore just finish its work. An application
|
|
84
|
+
that has been disposed (`app.dispose()`, as in tests) leaves the end of the process to whatever runs it.
|
|
85
|
+
|
|
86
|
+
## 4. The mode
|
|
87
|
+
|
|
88
|
+
`app.mode()` returns `'development'` or `'production'`. The environment overrides the code, so the same build can run in
|
|
89
|
+
either mode: the `MODE` environment variable wins, then `NODE_ENV`, then the `mode` option, and `'development'`
|
|
90
|
+
otherwise. A `MODE` with an unknown value is ignored with a warning; a `NODE_ENV` with an unknown value (such as `test`)
|
|
91
|
+
is skipped. The resolved mode is written back to `MODE` and `NODE_ENV`, so libraries see the same mode. The variables
|
|
92
|
+
can come from the system, from `Application.env({MODE: 'production'})`, or from the `.env` file that Bun reads (when
|
|
93
|
+
running `bun App.js`; executables built by Bun do not read it).
|
|
94
|
+
|
|
95
|
+
## 5. The packed application
|
|
96
|
+
|
|
97
|
+
`lakutata package bundle`, `package exe` and `package installer` pack the compiled application into a bundle, an
|
|
98
|
+
executable or installers. When it runs packed, `isPackaged()` (from `lakutata`) returns `true`, and `resourcesPath()`
|
|
99
|
+
returns the directory of its resources, the files declared in the `lakutata.resources` of its `package.json`; when not
|
|
100
|
+
packed, it returns `undefined` and the application reads those files from where they are built. See
|
|
101
|
+
[Packaging](Packaging.md).
|
|
102
|
+
|
|
103
|
+
## 6. Entrypoints
|
|
104
|
+
|
|
105
|
+
The `entrypoint` component (`lakutata/com/entrypoint`) serves the controllers over HTTP, the CLI, service transports,
|
|
106
|
+
schedules and message queues. Configure it with `buildEntrypoints({controllers, http, cli, service, schedule, queue})`
|
|
107
|
+
and list it in `bootstrap`; see [Entrypoint](Entrypoint.md).
|