@fluojs/platform-fastify 1.0.3 → 1.0.5
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.ko.md +3 -10
- package/README.md +3 -10
- package/dist/adapter.d.ts +1 -2
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +35 -23
- package/package.json +3 -3
package/README.ko.md
CHANGED
|
@@ -41,7 +41,7 @@ const app = await fluoFactory.create(AppModule, {
|
|
|
41
41
|
await app.listen();
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
`createFastifyAdapter()`는 기본 port로 `3000`을 사용하며 `process.env.PORT`를 읽지 않습니다. 잘못된 explicit
|
|
44
|
+
`createFastifyAdapter()`는 기본 port로 `3000`을 사용하며 `process.env.PORT`를 읽지 않습니다. `port`, `maxBodySize`, `retryDelayMs`, `retryLimit`, `shutdownTimeoutMs` 같은 잘못된 explicit numeric option은 adapter setup 중 throw됩니다. `maxBodySize`와 `shutdownTimeoutMs`는 음수가 아닌 정수 byte/time limit이므로 `0`도 유효합니다. `maxBodySize: 0`은 빈 request body만 허용하고, `shutdownTimeoutMs: 0`은 다음 timer turn에 Fastify close가 timeout되도록 요청합니다.
|
|
45
45
|
|
|
46
46
|
## 주요 패턴
|
|
47
47
|
|
|
@@ -111,14 +111,7 @@ await bootstrapFastifyApplication(AppModule, {
|
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### 로깅 (Logging)
|
|
114
|
-
fluo는 자체 로깅 시스템을 사용합니다. 어댑터는 Fastify 인스턴스를 생성할 때 네이티브 로거를 비활성화하며,
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
await runFastifyApplication(AppModule, {
|
|
118
|
-
logger: myLogger,
|
|
119
|
-
port: 3000,
|
|
120
|
-
});
|
|
121
|
-
```
|
|
114
|
+
fluo는 자체 로깅 시스템을 사용합니다. 어댑터는 Fastify 인스턴스를 생성할 때 네이티브 로거를 비활성화하며, `bootstrapFastifyApplication(...)` / `runFastifyApplication(...)`은 활성 런타임과 일관된 startup/shutdown diagnostics를 유지하도록 framework console logger를 내부에서 선택합니다.
|
|
122
115
|
|
|
123
116
|
### 미들웨어 (Middleware)
|
|
124
117
|
요청이 핸들러에 도달하기 전에 실행되는 런타임 레벨의 미들웨어를 등록할 수 있습니다. 이는 Fastify 전용 플러그인이 아닌 표준 `MiddlewareLike` 함수라는 점에 유의하세요.
|
|
@@ -167,7 +160,7 @@ fluo의 Fastify 어댑터는 높은 동시성 시나리오에서 raw Node.js 어
|
|
|
167
160
|
|
|
168
161
|
- **CORS 오류**: `cors` 부트스트랩 옵션을 사용 중인지 확인하세요. Fastify의 네이티브 CORS 플러그인을 사용하지 않으므로 오직 fluo가 관리하는 CORS 로직만 적용됩니다.
|
|
169
162
|
- **미들웨어 문제**: `middleware` 옵션은 런타임 레벨의 `MiddlewareLike[]` 함수 배열을 받습니다. 이는 Fastify 플러그인이 아니며 다른 fluo 어댑터들과 공통으로 사용되는 표준 인터페이스를 따릅니다.
|
|
170
|
-
- **로깅 (Logging)**: 로그 스트림 중복을 방지하기 위해 Fastify의 네이티브 로거가 비활성화됩니다.
|
|
163
|
+
- **로깅 (Logging)**: 로그 스트림 중복을 방지하기 위해 Fastify의 네이티브 로거가 비활성화됩니다. `runFastifyApplication`과 `bootstrapFastifyApplication`은 framework console logger를 내부에서 선택하므로 application code가 이 helper들에 logger option을 전달하지 않아야 합니다.
|
|
171
164
|
- **글로벌 접두사 (Global Prefix)**: 내부 경로 또는 헬스 체크 엔드포인트에 접두사가 붙지 않도록 `globalPrefixExclude`를 적절히 설정하세요.
|
|
172
165
|
- **Malformed Cookie**: 잘못된 cookie header는 request 실패로 이어지지 않고 보존됩니다.
|
|
173
166
|
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ const app = await fluoFactory.create(AppModule, {
|
|
|
41
41
|
await app.listen();
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
`createFastifyAdapter()` defaults to port `3000` and does not read `process.env.PORT`; invalid explicit port
|
|
44
|
+
`createFastifyAdapter()` defaults to port `3000` and does not read `process.env.PORT`; invalid explicit numeric options such as `port`, `maxBodySize`, `retryDelayMs`, `retryLimit`, and `shutdownTimeoutMs` throw during adapter setup. `maxBodySize` and `shutdownTimeoutMs` are non-negative integer byte/time limits, so `0` is valid: `maxBodySize: 0` allows only empty request bodies, and `shutdownTimeoutMs: 0` asks Fastify to close on the next timer turn.
|
|
45
45
|
|
|
46
46
|
## Common Patterns
|
|
47
47
|
|
|
@@ -111,14 +111,7 @@ await bootstrapFastifyApplication(AppModule, {
|
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### Logging
|
|
114
|
-
fluo uses its own logging system. The adapter creates the Fastify instance with its native logger disabled and
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
await runFastifyApplication(AppModule, {
|
|
118
|
-
logger: myLogger,
|
|
119
|
-
port: 3000,
|
|
120
|
-
});
|
|
121
|
-
```
|
|
114
|
+
fluo uses its own logging system. The adapter creates the Fastify instance with its native logger disabled, and `bootstrapFastifyApplication(...)` / `runFastifyApplication(...)` select the framework console logger internally so startup and shutdown diagnostics stay consistent with the active runtime.
|
|
122
115
|
|
|
123
116
|
### Middleware
|
|
124
117
|
You can register runtime-level middleware that runs before the request reaches the handlers. Note that these are standard `MiddlewareLike` functions, not Fastify-specific plugins.
|
|
@@ -167,7 +160,7 @@ The same file also covers Fastify-specific native route registration with wildca
|
|
|
167
160
|
|
|
168
161
|
- **CORS Errors**: Ensure you're using the `cors` bootstrap option. Since Fastify's native CORS plugin is not registered, only the fluo-managed CORS logic applies.
|
|
169
162
|
- **Middleware Issues**: The `middleware` option accepts runtime-level `MiddlewareLike[]` functions. These are not Fastify plugins and follow the standard middleware interface used across fluo adapters.
|
|
170
|
-
- **Logging**: The native Fastify logger is disabled to prevent duplicate log streams.
|
|
163
|
+
- **Logging**: The native Fastify logger is disabled to prevent duplicate log streams. `runFastifyApplication` and `bootstrapFastifyApplication` select the framework console logger internally; application code should not pass a logger option to these helpers.
|
|
171
164
|
- **Global Prefix**: Use `globalPrefixExclude` to prevent the prefix from being applied to internal routes or health check endpoints.
|
|
172
165
|
- **Malformed Cookies**: Malformed cookie headers are preserved rather than failing the request.
|
|
173
166
|
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ServerOptions as HttpsServerOptions } from 'node:https';
|
|
2
2
|
import { type CorsOptions, type Dispatcher, type HttpApplicationAdapter, type MiddlewareLike, type SecurityHeadersOptions } from '@fluojs/http';
|
|
3
|
-
import {
|
|
3
|
+
import type { Application, CreateApplicationOptions, ModuleType, MultipartOptions, UploadedFile } from '@fluojs/runtime';
|
|
4
4
|
declare module '@fluojs/http' {
|
|
5
5
|
interface FrameworkRequest {
|
|
6
6
|
files?: UploadedFile[];
|
|
@@ -34,7 +34,6 @@ export interface BootstrapFastifyApplicationOptions extends Omit<CreateApplicati
|
|
|
34
34
|
globalPrefixExclude?: readonly string[];
|
|
35
35
|
host?: string;
|
|
36
36
|
https?: HttpsServerOptions;
|
|
37
|
-
logger?: ApplicationLogger;
|
|
38
37
|
maxBodySize?: number;
|
|
39
38
|
middleware?: MiddlewareLike[];
|
|
40
39
|
multipart?: MultipartOptions;
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Transform } from 'node:stream';
|
|
2
2
|
import multipart from '@fastify/multipart';
|
|
3
|
-
import
|
|
4
|
-
import { createServerBackedHttpAdapterRealtimeCapability, createErrorResponse, HttpException, InternalServerErrorException, PayloadTooLargeException } from '@fluojs/http';
|
|
3
|
+
import { createErrorResponse, createServerBackedHttpAdapterRealtimeCapability, HttpException, InternalServerErrorException, PayloadTooLargeException } from '@fluojs/http';
|
|
5
4
|
import { attachFrameworkRequestNativeRouteHandoff, bindRawRequestNativeRouteHandoff, consumeRawRequestNativeRouteHandoff, isRoutePathNormalizationSensitive } from '@fluojs/http/internal';
|
|
6
|
-
import {
|
|
7
|
-
import { cloneHeaderValue, createDeferredFrameworkRequestShell, createMemoizedAsyncValue, createMemoizedValue, parseQueryParamsFromSearch, snapshotSimpleQueryRecord, splitRawRequestUrl } from '@fluojs/runtime/internal-node';
|
|
8
|
-
import { bootstrapHttpAdapterApplication, runHttpAdapterApplication } from '@fluojs/runtime/internal/http-adapter';
|
|
5
|
+
import { bootstrapHttpAdapterApplication, createConsoleApplicationLogger, runHttpAdapterApplication } from '@fluojs/runtime/internal/http-adapter';
|
|
9
6
|
import { dispatchWithRequestResponseFactory } from '@fluojs/runtime/internal/request-response-factory';
|
|
7
|
+
import { cloneHeaderValue, createDeferredFrameworkRequestShell, createMemoizedAsyncValue, createMemoizedValue, parseQueryParamsFromSearch, snapshotSimpleQueryRecord, splitRawRequestUrl } from '@fluojs/runtime/internal-node';
|
|
8
|
+
import { createNodeShutdownSignalRegistration, defaultNodeShutdownSignals } from '@fluojs/runtime/node';
|
|
9
|
+
import fastify from 'fastify';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Transport-level knobs for the standalone Fastify HTTP adapter factory.
|
|
@@ -52,6 +52,11 @@ export class FastifyHttpApplicationAdapter {
|
|
|
52
52
|
this.maxBodySize = maxBodySize;
|
|
53
53
|
this.preserveRawBody = preserveRawBody;
|
|
54
54
|
this.shutdownTimeoutMs = shutdownTimeoutMs;
|
|
55
|
+
resolvePort(this.port);
|
|
56
|
+
resolveNonNegativeIntegerOption('retryDelayMs', this.retryDelayMs, 150);
|
|
57
|
+
resolveNonNegativeIntegerOption('retryLimit', this.retryLimit, 20);
|
|
58
|
+
resolveNonNegativeIntegerOption('maxBodySize', this.maxBodySize, DEFAULT_MAX_BODY_SIZE);
|
|
59
|
+
resolveNonNegativeIntegerOption('shutdownTimeoutMs', this.shutdownTimeoutMs, DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
|
55
60
|
this.app = createFastifyApp(this.httpsOptions, this.maxBodySize);
|
|
56
61
|
this.requestResponseFactory = createFastifyRequestResponseFactory(this.multipartOptions, this.maxBodySize, this.preserveRawBody);
|
|
57
62
|
}
|
|
@@ -70,23 +75,21 @@ export class FastifyHttpApplicationAdapter {
|
|
|
70
75
|
await this.listenWithRetry();
|
|
71
76
|
}
|
|
72
77
|
async close() {
|
|
73
|
-
if (
|
|
74
|
-
this.
|
|
78
|
+
if (this.closeInFlight) {
|
|
79
|
+
await waitForCloseWithTimeout(this.closeInFlight, this.shutdownTimeoutMs);
|
|
75
80
|
return;
|
|
76
81
|
}
|
|
77
|
-
if (!this.
|
|
78
|
-
|
|
79
|
-
const closeInFlight = closePromise.finally(() => {
|
|
80
|
-
this.closeInFlight = undefined;
|
|
81
|
-
this.dispatcher = undefined;
|
|
82
|
-
});
|
|
83
|
-
this.closeInFlight = closeInFlight;
|
|
84
|
-
void closeInFlight.catch(() => {});
|
|
85
|
-
}
|
|
86
|
-
const closeInFlight = this.closeInFlight;
|
|
87
|
-
if (!closeInFlight) {
|
|
82
|
+
if (!this.app.server.listening) {
|
|
83
|
+
this.dispatcher = undefined;
|
|
88
84
|
return;
|
|
89
85
|
}
|
|
86
|
+
const closePromise = this.app.close();
|
|
87
|
+
const closeInFlight = closePromise.finally(() => {
|
|
88
|
+
this.closeInFlight = undefined;
|
|
89
|
+
this.dispatcher = undefined;
|
|
90
|
+
});
|
|
91
|
+
this.closeInFlight = closeInFlight;
|
|
92
|
+
void closeInFlight.catch(() => {});
|
|
90
93
|
await waitForCloseWithTimeout(closeInFlight, this.shutdownTimeoutMs);
|
|
91
94
|
}
|
|
92
95
|
async registerPluginsAndRoutes(dispatcher) {
|
|
@@ -257,7 +260,7 @@ function readSimpleQueryRecord(query) {
|
|
|
257
260
|
}
|
|
258
261
|
const record = query;
|
|
259
262
|
for (const key in record) {
|
|
260
|
-
if (!Object.
|
|
263
|
+
if (!Object.hasOwn(record, key)) {
|
|
261
264
|
continue;
|
|
262
265
|
}
|
|
263
266
|
const value = record[key];
|
|
@@ -372,7 +375,8 @@ export function createFastifyAdapter(options = {}, multipartOptions) {
|
|
|
372
375
|
* @returns An initialized application shell that can be listened to later.
|
|
373
376
|
*/
|
|
374
377
|
export async function bootstrapFastifyApplication(rootModule, options) {
|
|
375
|
-
|
|
378
|
+
const logger = createConsoleApplicationLogger();
|
|
379
|
+
return bootstrapHttpAdapterApplication(rootModule, options, createFastifyAdapter(options, options.multipart), logger);
|
|
376
380
|
}
|
|
377
381
|
|
|
378
382
|
/**
|
|
@@ -386,11 +390,12 @@ export async function bootstrapFastifyApplication(rootModule, options) {
|
|
|
386
390
|
* @returns A bootstrapped application shell ready to listen.
|
|
387
391
|
*/
|
|
388
392
|
export async function runFastifyApplication(rootModule, options) {
|
|
393
|
+
const logger = createConsoleApplicationLogger();
|
|
389
394
|
const adapter = createFastifyAdapter(options, options.multipart);
|
|
390
395
|
return runHttpAdapterApplication(rootModule, {
|
|
391
396
|
...options,
|
|
392
397
|
shutdownRegistration: createNodeShutdownSignalRegistration(options.shutdownSignals ?? defaultNodeShutdownSignals())
|
|
393
|
-
}, adapter);
|
|
398
|
+
}, adapter, logger);
|
|
394
399
|
}
|
|
395
400
|
class MutableFastifyFrameworkResponse {
|
|
396
401
|
committed;
|
|
@@ -578,7 +583,7 @@ function normalizeNativeRouteParams(params) {
|
|
|
578
583
|
}
|
|
579
584
|
let normalized;
|
|
580
585
|
for (const key in params) {
|
|
581
|
-
if (!Object.
|
|
586
|
+
if (!Object.hasOwn(params, key)) {
|
|
582
587
|
continue;
|
|
583
588
|
}
|
|
584
589
|
const value = params[key];
|
|
@@ -592,7 +597,7 @@ function normalizeNativeRouteParams(params) {
|
|
|
592
597
|
}
|
|
593
598
|
function hasNativeRouteParamSeparators(params) {
|
|
594
599
|
for (const key in params) {
|
|
595
|
-
if (Object.
|
|
600
|
+
if (Object.hasOwn(params, key) && params[key]?.includes('/')) {
|
|
596
601
|
return true;
|
|
597
602
|
}
|
|
598
603
|
}
|
|
@@ -827,6 +832,13 @@ function resolvePort(value) {
|
|
|
827
832
|
}
|
|
828
833
|
return port;
|
|
829
834
|
}
|
|
835
|
+
function resolveNonNegativeIntegerOption(name, value, defaultValue) {
|
|
836
|
+
const resolved = value ?? defaultValue;
|
|
837
|
+
if (!Number.isInteger(resolved) || resolved < 0) {
|
|
838
|
+
throw new Error(`Invalid ${name} value: ${String(resolved)}. Expected a non-negative integer.`);
|
|
839
|
+
}
|
|
840
|
+
return resolved;
|
|
841
|
+
}
|
|
830
842
|
function toHttpException(error) {
|
|
831
843
|
if (error instanceof HttpException) {
|
|
832
844
|
return error;
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"platform",
|
|
9
9
|
"server"
|
|
10
10
|
],
|
|
11
|
-
"version": "1.0.
|
|
11
|
+
"version": "1.0.5",
|
|
12
12
|
"private": false,
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"repository": {
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"fastify": "^5.8.5",
|
|
40
40
|
"fastify-raw-body": "^5.0.0",
|
|
41
41
|
"@fluojs/http": "^1.1.0",
|
|
42
|
-
"@fluojs/runtime": "^1.1.
|
|
42
|
+
"@fluojs/runtime": "^1.1.5"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"vitest": "^3.2.4",
|
|
46
46
|
"@fluojs/di": "^1.0.3",
|
|
47
|
-
"@fluojs/testing": "^1.0.
|
|
47
|
+
"@fluojs/testing": "^1.0.4"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"prebuild": "node ../../tooling/scripts/clean-dist.mjs",
|