@application-kit/bootstrap 0.2.4 → 0.4.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/CHANGELOG.md +20 -0
- package/README.md +59 -3
- package/dist/cjs/consumer/consumer-bootstrap.d.ts +3 -0
- package/dist/cjs/consumer/consumer-bootstrap.js +17 -0
- package/dist/cjs/consumer/consumer-process.environment.d.ts +3 -0
- package/dist/cjs/consumer/consumer-process.environment.js +27 -0
- package/dist/cjs/consumer/index.d.ts +2 -0
- package/dist/cjs/consumer/index.js +18 -0
- package/dist/cjs/swagger/index.d.ts +3 -0
- package/dist/cjs/swagger/index.js +19 -0
- package/dist/cjs/swagger/setup-swagger.d.ts +3 -0
- package/dist/cjs/swagger/setup-swagger.js +25 -0
- package/dist/cjs/swagger/swagger-options.interface.d.ts +6 -0
- package/dist/cjs/swagger/swagger-options.interface.js +2 -0
- package/dist/cjs/swagger/swagger.environment.d.ts +3 -0
- package/dist/cjs/swagger/swagger.environment.js +25 -0
- package/dist/cjs/web/index.d.ts +2 -0
- package/dist/cjs/web/index.js +2 -0
- package/dist/cjs/web/web-bootstrap.d.ts +4 -0
- package/dist/cjs/web/web-bootstrap.js +20 -0
- package/dist/cjs/web/web-process.environment.d.ts +4 -0
- package/dist/cjs/web/web-process.environment.js +35 -0
- package/dist/esm/consumer/consumer-bootstrap.d.ts +3 -0
- package/dist/esm/consumer/consumer-bootstrap.js +10 -0
- package/dist/esm/consumer/consumer-process.environment.d.ts +3 -0
- package/dist/esm/consumer/consumer-process.environment.js +23 -0
- package/dist/esm/consumer/index.d.ts +2 -0
- package/dist/esm/consumer/index.js +2 -0
- package/dist/esm/swagger/index.d.ts +3 -0
- package/dist/esm/swagger/index.js +3 -0
- package/dist/esm/swagger/setup-swagger.d.ts +3 -0
- package/dist/esm/swagger/setup-swagger.js +18 -0
- package/dist/esm/swagger/swagger-options.interface.d.ts +6 -0
- package/dist/esm/swagger/swagger-options.interface.js +1 -0
- package/dist/esm/swagger/swagger.environment.d.ts +3 -0
- package/dist/esm/swagger/swagger.environment.js +21 -0
- package/dist/esm/web/index.d.ts +2 -0
- package/dist/esm/web/index.js +2 -0
- package/dist/esm/web/web-bootstrap.d.ts +4 -0
- package/dist/esm/web/web-bootstrap.js +13 -0
- package/dist/esm/web/web-process.environment.d.ts +4 -0
- package/dist/esm/web/web-process.environment.js +31 -0
- package/package.json +35 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @application-kit/bootstrap
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9ee9bfa: Вход `@application-kit/bootstrap/swagger`: `setupSwagger(app, { include, path?, version? })` публикует документ OpenAPI,
|
|
8
|
+
только если `SWAGGER_ENABLED` включён явно. `@nestjs/swagger` — optional peer, его тянет только этот вход.
|
|
9
|
+
|
|
10
|
+
## 0.3.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- c9f24d0: Процессы запускаются целиком из пакета, а переменные контракта чарта валидируются на старте:
|
|
15
|
+
|
|
16
|
+
- `webBootstrap(rootModule, options)` из `/web` читает `PORT` (по умолчанию 3000) и `TRUST_PROXY_HOPS` (по умолчанию 0), создаёт приложение через `createFastifyApplication`, слушает `0.0.0.0` и возвращает приложение;
|
|
17
|
+
- новый вход `/consumer`: `consumerBootstrap(rootModule, server)` читает `METRICS_PORT` (по умолчанию 3001), поднимает сервер `/metrics` и передаёт корневой модуль транспорту `server` (например `kafkaConsumerServer` из `@application-kit/kafka`) вместе с логгером `nestjs-pino`.
|
|
18
|
+
|
|
19
|
+
Значение, которое не является целым числом в допустимом диапазоне (`abc`, `-1`, `1.5`, порт больше 65535), роняет старт ошибкой `ClassValidationError` с именем переменной ещё до создания приложения. Раньше `Number('abc')` давал `NaN`, и доверенных прокси становилось молча ноль.
|
|
20
|
+
|
|
21
|
+
Для этих входов нужен peer `@libs-for-dev/nestjs-config-module` ^3.0.0 рядом с `class-transformer` и `class-validator`. Потребителю `createFastifyApplication` менять ничего не нужно.
|
|
22
|
+
|
|
3
23
|
## 0.2.4
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @application-kit/bootstrap
|
|
2
2
|
|
|
3
|
-
Бутстрап процессов NestJS: web на Fastify с
|
|
4
|
-
|
|
3
|
+
Бутстрап процессов NestJS: web на Fastify с периметром, consumer с сервером метрик и CLI на nestjs-console. Состав
|
|
4
|
+
модулей, контроллеры документа Swagger и хуки метрик знает приложение: пакет собирает процесс из его корневого модуля и опций. Порт, число
|
|
5
|
+
прокси и порт метрик — переменные окружения контракта чарта; невалидное значение роняет старт.
|
|
5
6
|
|
|
6
7
|
## Установка
|
|
7
8
|
|
|
@@ -17,13 +18,40 @@ Peer-зависимости — `@nestjs/common`, `@nestjs/core`, `nestjs-pino`;
|
|
|
17
18
|
|
|
18
19
|
| Вход | Для чего | Тянет |
|
|
19
20
|
|------|----------|-------|
|
|
20
|
-
| `@application-kit/bootstrap/web` | `createFastifyApplication` — web-процесс на Fastify | `@nestjs/platform-fastify`, `@fastify/cookie`, `class-validator`, `class-transformer`, `@opentelemetry/api` |
|
|
21
|
+
| `@application-kit/bootstrap/web` | `webBootstrap`, `createFastifyApplication` — web-процесс на Fastify | `@nestjs/platform-fastify`, `@fastify/cookie`, `class-validator`, `class-transformer`, `@opentelemetry/api`, `@libs-for-dev/nestjs-config-module` |
|
|
22
|
+
| `@application-kit/bootstrap/consumer` | `consumerBootstrap` — процесс-консьюмер без HTTP-слоя | `class-validator`, `class-transformer`, `@libs-for-dev/nestjs-config-module` |
|
|
21
23
|
| `@application-kit/bootstrap/cli` | `cliBootstrap` — CLI-процесс | `nestjs-console` |
|
|
24
|
+
| `@application-kit/bootstrap/swagger` | `setupSwagger` — документ OpenAPI web-процесса по выключателю | `@nestjs/swagger`, `class-validator`, `class-transformer`, `@libs-for-dev/nestjs-config-module` |
|
|
22
25
|
|
|
23
26
|
Корневого входа нет: web-процессу `nestjs-console` не нужен, CLI — Fastify.
|
|
24
27
|
|
|
28
|
+
## Окружение
|
|
29
|
+
|
|
30
|
+
| Переменная | Процесс | По умолчанию | |
|
|
31
|
+
|------------|---------|--------------|---|
|
|
32
|
+
| `PORT` | web | `3000` | порт `listen` на `0.0.0.0` |
|
|
33
|
+
| `TRUST_PROXY_HOPS` | web | `0` | сколько прокси перед приложением доверенные; `0` — только сокет |
|
|
34
|
+
| `METRICS_PORT` | consumer | `3001` | порт отдельного сервера `/metrics` |
|
|
35
|
+
| `SWAGGER_ENABLED` | web | `false` | публиковать ли документ `setupSwagger`; выключают `false`, `0` и пустая строка |
|
|
36
|
+
|
|
37
|
+
Значение числовых переменных — целое не меньше 0 (порт — не больше 65535). Иное (`abc`, `1.5`, `-1`) — `ClassValidationError` с именем
|
|
38
|
+
переменной до создания приложения: `Number('abc')` дал бы `NaN`, и доверенных прокси молча стало бы ноль.
|
|
39
|
+
|
|
25
40
|
## Web
|
|
26
41
|
|
|
42
|
+
```ts
|
|
43
|
+
import { webBootstrap } from '@application-kit/bootstrap/web'
|
|
44
|
+
|
|
45
|
+
void webBootstrap(AppModule, {
|
|
46
|
+
configure: (app) => {
|
|
47
|
+
setupMetricsHooks(app)
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`webBootstrap` берёт порт и прокси из окружения, собирает приложение через `createFastifyApplication`, слушает и
|
|
53
|
+
возвращает его. `createFastifyApplication` — для своего запуска, когда порт и прокси приходят не из окружения:
|
|
54
|
+
|
|
27
55
|
```ts
|
|
28
56
|
import { createFastifyApplication } from '@application-kit/bootstrap/web'
|
|
29
57
|
|
|
@@ -56,6 +84,34 @@ await app.listen(port, '0.0.0.0')
|
|
|
56
84
|
| `cookie` | `{}` | опции `@fastify/cookie`; `false` — плагин не регистрируется |
|
|
57
85
|
| `configure` | — | `(app) => void`, зовётся после хука request-id, до интерцептора и пайпа |
|
|
58
86
|
|
|
87
|
+
## Swagger
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { setupSwagger } from '@application-kit/bootstrap/swagger'
|
|
91
|
+
|
|
92
|
+
const options = {
|
|
93
|
+
configure: (app) => {
|
|
94
|
+
setupSwagger(app, { include: [HealthHttpModule, MetricsHttpModule] })
|
|
95
|
+
},
|
|
96
|
+
} satisfies FastifyApplicationOptionsInterface
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Документ описывает всю серверную поверхность и аутентификации не требует, поэтому без `SWAGGER_ENABLED` он не
|
|
100
|
+
публикуется. В документ попадают контроллеры модулей из `include`, `operationId` — имя метода. UI отдаётся по `path`
|
|
101
|
+
(по умолчанию `swagger`), JSON — по `<path>-json`, версия в `info` — `version` (по умолчанию `1.0`).
|
|
102
|
+
|
|
103
|
+
## Consumer
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { consumerBootstrap } from '@application-kit/bootstrap/consumer'
|
|
107
|
+
import { kafkaConsumerServer } from '@application-kit/kafka'
|
|
108
|
+
|
|
109
|
+
void consumerBootstrap(ConsumerModule, kafkaConsumerServer)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Сервер `/metrics` поднимается на `METRICS_PORT` со своим реестром метрик процесса, затем корневой модуль уходит
|
|
113
|
+
транспорту вместе с логгером `nestjs-pino`. Транспорт передаёт приложение: от брокера пакет не зависит.
|
|
114
|
+
|
|
59
115
|
## CLI
|
|
60
116
|
|
|
61
117
|
```ts
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.consumerBootstrap = void 0;
|
|
7
|
+
const metrics_1 = require("@application-kit/observability/metrics");
|
|
8
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
9
|
+
const nestjs_pino_1 = require("nestjs-pino");
|
|
10
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
11
|
+
const consumer_process_environment_js_1 = require("./consumer-process.environment.js");
|
|
12
|
+
const consumerBootstrap = async (rootModule, server) => {
|
|
13
|
+
const environment = (0, nestjs_config_module_1.exposeObjectWithValidation)(node_process_1.default.env, consumer_process_environment_js_1.ConsumerProcessEnvironment);
|
|
14
|
+
(0, metrics_1.startMetricsServer)({ port: environment.METRICS_PORT, registry: new metrics_1.MetricsRegistry() });
|
|
15
|
+
await server(rootModule, nestjs_pino_1.Logger);
|
|
16
|
+
};
|
|
17
|
+
exports.consumerBootstrap = consumerBootstrap;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ConsumerProcessEnvironment = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const MAX_PORT = 65_535;
|
|
16
|
+
class ConsumerProcessEnvironment {
|
|
17
|
+
METRICS_PORT = 3001;
|
|
18
|
+
}
|
|
19
|
+
exports.ConsumerProcessEnvironment = ConsumerProcessEnvironment;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsInt)(),
|
|
23
|
+
(0, class_validator_1.Max)(MAX_PORT),
|
|
24
|
+
(0, class_validator_1.Min)(0),
|
|
25
|
+
(0, class_transformer_1.Type)(() => Number),
|
|
26
|
+
__metadata("design:type", Object)
|
|
27
|
+
], ConsumerProcessEnvironment.prototype, "METRICS_PORT", void 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./consumer-bootstrap.js"), exports);
|
|
18
|
+
__exportStar(require("./consumer-process.environment.js"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
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("./setup-swagger.js"), exports);
|
|
18
|
+
__exportStar(require("./swagger-options.interface.js"), exports);
|
|
19
|
+
__exportStar(require("./swagger.environment.js"), exports);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setupSwagger = void 0;
|
|
7
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
8
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
9
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
10
|
+
const swagger_environment_js_1 = require("./swagger.environment.js");
|
|
11
|
+
const DEFAULT_PATH = 'swagger';
|
|
12
|
+
const DEFAULT_VERSION = '1.0';
|
|
13
|
+
const setupSwagger = (app, options) => {
|
|
14
|
+
const environment = (0, nestjs_config_module_1.exposeObjectWithValidation)(node_process_1.default.env, swagger_environment_js_1.SwaggerEnvironment);
|
|
15
|
+
if (!environment.SWAGGER_ENABLED) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const document = swagger_1.SwaggerModule.createDocument(app, new swagger_1.DocumentBuilder().setVersion(options.version ?? DEFAULT_VERSION)
|
|
19
|
+
.build(), {
|
|
20
|
+
include: options.include,
|
|
21
|
+
operationIdFactory: (_controllerKey, methodKey) => methodKey,
|
|
22
|
+
});
|
|
23
|
+
swagger_1.SwaggerModule.setup(options.path ?? DEFAULT_PATH, app, document);
|
|
24
|
+
};
|
|
25
|
+
exports.setupSwagger = setupSwagger;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SwaggerEnvironment = void 0;
|
|
13
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
14
|
+
const class_transformer_1 = require("class-transformer");
|
|
15
|
+
const class_validator_1 = require("class-validator");
|
|
16
|
+
class SwaggerEnvironment {
|
|
17
|
+
SWAGGER_ENABLED = false;
|
|
18
|
+
}
|
|
19
|
+
exports.SwaggerEnvironment = SwaggerEnvironment;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, class_transformer_1.Expose)(),
|
|
22
|
+
(0, class_validator_1.IsBoolean)(),
|
|
23
|
+
(0, nestjs_config_module_1.ParseBoolean)(),
|
|
24
|
+
__metadata("design:type", Object)
|
|
25
|
+
], SwaggerEnvironment.prototype, "SWAGGER_ENABLED", void 0);
|
package/dist/cjs/web/index.d.ts
CHANGED
package/dist/cjs/web/index.js
CHANGED
|
@@ -16,3 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./create-fastify-application.js"), exports);
|
|
18
18
|
__exportStar(require("./fastify-application-options.interface.js"), exports);
|
|
19
|
+
__exportStar(require("./web-bootstrap.js"), exports);
|
|
20
|
+
__exportStar(require("./web-process.environment.js"), exports);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
3
|
+
import type { FastifyApplicationOptionsInterface } from './fastify-application-options.interface.js';
|
|
4
|
+
export declare const webBootstrap: (rootModule: Type, options?: Omit<FastifyApplicationOptionsInterface, "trustProxyHops">) => Promise<NestFastifyApplication>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.webBootstrap = void 0;
|
|
7
|
+
const nestjs_config_module_1 = require("@libs-for-dev/nestjs-config-module");
|
|
8
|
+
const nestjs_pino_1 = require("nestjs-pino");
|
|
9
|
+
const node_process_1 = __importDefault(require("node:process"));
|
|
10
|
+
const create_fastify_application_js_1 = require("./create-fastify-application.js");
|
|
11
|
+
const web_process_environment_js_1 = require("./web-process.environment.js");
|
|
12
|
+
const LISTEN_HOST = '0.0.0.0';
|
|
13
|
+
const webBootstrap = async (rootModule, options = {}) => {
|
|
14
|
+
const environment = (0, nestjs_config_module_1.exposeObjectWithValidation)(node_process_1.default.env, web_process_environment_js_1.WebProcessEnvironment);
|
|
15
|
+
const app = await (0, create_fastify_application_js_1.createFastifyApplication)(rootModule, { ...options, trustProxyHops: environment.TRUST_PROXY_HOPS });
|
|
16
|
+
await app.listen(environment.PORT, LISTEN_HOST);
|
|
17
|
+
app.get(nestjs_pino_1.Logger).log(`Application is running on port "${environment.PORT}"`);
|
|
18
|
+
return app;
|
|
19
|
+
};
|
|
20
|
+
exports.webBootstrap = webBootstrap;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WebProcessEnvironment = void 0;
|
|
13
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
|
+
const class_validator_1 = require("class-validator");
|
|
15
|
+
const MAX_PORT = 65_535;
|
|
16
|
+
class WebProcessEnvironment {
|
|
17
|
+
PORT = 3000;
|
|
18
|
+
TRUST_PROXY_HOPS = 0;
|
|
19
|
+
}
|
|
20
|
+
exports.WebProcessEnvironment = WebProcessEnvironment;
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, class_transformer_1.Expose)(),
|
|
23
|
+
(0, class_validator_1.IsInt)(),
|
|
24
|
+
(0, class_validator_1.Max)(MAX_PORT),
|
|
25
|
+
(0, class_validator_1.Min)(0),
|
|
26
|
+
(0, class_transformer_1.Type)(() => Number),
|
|
27
|
+
__metadata("design:type", Object)
|
|
28
|
+
], WebProcessEnvironment.prototype, "PORT", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, class_transformer_1.Expose)(),
|
|
31
|
+
(0, class_validator_1.IsInt)(),
|
|
32
|
+
(0, class_validator_1.Min)(0),
|
|
33
|
+
(0, class_transformer_1.Type)(() => Number),
|
|
34
|
+
__metadata("design:type", Object)
|
|
35
|
+
], WebProcessEnvironment.prototype, "TRUST_PROXY_HOPS", void 0);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MetricsRegistry, startMetricsServer } from '@application-kit/observability/metrics';
|
|
2
|
+
import { exposeObjectWithValidation } from '@libs-for-dev/nestjs-config-module';
|
|
3
|
+
import { Logger } from 'nestjs-pino';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { ConsumerProcessEnvironment } from './consumer-process.environment.js';
|
|
6
|
+
export const consumerBootstrap = async (rootModule, server) => {
|
|
7
|
+
const environment = exposeObjectWithValidation(process.env, ConsumerProcessEnvironment);
|
|
8
|
+
startMetricsServer({ port: environment.METRICS_PORT, registry: new MetricsRegistry() });
|
|
9
|
+
await server(rootModule, Logger);
|
|
10
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Expose, Type } from 'class-transformer';
|
|
11
|
+
import { IsInt, Max, Min } from 'class-validator';
|
|
12
|
+
const MAX_PORT = 65_535;
|
|
13
|
+
export class ConsumerProcessEnvironment {
|
|
14
|
+
METRICS_PORT = 3001;
|
|
15
|
+
}
|
|
16
|
+
__decorate([
|
|
17
|
+
Expose(),
|
|
18
|
+
IsInt(),
|
|
19
|
+
Max(MAX_PORT),
|
|
20
|
+
Min(0),
|
|
21
|
+
Type(() => Number),
|
|
22
|
+
__metadata("design:type", Object)
|
|
23
|
+
], ConsumerProcessEnvironment.prototype, "METRICS_PORT", void 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { exposeObjectWithValidation } from '@libs-for-dev/nestjs-config-module';
|
|
2
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { SwaggerEnvironment } from './swagger.environment.js';
|
|
5
|
+
const DEFAULT_PATH = 'swagger';
|
|
6
|
+
const DEFAULT_VERSION = '1.0';
|
|
7
|
+
export const setupSwagger = (app, options) => {
|
|
8
|
+
const environment = exposeObjectWithValidation(process.env, SwaggerEnvironment);
|
|
9
|
+
if (!environment.SWAGGER_ENABLED) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const document = SwaggerModule.createDocument(app, new DocumentBuilder().setVersion(options.version ?? DEFAULT_VERSION)
|
|
13
|
+
.build(), {
|
|
14
|
+
include: options.include,
|
|
15
|
+
operationIdFactory: (_controllerKey, methodKey) => methodKey,
|
|
16
|
+
});
|
|
17
|
+
SwaggerModule.setup(options.path ?? DEFAULT_PATH, app, document);
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { ParseBoolean } from '@libs-for-dev/nestjs-config-module';
|
|
11
|
+
import { Expose } from 'class-transformer';
|
|
12
|
+
import { IsBoolean } from 'class-validator';
|
|
13
|
+
export class SwaggerEnvironment {
|
|
14
|
+
SWAGGER_ENABLED = false;
|
|
15
|
+
}
|
|
16
|
+
__decorate([
|
|
17
|
+
Expose(),
|
|
18
|
+
IsBoolean(),
|
|
19
|
+
ParseBoolean(),
|
|
20
|
+
__metadata("design:type", Object)
|
|
21
|
+
], SwaggerEnvironment.prototype, "SWAGGER_ENABLED", void 0);
|
package/dist/esm/web/index.d.ts
CHANGED
package/dist/esm/web/index.js
CHANGED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Type } from '@nestjs/common';
|
|
2
|
+
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
3
|
+
import type { FastifyApplicationOptionsInterface } from './fastify-application-options.interface.js';
|
|
4
|
+
export declare const webBootstrap: (rootModule: Type, options?: Omit<FastifyApplicationOptionsInterface, "trustProxyHops">) => Promise<NestFastifyApplication>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { exposeObjectWithValidation } from '@libs-for-dev/nestjs-config-module';
|
|
2
|
+
import { Logger } from 'nestjs-pino';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { createFastifyApplication } from './create-fastify-application.js';
|
|
5
|
+
import { WebProcessEnvironment } from './web-process.environment.js';
|
|
6
|
+
const LISTEN_HOST = '0.0.0.0';
|
|
7
|
+
export const webBootstrap = async (rootModule, options = {}) => {
|
|
8
|
+
const environment = exposeObjectWithValidation(process.env, WebProcessEnvironment);
|
|
9
|
+
const app = await createFastifyApplication(rootModule, { ...options, trustProxyHops: environment.TRUST_PROXY_HOPS });
|
|
10
|
+
await app.listen(environment.PORT, LISTEN_HOST);
|
|
11
|
+
app.get(Logger).log(`Application is running on port "${environment.PORT}"`);
|
|
12
|
+
return app;
|
|
13
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Expose, Type } from 'class-transformer';
|
|
11
|
+
import { IsInt, Max, Min } from 'class-validator';
|
|
12
|
+
const MAX_PORT = 65_535;
|
|
13
|
+
export class WebProcessEnvironment {
|
|
14
|
+
PORT = 3000;
|
|
15
|
+
TRUST_PROXY_HOPS = 0;
|
|
16
|
+
}
|
|
17
|
+
__decorate([
|
|
18
|
+
Expose(),
|
|
19
|
+
IsInt(),
|
|
20
|
+
Max(MAX_PORT),
|
|
21
|
+
Min(0),
|
|
22
|
+
Type(() => Number),
|
|
23
|
+
__metadata("design:type", Object)
|
|
24
|
+
], WebProcessEnvironment.prototype, "PORT", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
Expose(),
|
|
27
|
+
IsInt(),
|
|
28
|
+
Min(0),
|
|
29
|
+
Type(() => Number),
|
|
30
|
+
__metadata("design:type", Object)
|
|
31
|
+
], WebProcessEnvironment.prototype, "TRUST_PROXY_HOPS", void 0);
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@application-kit/bootstrap",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Бутстрап процессов NestJS: web на Fastify с периметром (доверенные прокси по хопам, request-id в каждом ответе, cookie, ValidationPipe с плоским списком ошибок, graceful shutdown)
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Бутстрап процессов NestJS: web на Fastify с периметром (доверенные прокси по хопам, request-id в каждом ответе, cookie, ValidationPipe с плоским списком ошибок, graceful shutdown), consumer с сервером метрик, CLI на nestjs-console с логгером pino; порты и прокси — из валидированного окружения",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bootstrap",
|
|
7
7
|
"fastify",
|
|
8
8
|
"nestjs",
|
|
9
|
-
"nestjs-console"
|
|
9
|
+
"nestjs-console",
|
|
10
|
+
"swagger"
|
|
10
11
|
],
|
|
11
12
|
"homepage": "https://gitlab.com/application-kit/application-kit/-/tree/main/packages/bootstrap",
|
|
12
13
|
"bugs": "https://gitlab.com/application-kit/application-kit/-/issues",
|
|
@@ -32,7 +33,27 @@
|
|
|
32
33
|
"default": "./dist/cjs/cli/index.js"
|
|
33
34
|
}
|
|
34
35
|
},
|
|
36
|
+
"./consumer": {
|
|
37
|
+
"import": {
|
|
38
|
+
"types": "./dist/esm/consumer/index.d.ts",
|
|
39
|
+
"default": "./dist/esm/consumer/index.js"
|
|
40
|
+
},
|
|
41
|
+
"require": {
|
|
42
|
+
"types": "./dist/cjs/consumer/index.d.ts",
|
|
43
|
+
"default": "./dist/cjs/consumer/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
35
46
|
"./package.json": "./package.json",
|
|
47
|
+
"./swagger": {
|
|
48
|
+
"import": {
|
|
49
|
+
"types": "./dist/esm/swagger/index.d.ts",
|
|
50
|
+
"default": "./dist/esm/swagger/index.js"
|
|
51
|
+
},
|
|
52
|
+
"require": {
|
|
53
|
+
"types": "./dist/cjs/swagger/index.d.ts",
|
|
54
|
+
"default": "./dist/cjs/swagger/index.js"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
36
57
|
"./web": {
|
|
37
58
|
"import": {
|
|
38
59
|
"types": "./dist/esm/web/index.d.ts",
|
|
@@ -51,7 +72,7 @@
|
|
|
51
72
|
"dist"
|
|
52
73
|
],
|
|
53
74
|
"scripts": {
|
|
54
|
-
"build": "rm -rf ./dist && node ../../scripts/barrels.mjs create ./src/cli && node ../../scripts/barrels.mjs create ./src/web && tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json && node ../../scripts/barrels.mjs clean ./src && node ../../scripts/mark-cjs.mjs ./dist/cjs",
|
|
75
|
+
"build": "rm -rf ./dist && node ../../scripts/barrels.mjs create ./src/cli && node ../../scripts/barrels.mjs create ./src/consumer && node ../../scripts/barrels.mjs create ./src/swagger && node ../../scripts/barrels.mjs create ./src/web && tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json && node ../../scripts/barrels.mjs clean ./src && node ../../scripts/mark-cjs.mjs ./dist/cjs",
|
|
55
76
|
"lint:tsc": "tsc --noEmit --pretty --project .",
|
|
56
77
|
"test:mutation": "stryker run",
|
|
57
78
|
"test:unit": "vitest run"
|
|
@@ -61,9 +82,11 @@
|
|
|
61
82
|
},
|
|
62
83
|
"devDependencies": {
|
|
63
84
|
"@fastify/cookie": "^11.1.3",
|
|
85
|
+
"@libs-for-dev/nestjs-config-module": "3.0.0",
|
|
64
86
|
"@nestjs/common": "^11.2.7",
|
|
65
87
|
"@nestjs/core": "^11.2.7",
|
|
66
88
|
"@nestjs/platform-fastify": "^11.2.7",
|
|
89
|
+
"@nestjs/swagger": "^11.4.8",
|
|
67
90
|
"@opentelemetry/api": "^1.9.1",
|
|
68
91
|
"@stryker-mutator/core": "^10.0.0",
|
|
69
92
|
"@stryker-mutator/vitest-runner": "^10.0.0",
|
|
@@ -81,9 +104,11 @@
|
|
|
81
104
|
},
|
|
82
105
|
"peerDependencies": {
|
|
83
106
|
"@fastify/cookie": "^11.0.0",
|
|
107
|
+
"@libs-for-dev/nestjs-config-module": "^3.0.0",
|
|
84
108
|
"@nestjs/common": "^11.0.0",
|
|
85
109
|
"@nestjs/core": "^11.0.0",
|
|
86
110
|
"@nestjs/platform-fastify": "^11.0.0",
|
|
111
|
+
"@nestjs/swagger": "^11.0.0 || ^12.0.0",
|
|
87
112
|
"@opentelemetry/api": "^1.9.0",
|
|
88
113
|
"class-transformer": "^0.5.1",
|
|
89
114
|
"class-validator": "^0.15.1",
|
|
@@ -94,9 +119,15 @@
|
|
|
94
119
|
"@fastify/cookie": {
|
|
95
120
|
"optional": true
|
|
96
121
|
},
|
|
122
|
+
"@libs-for-dev/nestjs-config-module": {
|
|
123
|
+
"optional": true
|
|
124
|
+
},
|
|
97
125
|
"@nestjs/platform-fastify": {
|
|
98
126
|
"optional": true
|
|
99
127
|
},
|
|
128
|
+
"@nestjs/swagger": {
|
|
129
|
+
"optional": true
|
|
130
|
+
},
|
|
100
131
|
"@opentelemetry/api": {
|
|
101
132
|
"optional": true
|
|
102
133
|
},
|