@nestjs-ssr/react 0.3.5 → 0.3.7
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/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/{index-Dq2qZSge.d.ts → index-CGfEDKI4.d.ts} +77 -9
- package/dist/{index-CiYcz-1T.d.mts → index-DcpOFSp4.d.mts} +77 -9
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +85 -32
- package/dist/index.mjs +85 -32
- package/dist/render/index.d.mts +2 -2
- package/dist/render/index.d.ts +2 -2
- package/dist/render/index.js +85 -32
- package/dist/render/index.mjs +85 -32
- package/dist/{use-page-context-DChgHhL9.d.ts → use-page-context-CUV31oda.d.ts} +1 -1
- package/dist/{use-page-context-CVC9DHcL.d.mts → use-page-context-CmxWHIK3.d.mts} +1 -1
- package/package.json +32 -21
package/dist/client.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as PageContextProvider, P as PageProps, c as createSSRHooks, j as updatePageContext,
|
|
1
|
+
export { a as PageContextProvider, P as PageProps, c as createSSRHooks, j as updatePageContext, u as useCookie, b as useCookies, d as useHeader, e as useHeaders, f as usePageContext, g as useParams, h as useQuery, i as useRequest } from './use-page-context-CmxWHIK3.mjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
export { R as RenderContext } from './render-response.interface-ClWJXKL4.mjs';
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a as PageContextProvider, P as PageProps, c as createSSRHooks, j as updatePageContext,
|
|
1
|
+
export { a as PageContextProvider, P as PageProps, c as createSSRHooks, j as updatePageContext, u as useCookie, b as useCookies, d as useHeader, e as useHeaders, f as usePageContext, g as useParams, h as useQuery, i as useRequest } from './use-page-context-CUV31oda.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
export { R as RenderContext } from './render-response.interface-ClWJXKL4.js';
|
|
@@ -1,12 +1,79 @@
|
|
|
1
1
|
import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { Request, Response } from 'express';
|
|
4
3
|
import { H as HeadData, R as RenderContext } from './render-response.interface-ClWJXKL4.js';
|
|
4
|
+
import { ServerResponse } from 'http';
|
|
5
5
|
import { ViteDevServer } from 'vite';
|
|
6
6
|
import { Reflector } from '@nestjs/core';
|
|
7
7
|
import { Observable } from 'rxjs';
|
|
8
8
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Common HTTP request interface that works with both Express and Fastify.
|
|
12
|
+
* This represents the minimal interface needed for SSR context building.
|
|
13
|
+
*/
|
|
14
|
+
interface SSRRequest {
|
|
15
|
+
/** Full request URL including query string */
|
|
16
|
+
url: string;
|
|
17
|
+
/** HTTP method (GET, POST, etc.) */
|
|
18
|
+
method: string;
|
|
19
|
+
/** Request headers */
|
|
20
|
+
headers: Record<string, string | string[] | undefined>;
|
|
21
|
+
/** URL path (Express: path, Fastify: routeOptions.url or url without query) */
|
|
22
|
+
path?: string;
|
|
23
|
+
/** Parsed query parameters */
|
|
24
|
+
query?: Record<string, string | string[] | undefined>;
|
|
25
|
+
/** Route parameters */
|
|
26
|
+
params?: Record<string, string>;
|
|
27
|
+
/** Parsed cookies (requires cookie-parser middleware) */
|
|
28
|
+
cookies?: Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* User object populated by authentication middleware (e.g., Passport).
|
|
31
|
+
* Type is `unknown` since the shape depends on your auth strategy.
|
|
32
|
+
*/
|
|
33
|
+
user?: unknown;
|
|
34
|
+
/** Allow any additional properties for framework-specific extensions */
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Minimal interface for the raw Node.js response.
|
|
39
|
+
* This is a subset of ServerResponse that we actually use for streaming SSR.
|
|
40
|
+
*/
|
|
41
|
+
interface RawServerResponse {
|
|
42
|
+
statusCode: number;
|
|
43
|
+
headersSent: boolean;
|
|
44
|
+
writableEnded: boolean;
|
|
45
|
+
setHeader(name: string, value: string | number | readonly string[]): void;
|
|
46
|
+
write(chunk: string | Buffer): boolean;
|
|
47
|
+
end(data?: string | Buffer): void;
|
|
48
|
+
on?(event: string, listener: (...args: any[]) => void): this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Common HTTP response interface that works with both Express and Fastify.
|
|
52
|
+
* For streaming SSR, we access the raw Node.js ServerResponse.
|
|
53
|
+
*/
|
|
54
|
+
interface SSRResponse {
|
|
55
|
+
/** HTTP status code (optional - Fastify has it on raw) */
|
|
56
|
+
statusCode?: number;
|
|
57
|
+
/** Whether headers have been sent (Express) */
|
|
58
|
+
headersSent?: boolean;
|
|
59
|
+
/** Whether headers have been sent (Fastify uses 'sent') */
|
|
60
|
+
sent?: boolean;
|
|
61
|
+
/** Whether the response stream has ended */
|
|
62
|
+
writableEnded?: boolean;
|
|
63
|
+
/** Set a response header */
|
|
64
|
+
setHeader?(name: string, value: string | number | readonly string[]): void;
|
|
65
|
+
/** Write data to the response */
|
|
66
|
+
write?(chunk: string | Buffer): boolean;
|
|
67
|
+
/** End the response */
|
|
68
|
+
end?(data?: string | Buffer): void;
|
|
69
|
+
/** Event listener for 'close' event */
|
|
70
|
+
on?(event: string, listener: (...args: any[]) => void): this;
|
|
71
|
+
/** Raw Node.js response (Fastify) - uses minimal interface for easier testing */
|
|
72
|
+
raw?: RawServerResponse | ServerResponse;
|
|
73
|
+
/** Allow additional properties */
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}
|
|
76
|
+
|
|
10
77
|
/**
|
|
11
78
|
* Custom context properties that can be added via context factory.
|
|
12
79
|
* Allows any properties to be merged into RenderContext.
|
|
@@ -16,7 +83,7 @@ type CustomContextProperties = Record<string, unknown>;
|
|
|
16
83
|
* Context factory function signature
|
|
17
84
|
* Called for each request to build custom context properties
|
|
18
85
|
*
|
|
19
|
-
* @param params - Object containing the Express
|
|
86
|
+
* @param params - Object containing the HTTP request (Express or Fastify)
|
|
20
87
|
* @returns Custom context properties to merge into RenderContext (sync or async)
|
|
21
88
|
*
|
|
22
89
|
* @example
|
|
@@ -37,8 +104,9 @@ type CustomContextProperties = Record<string, unknown>;
|
|
|
37
104
|
* })
|
|
38
105
|
* ```
|
|
39
106
|
*/
|
|
40
|
-
type ContextFactory = (params: {
|
|
41
|
-
|
|
107
|
+
type ContextFactory<TRequest extends SSRRequest = SSRRequest> = (params: {
|
|
108
|
+
/** HTTP request object (Express Request or Fastify FastifyRequest) */
|
|
109
|
+
req: TRequest;
|
|
42
110
|
}) => CustomContextProperties | Promise<CustomContextProperties>;
|
|
43
111
|
/**
|
|
44
112
|
* SSR rendering mode configuration
|
|
@@ -486,7 +554,7 @@ declare class StreamingErrorHandler {
|
|
|
486
554
|
* Handle error that occurred before shell was ready
|
|
487
555
|
* Can still set HTTP status code and send error page
|
|
488
556
|
*/
|
|
489
|
-
handleShellError(error: Error, res:
|
|
557
|
+
handleShellError(error: Error, res: SSRResponse, viewPath: string, isDevelopment: boolean): void;
|
|
490
558
|
/**
|
|
491
559
|
* Handle error that occurred during streaming
|
|
492
560
|
* Headers already sent, can only log the error
|
|
@@ -552,11 +620,11 @@ declare class StreamRenderer {
|
|
|
552
620
|
*
|
|
553
621
|
* @param viewComponent - The React component to render
|
|
554
622
|
* @param data - Data to pass to the component
|
|
555
|
-
* @param res -
|
|
623
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
556
624
|
* @param context - Render context with Vite and manifest info
|
|
557
625
|
* @param head - Head data for SEO tags
|
|
558
626
|
*/
|
|
559
|
-
render(viewComponent: any, data: any, res:
|
|
627
|
+
render(viewComponent: any, data: any, res: SSRResponse, context: StreamRenderContext, head?: HeadData): Promise<void>;
|
|
560
628
|
}
|
|
561
629
|
|
|
562
630
|
/**
|
|
@@ -621,7 +689,7 @@ declare class RenderService {
|
|
|
621
689
|
* - Better TTFB, progressive rendering
|
|
622
690
|
* - Requires response object
|
|
623
691
|
*/
|
|
624
|
-
render(viewComponent: any, data?: any, res?:
|
|
692
|
+
render(viewComponent: any, data?: any, res?: SSRResponse, head?: HeadData): Promise<string | void>;
|
|
625
693
|
/**
|
|
626
694
|
* Render a segment for client-side navigation.
|
|
627
695
|
* Always uses string mode (streaming not supported for segments).
|
|
@@ -691,4 +759,4 @@ declare function ErrorPageDevelopment({ error, viewPath, phase, }: ErrorPageDeve
|
|
|
691
759
|
*/
|
|
692
760
|
declare function ErrorPageProduction(): react_jsx_runtime.JSX.Element;
|
|
693
761
|
|
|
694
|
-
export { type ContextFactory as C, ErrorPageDevelopment as E,
|
|
762
|
+
export { type ContextFactory as C, ErrorPageDevelopment as E, type RenderConfig as R, type SSRMode as S, TemplateParserService as T, ErrorPageProduction as a, RenderInterceptor as b, RenderModule as c, RenderService as d, StreamingErrorHandler as e };
|
|
@@ -1,12 +1,79 @@
|
|
|
1
1
|
import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { Request, Response } from 'express';
|
|
4
3
|
import { H as HeadData, R as RenderContext } from './render-response.interface-ClWJXKL4.mjs';
|
|
4
|
+
import { ServerResponse } from 'http';
|
|
5
5
|
import { ViteDevServer } from 'vite';
|
|
6
6
|
import { Reflector } from '@nestjs/core';
|
|
7
7
|
import { Observable } from 'rxjs';
|
|
8
8
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Common HTTP request interface that works with both Express and Fastify.
|
|
12
|
+
* This represents the minimal interface needed for SSR context building.
|
|
13
|
+
*/
|
|
14
|
+
interface SSRRequest {
|
|
15
|
+
/** Full request URL including query string */
|
|
16
|
+
url: string;
|
|
17
|
+
/** HTTP method (GET, POST, etc.) */
|
|
18
|
+
method: string;
|
|
19
|
+
/** Request headers */
|
|
20
|
+
headers: Record<string, string | string[] | undefined>;
|
|
21
|
+
/** URL path (Express: path, Fastify: routeOptions.url or url without query) */
|
|
22
|
+
path?: string;
|
|
23
|
+
/** Parsed query parameters */
|
|
24
|
+
query?: Record<string, string | string[] | undefined>;
|
|
25
|
+
/** Route parameters */
|
|
26
|
+
params?: Record<string, string>;
|
|
27
|
+
/** Parsed cookies (requires cookie-parser middleware) */
|
|
28
|
+
cookies?: Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* User object populated by authentication middleware (e.g., Passport).
|
|
31
|
+
* Type is `unknown` since the shape depends on your auth strategy.
|
|
32
|
+
*/
|
|
33
|
+
user?: unknown;
|
|
34
|
+
/** Allow any additional properties for framework-specific extensions */
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Minimal interface for the raw Node.js response.
|
|
39
|
+
* This is a subset of ServerResponse that we actually use for streaming SSR.
|
|
40
|
+
*/
|
|
41
|
+
interface RawServerResponse {
|
|
42
|
+
statusCode: number;
|
|
43
|
+
headersSent: boolean;
|
|
44
|
+
writableEnded: boolean;
|
|
45
|
+
setHeader(name: string, value: string | number | readonly string[]): void;
|
|
46
|
+
write(chunk: string | Buffer): boolean;
|
|
47
|
+
end(data?: string | Buffer): void;
|
|
48
|
+
on?(event: string, listener: (...args: any[]) => void): this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Common HTTP response interface that works with both Express and Fastify.
|
|
52
|
+
* For streaming SSR, we access the raw Node.js ServerResponse.
|
|
53
|
+
*/
|
|
54
|
+
interface SSRResponse {
|
|
55
|
+
/** HTTP status code (optional - Fastify has it on raw) */
|
|
56
|
+
statusCode?: number;
|
|
57
|
+
/** Whether headers have been sent (Express) */
|
|
58
|
+
headersSent?: boolean;
|
|
59
|
+
/** Whether headers have been sent (Fastify uses 'sent') */
|
|
60
|
+
sent?: boolean;
|
|
61
|
+
/** Whether the response stream has ended */
|
|
62
|
+
writableEnded?: boolean;
|
|
63
|
+
/** Set a response header */
|
|
64
|
+
setHeader?(name: string, value: string | number | readonly string[]): void;
|
|
65
|
+
/** Write data to the response */
|
|
66
|
+
write?(chunk: string | Buffer): boolean;
|
|
67
|
+
/** End the response */
|
|
68
|
+
end?(data?: string | Buffer): void;
|
|
69
|
+
/** Event listener for 'close' event */
|
|
70
|
+
on?(event: string, listener: (...args: any[]) => void): this;
|
|
71
|
+
/** Raw Node.js response (Fastify) - uses minimal interface for easier testing */
|
|
72
|
+
raw?: RawServerResponse | ServerResponse;
|
|
73
|
+
/** Allow additional properties */
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}
|
|
76
|
+
|
|
10
77
|
/**
|
|
11
78
|
* Custom context properties that can be added via context factory.
|
|
12
79
|
* Allows any properties to be merged into RenderContext.
|
|
@@ -16,7 +83,7 @@ type CustomContextProperties = Record<string, unknown>;
|
|
|
16
83
|
* Context factory function signature
|
|
17
84
|
* Called for each request to build custom context properties
|
|
18
85
|
*
|
|
19
|
-
* @param params - Object containing the Express
|
|
86
|
+
* @param params - Object containing the HTTP request (Express or Fastify)
|
|
20
87
|
* @returns Custom context properties to merge into RenderContext (sync or async)
|
|
21
88
|
*
|
|
22
89
|
* @example
|
|
@@ -37,8 +104,9 @@ type CustomContextProperties = Record<string, unknown>;
|
|
|
37
104
|
* })
|
|
38
105
|
* ```
|
|
39
106
|
*/
|
|
40
|
-
type ContextFactory = (params: {
|
|
41
|
-
|
|
107
|
+
type ContextFactory<TRequest extends SSRRequest = SSRRequest> = (params: {
|
|
108
|
+
/** HTTP request object (Express Request or Fastify FastifyRequest) */
|
|
109
|
+
req: TRequest;
|
|
42
110
|
}) => CustomContextProperties | Promise<CustomContextProperties>;
|
|
43
111
|
/**
|
|
44
112
|
* SSR rendering mode configuration
|
|
@@ -486,7 +554,7 @@ declare class StreamingErrorHandler {
|
|
|
486
554
|
* Handle error that occurred before shell was ready
|
|
487
555
|
* Can still set HTTP status code and send error page
|
|
488
556
|
*/
|
|
489
|
-
handleShellError(error: Error, res:
|
|
557
|
+
handleShellError(error: Error, res: SSRResponse, viewPath: string, isDevelopment: boolean): void;
|
|
490
558
|
/**
|
|
491
559
|
* Handle error that occurred during streaming
|
|
492
560
|
* Headers already sent, can only log the error
|
|
@@ -552,11 +620,11 @@ declare class StreamRenderer {
|
|
|
552
620
|
*
|
|
553
621
|
* @param viewComponent - The React component to render
|
|
554
622
|
* @param data - Data to pass to the component
|
|
555
|
-
* @param res -
|
|
623
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
556
624
|
* @param context - Render context with Vite and manifest info
|
|
557
625
|
* @param head - Head data for SEO tags
|
|
558
626
|
*/
|
|
559
|
-
render(viewComponent: any, data: any, res:
|
|
627
|
+
render(viewComponent: any, data: any, res: SSRResponse, context: StreamRenderContext, head?: HeadData): Promise<void>;
|
|
560
628
|
}
|
|
561
629
|
|
|
562
630
|
/**
|
|
@@ -621,7 +689,7 @@ declare class RenderService {
|
|
|
621
689
|
* - Better TTFB, progressive rendering
|
|
622
690
|
* - Requires response object
|
|
623
691
|
*/
|
|
624
|
-
render(viewComponent: any, data?: any, res?:
|
|
692
|
+
render(viewComponent: any, data?: any, res?: SSRResponse, head?: HeadData): Promise<string | void>;
|
|
625
693
|
/**
|
|
626
694
|
* Render a segment for client-side navigation.
|
|
627
695
|
* Always uses string mode (streaming not supported for segments).
|
|
@@ -691,4 +759,4 @@ declare function ErrorPageDevelopment({ error, viewPath, phase, }: ErrorPageDeve
|
|
|
691
759
|
*/
|
|
692
760
|
declare function ErrorPageProduction(): react_jsx_runtime.JSX.Element;
|
|
693
761
|
|
|
694
|
-
export { type ContextFactory as C, ErrorPageDevelopment as E,
|
|
762
|
+
export { type ContextFactory as C, ErrorPageDevelopment as E, type RenderConfig as R, type SSRMode as S, TemplateParserService as T, ErrorPageProduction as a, RenderInterceptor as b, RenderModule as c, RenderService as d, StreamingErrorHandler as e };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { C as ContextFactory, E as ErrorPageDevelopment,
|
|
1
|
+
export { C as ContextFactory, E as ErrorPageDevelopment, a as ErrorPageProduction, R as RenderConfig, b as RenderInterceptor, c as RenderModule, d as RenderService, S as SSRMode, e as StreamingErrorHandler, T as TemplateParserService } from './index-DcpOFSp4.mjs';
|
|
2
2
|
import React, { ComponentType, ReactNode } from 'react';
|
|
3
|
-
import { P as PageProps } from './use-page-context-
|
|
4
|
-
export { a as PageContextProvider, c as createSSRHooks,
|
|
3
|
+
import { P as PageProps } from './use-page-context-CmxWHIK3.mjs';
|
|
4
|
+
export { a as PageContextProvider, c as createSSRHooks, u as useCookie, b as useCookies, d as useHeader, e as useHeaders, f as usePageContext, g as useParams, h as useQuery, i as useRequest } from './use-page-context-CmxWHIK3.mjs';
|
|
5
5
|
import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-ClWJXKL4.mjs';
|
|
6
6
|
import '@nestjs/common';
|
|
7
|
-
import '
|
|
7
|
+
import 'http';
|
|
8
8
|
import 'vite';
|
|
9
9
|
import '@nestjs/core';
|
|
10
10
|
import 'rxjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { C as ContextFactory, E as ErrorPageDevelopment,
|
|
1
|
+
export { C as ContextFactory, E as ErrorPageDevelopment, a as ErrorPageProduction, R as RenderConfig, b as RenderInterceptor, c as RenderModule, d as RenderService, S as SSRMode, e as StreamingErrorHandler, T as TemplateParserService } from './index-CGfEDKI4.js';
|
|
2
2
|
import React, { ComponentType, ReactNode } from 'react';
|
|
3
|
-
import { P as PageProps } from './use-page-context-
|
|
4
|
-
export { a as PageContextProvider, c as createSSRHooks,
|
|
3
|
+
import { P as PageProps } from './use-page-context-CUV31oda.js';
|
|
4
|
+
export { a as PageContextProvider, c as createSSRHooks, u as useCookie, b as useCookies, d as useHeader, e as useHeaders, f as usePageContext, g as useParams, h as useQuery, i as useRequest } from './use-page-context-CUV31oda.js';
|
|
5
5
|
import { R as RenderContext, H as HeadData, a as RenderResponse } from './render-response.interface-ClWJXKL4.js';
|
|
6
6
|
import '@nestjs/common';
|
|
7
|
-
import '
|
|
7
|
+
import 'http';
|
|
8
8
|
import 'vite';
|
|
9
9
|
import '@nestjs/core';
|
|
10
10
|
import 'rxjs';
|
package/dist/index.js
CHANGED
|
@@ -462,6 +462,39 @@ function ErrorPageProduction() {
|
|
|
462
462
|
}
|
|
463
463
|
__name(ErrorPageProduction, "ErrorPageProduction");
|
|
464
464
|
|
|
465
|
+
// src/render/adapters/http-adapter-utils.ts
|
|
466
|
+
function detectAdapterType(httpAdapterHost) {
|
|
467
|
+
const adapter = httpAdapterHost?.httpAdapter;
|
|
468
|
+
if (!adapter) return "unknown";
|
|
469
|
+
const instance = adapter.getInstance();
|
|
470
|
+
if (instance && typeof instance.register === "function") {
|
|
471
|
+
return "fastify";
|
|
472
|
+
}
|
|
473
|
+
if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
|
|
474
|
+
return "express";
|
|
475
|
+
}
|
|
476
|
+
return "unknown";
|
|
477
|
+
}
|
|
478
|
+
__name(detectAdapterType, "detectAdapterType");
|
|
479
|
+
function isFastifyLikeResponse(res) {
|
|
480
|
+
return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
|
|
481
|
+
}
|
|
482
|
+
__name(isFastifyLikeResponse, "isFastifyLikeResponse");
|
|
483
|
+
function getRawResponse(res) {
|
|
484
|
+
if (isFastifyLikeResponse(res)) {
|
|
485
|
+
return res.raw;
|
|
486
|
+
}
|
|
487
|
+
return res;
|
|
488
|
+
}
|
|
489
|
+
__name(getRawResponse, "getRawResponse");
|
|
490
|
+
function isHeadersSent(res) {
|
|
491
|
+
if (typeof res.sent === "boolean") {
|
|
492
|
+
return res.sent;
|
|
493
|
+
}
|
|
494
|
+
return res.headersSent === true;
|
|
495
|
+
}
|
|
496
|
+
__name(isHeadersSent, "isHeadersSent");
|
|
497
|
+
|
|
465
498
|
// src/render/streaming-error-handler.ts
|
|
466
499
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
467
500
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -497,21 +530,19 @@ exports.StreamingErrorHandler = class _StreamingErrorHandler {
|
|
|
497
530
|
*/
|
|
498
531
|
handleShellError(error, res, viewPath, isDevelopment) {
|
|
499
532
|
this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
|
|
500
|
-
|
|
533
|
+
const rawRes = getRawResponse(res);
|
|
534
|
+
if (isHeadersSent(res)) {
|
|
501
535
|
this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
|
|
502
|
-
if (!
|
|
503
|
-
|
|
504
|
-
|
|
536
|
+
if (!rawRes.writableEnded) {
|
|
537
|
+
rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
|
|
538
|
+
rawRes.end();
|
|
505
539
|
}
|
|
506
540
|
return;
|
|
507
541
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
} else {
|
|
513
|
-
res.send(this.renderProductionErrorPage());
|
|
514
|
-
}
|
|
542
|
+
rawRes.statusCode = 500;
|
|
543
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
544
|
+
const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
|
|
545
|
+
rawRes.end(html);
|
|
515
546
|
}
|
|
516
547
|
/**
|
|
517
548
|
* Handle error that occurred during streaming
|
|
@@ -667,7 +698,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
667
698
|
*
|
|
668
699
|
* @param viewComponent - The React component to render
|
|
669
700
|
* @param data - Data to pass to the component
|
|
670
|
-
* @param res -
|
|
701
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
671
702
|
* @param context - Render context with Vite and manifest info
|
|
672
703
|
* @param head - Head data for SEO tags
|
|
673
704
|
*/
|
|
@@ -709,20 +740,21 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
709
740
|
const { PassThrough } = await import('stream');
|
|
710
741
|
const reactStream = new PassThrough();
|
|
711
742
|
let allReadyFired = false;
|
|
743
|
+
const rawRes = getRawResponse(res);
|
|
712
744
|
const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
|
|
713
745
|
onShellReady: /* @__PURE__ */ __name(() => {
|
|
714
746
|
shellReadyTime = Date.now();
|
|
715
|
-
if (!
|
|
716
|
-
|
|
717
|
-
|
|
747
|
+
if (!rawRes.headersSent) {
|
|
748
|
+
rawRes.statusCode = didError ? 500 : 200;
|
|
749
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
718
750
|
}
|
|
719
751
|
let htmlStart = templateParts.htmlStart;
|
|
720
752
|
htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
|
|
721
753
|
htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
|
|
722
|
-
|
|
723
|
-
|
|
754
|
+
rawRes.write(htmlStart);
|
|
755
|
+
rawRes.write(templateParts.rootStart);
|
|
724
756
|
pipe(reactStream);
|
|
725
|
-
reactStream.pipe(
|
|
757
|
+
reactStream.pipe(rawRes, {
|
|
726
758
|
end: false
|
|
727
759
|
});
|
|
728
760
|
if (context.isDevelopment) {
|
|
@@ -747,11 +779,11 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
747
779
|
if (shellErrorOccurred) {
|
|
748
780
|
return;
|
|
749
781
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
782
|
+
rawRes.write(inlineScripts);
|
|
783
|
+
rawRes.write(clientScript);
|
|
784
|
+
rawRes.write(templateParts.rootEnd);
|
|
785
|
+
rawRes.write(templateParts.htmlEnd);
|
|
786
|
+
rawRes.end();
|
|
755
787
|
if (context.isDevelopment) {
|
|
756
788
|
const totalTime = Date.now() - startTime;
|
|
757
789
|
const streamTime = Date.now() - shellReadyTime;
|
|
@@ -763,7 +795,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
763
795
|
reactStream.on("error", (error) => {
|
|
764
796
|
reject(error);
|
|
765
797
|
});
|
|
766
|
-
|
|
798
|
+
rawRes.on("close", () => {
|
|
767
799
|
abort();
|
|
768
800
|
resolve();
|
|
769
801
|
});
|
|
@@ -1221,9 +1253,10 @@ exports.RenderInterceptor = class RenderInterceptor {
|
|
|
1221
1253
|
if (typeof data === "string") {
|
|
1222
1254
|
return data;
|
|
1223
1255
|
}
|
|
1256
|
+
const requestPath = request.path ?? request.url?.split("?")[0] ?? "/";
|
|
1224
1257
|
const renderContext = {
|
|
1225
1258
|
url: request.url,
|
|
1226
|
-
path:
|
|
1259
|
+
path: requestPath,
|
|
1227
1260
|
query: request.query,
|
|
1228
1261
|
params: request.params,
|
|
1229
1262
|
method: request.method
|
|
@@ -1361,7 +1394,7 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1361
1394
|
if (isDevelopment) {
|
|
1362
1395
|
await this.setupDevelopmentMode();
|
|
1363
1396
|
} else {
|
|
1364
|
-
this.setupProductionMode();
|
|
1397
|
+
await this.setupProductionMode();
|
|
1365
1398
|
}
|
|
1366
1399
|
}
|
|
1367
1400
|
async setupDevelopmentMode() {
|
|
@@ -1403,18 +1436,38 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1403
1436
|
this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
|
|
1404
1437
|
}
|
|
1405
1438
|
}
|
|
1406
|
-
setupProductionMode() {
|
|
1439
|
+
async setupProductionMode() {
|
|
1407
1440
|
try {
|
|
1408
1441
|
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
1409
|
-
if (httpAdapter)
|
|
1410
|
-
|
|
1411
|
-
|
|
1442
|
+
if (!httpAdapter) return;
|
|
1443
|
+
const app = httpAdapter.getInstance();
|
|
1444
|
+
const { join: join2 } = __require("path");
|
|
1445
|
+
const staticPath = join2(process.cwd(), "dist/client");
|
|
1446
|
+
const adapterType = detectAdapterType(this.httpAdapterHost);
|
|
1447
|
+
if (adapterType === "fastify") {
|
|
1448
|
+
try {
|
|
1449
|
+
const fastifyStatic = await import('@fastify/static').catch(() => null);
|
|
1450
|
+
if (fastifyStatic) {
|
|
1451
|
+
await app.register(fastifyStatic.default, {
|
|
1452
|
+
root: staticPath,
|
|
1453
|
+
prefix: "/",
|
|
1454
|
+
index: false,
|
|
1455
|
+
maxAge: 31536e6
|
|
1456
|
+
});
|
|
1457
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
|
|
1458
|
+
} else {
|
|
1459
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1460
|
+
}
|
|
1461
|
+
} catch {
|
|
1462
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1463
|
+
}
|
|
1464
|
+
} else {
|
|
1412
1465
|
const express = __require("express");
|
|
1413
|
-
app.use(express.static(
|
|
1466
|
+
app.use(express.static(staticPath, {
|
|
1414
1467
|
index: false,
|
|
1415
1468
|
maxAge: "1y"
|
|
1416
1469
|
}));
|
|
1417
|
-
this.logger.log("\u2713 Static assets configured (dist/client)");
|
|
1470
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
|
|
1418
1471
|
}
|
|
1419
1472
|
} catch (error) {
|
|
1420
1473
|
this.logger.warn(`Failed to setup static assets: ${error.message}`);
|
package/dist/index.mjs
CHANGED
|
@@ -455,6 +455,39 @@ function ErrorPageProduction() {
|
|
|
455
455
|
}
|
|
456
456
|
__name(ErrorPageProduction, "ErrorPageProduction");
|
|
457
457
|
|
|
458
|
+
// src/render/adapters/http-adapter-utils.ts
|
|
459
|
+
function detectAdapterType(httpAdapterHost) {
|
|
460
|
+
const adapter = httpAdapterHost?.httpAdapter;
|
|
461
|
+
if (!adapter) return "unknown";
|
|
462
|
+
const instance = adapter.getInstance();
|
|
463
|
+
if (instance && typeof instance.register === "function") {
|
|
464
|
+
return "fastify";
|
|
465
|
+
}
|
|
466
|
+
if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
|
|
467
|
+
return "express";
|
|
468
|
+
}
|
|
469
|
+
return "unknown";
|
|
470
|
+
}
|
|
471
|
+
__name(detectAdapterType, "detectAdapterType");
|
|
472
|
+
function isFastifyLikeResponse(res) {
|
|
473
|
+
return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
|
|
474
|
+
}
|
|
475
|
+
__name(isFastifyLikeResponse, "isFastifyLikeResponse");
|
|
476
|
+
function getRawResponse(res) {
|
|
477
|
+
if (isFastifyLikeResponse(res)) {
|
|
478
|
+
return res.raw;
|
|
479
|
+
}
|
|
480
|
+
return res;
|
|
481
|
+
}
|
|
482
|
+
__name(getRawResponse, "getRawResponse");
|
|
483
|
+
function isHeadersSent(res) {
|
|
484
|
+
if (typeof res.sent === "boolean") {
|
|
485
|
+
return res.sent;
|
|
486
|
+
}
|
|
487
|
+
return res.headersSent === true;
|
|
488
|
+
}
|
|
489
|
+
__name(isHeadersSent, "isHeadersSent");
|
|
490
|
+
|
|
458
491
|
// src/render/streaming-error-handler.ts
|
|
459
492
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
460
493
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -490,21 +523,19 @@ var StreamingErrorHandler = class _StreamingErrorHandler {
|
|
|
490
523
|
*/
|
|
491
524
|
handleShellError(error, res, viewPath, isDevelopment) {
|
|
492
525
|
this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
|
|
493
|
-
|
|
526
|
+
const rawRes = getRawResponse(res);
|
|
527
|
+
if (isHeadersSent(res)) {
|
|
494
528
|
this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
|
|
495
|
-
if (!
|
|
496
|
-
|
|
497
|
-
|
|
529
|
+
if (!rawRes.writableEnded) {
|
|
530
|
+
rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
|
|
531
|
+
rawRes.end();
|
|
498
532
|
}
|
|
499
533
|
return;
|
|
500
534
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
} else {
|
|
506
|
-
res.send(this.renderProductionErrorPage());
|
|
507
|
-
}
|
|
535
|
+
rawRes.statusCode = 500;
|
|
536
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
537
|
+
const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
|
|
538
|
+
rawRes.end(html);
|
|
508
539
|
}
|
|
509
540
|
/**
|
|
510
541
|
* Handle error that occurred during streaming
|
|
@@ -660,7 +691,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
660
691
|
*
|
|
661
692
|
* @param viewComponent - The React component to render
|
|
662
693
|
* @param data - Data to pass to the component
|
|
663
|
-
* @param res -
|
|
694
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
664
695
|
* @param context - Render context with Vite and manifest info
|
|
665
696
|
* @param head - Head data for SEO tags
|
|
666
697
|
*/
|
|
@@ -702,20 +733,21 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
702
733
|
const { PassThrough } = await import('stream');
|
|
703
734
|
const reactStream = new PassThrough();
|
|
704
735
|
let allReadyFired = false;
|
|
736
|
+
const rawRes = getRawResponse(res);
|
|
705
737
|
const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
|
|
706
738
|
onShellReady: /* @__PURE__ */ __name(() => {
|
|
707
739
|
shellReadyTime = Date.now();
|
|
708
|
-
if (!
|
|
709
|
-
|
|
710
|
-
|
|
740
|
+
if (!rawRes.headersSent) {
|
|
741
|
+
rawRes.statusCode = didError ? 500 : 200;
|
|
742
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
711
743
|
}
|
|
712
744
|
let htmlStart = templateParts.htmlStart;
|
|
713
745
|
htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
|
|
714
746
|
htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
|
|
715
|
-
|
|
716
|
-
|
|
747
|
+
rawRes.write(htmlStart);
|
|
748
|
+
rawRes.write(templateParts.rootStart);
|
|
717
749
|
pipe(reactStream);
|
|
718
|
-
reactStream.pipe(
|
|
750
|
+
reactStream.pipe(rawRes, {
|
|
719
751
|
end: false
|
|
720
752
|
});
|
|
721
753
|
if (context.isDevelopment) {
|
|
@@ -740,11 +772,11 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
740
772
|
if (shellErrorOccurred) {
|
|
741
773
|
return;
|
|
742
774
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
775
|
+
rawRes.write(inlineScripts);
|
|
776
|
+
rawRes.write(clientScript);
|
|
777
|
+
rawRes.write(templateParts.rootEnd);
|
|
778
|
+
rawRes.write(templateParts.htmlEnd);
|
|
779
|
+
rawRes.end();
|
|
748
780
|
if (context.isDevelopment) {
|
|
749
781
|
const totalTime = Date.now() - startTime;
|
|
750
782
|
const streamTime = Date.now() - shellReadyTime;
|
|
@@ -756,7 +788,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
756
788
|
reactStream.on("error", (error) => {
|
|
757
789
|
reject(error);
|
|
758
790
|
});
|
|
759
|
-
|
|
791
|
+
rawRes.on("close", () => {
|
|
760
792
|
abort();
|
|
761
793
|
resolve();
|
|
762
794
|
});
|
|
@@ -1214,9 +1246,10 @@ var RenderInterceptor = class {
|
|
|
1214
1246
|
if (typeof data === "string") {
|
|
1215
1247
|
return data;
|
|
1216
1248
|
}
|
|
1249
|
+
const requestPath = request.path ?? request.url?.split("?")[0] ?? "/";
|
|
1217
1250
|
const renderContext = {
|
|
1218
1251
|
url: request.url,
|
|
1219
|
-
path:
|
|
1252
|
+
path: requestPath,
|
|
1220
1253
|
query: request.query,
|
|
1221
1254
|
params: request.params,
|
|
1222
1255
|
method: request.method
|
|
@@ -1354,7 +1387,7 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1354
1387
|
if (isDevelopment) {
|
|
1355
1388
|
await this.setupDevelopmentMode();
|
|
1356
1389
|
} else {
|
|
1357
|
-
this.setupProductionMode();
|
|
1390
|
+
await this.setupProductionMode();
|
|
1358
1391
|
}
|
|
1359
1392
|
}
|
|
1360
1393
|
async setupDevelopmentMode() {
|
|
@@ -1396,18 +1429,38 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1396
1429
|
this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
|
|
1397
1430
|
}
|
|
1398
1431
|
}
|
|
1399
|
-
setupProductionMode() {
|
|
1432
|
+
async setupProductionMode() {
|
|
1400
1433
|
try {
|
|
1401
1434
|
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
1402
|
-
if (httpAdapter)
|
|
1403
|
-
|
|
1404
|
-
|
|
1435
|
+
if (!httpAdapter) return;
|
|
1436
|
+
const app = httpAdapter.getInstance();
|
|
1437
|
+
const { join: join2 } = __require("path");
|
|
1438
|
+
const staticPath = join2(process.cwd(), "dist/client");
|
|
1439
|
+
const adapterType = detectAdapterType(this.httpAdapterHost);
|
|
1440
|
+
if (adapterType === "fastify") {
|
|
1441
|
+
try {
|
|
1442
|
+
const fastifyStatic = await import('@fastify/static').catch(() => null);
|
|
1443
|
+
if (fastifyStatic) {
|
|
1444
|
+
await app.register(fastifyStatic.default, {
|
|
1445
|
+
root: staticPath,
|
|
1446
|
+
prefix: "/",
|
|
1447
|
+
index: false,
|
|
1448
|
+
maxAge: 31536e6
|
|
1449
|
+
});
|
|
1450
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
|
|
1451
|
+
} else {
|
|
1452
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1453
|
+
}
|
|
1454
|
+
} catch {
|
|
1455
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1456
|
+
}
|
|
1457
|
+
} else {
|
|
1405
1458
|
const express = __require("express");
|
|
1406
|
-
app.use(express.static(
|
|
1459
|
+
app.use(express.static(staticPath, {
|
|
1407
1460
|
index: false,
|
|
1408
1461
|
maxAge: "1y"
|
|
1409
1462
|
}));
|
|
1410
|
-
this.logger.log("\u2713 Static assets configured (dist/client)");
|
|
1463
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
|
|
1411
1464
|
}
|
|
1412
1465
|
} catch (error) {
|
|
1413
1466
|
this.logger.warn(`Failed to setup static assets: ${error.message}`);
|
package/dist/render/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { E as ErrorPageDevelopment,
|
|
1
|
+
export { E as ErrorPageDevelopment, a as ErrorPageProduction, b as RenderInterceptor, c as RenderModule, d as RenderService, e as StreamingErrorHandler, T as TemplateParserService } from '../index-DcpOFSp4.mjs';
|
|
2
2
|
import '@nestjs/common';
|
|
3
3
|
import 'react';
|
|
4
|
-
import 'express';
|
|
5
4
|
import '../render-response.interface-ClWJXKL4.mjs';
|
|
5
|
+
import 'http';
|
|
6
6
|
import 'vite';
|
|
7
7
|
import '@nestjs/core';
|
|
8
8
|
import 'rxjs';
|
package/dist/render/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { E as ErrorPageDevelopment,
|
|
1
|
+
export { E as ErrorPageDevelopment, a as ErrorPageProduction, b as RenderInterceptor, c as RenderModule, d as RenderService, e as StreamingErrorHandler, T as TemplateParserService } from '../index-CGfEDKI4.js';
|
|
2
2
|
import '@nestjs/common';
|
|
3
3
|
import 'react';
|
|
4
|
-
import 'express';
|
|
5
4
|
import '../render-response.interface-ClWJXKL4.js';
|
|
5
|
+
import 'http';
|
|
6
6
|
import 'vite';
|
|
7
7
|
import '@nestjs/core';
|
|
8
8
|
import 'rxjs';
|
package/dist/render/index.js
CHANGED
|
@@ -461,6 +461,39 @@ function ErrorPageProduction() {
|
|
|
461
461
|
}
|
|
462
462
|
__name(ErrorPageProduction, "ErrorPageProduction");
|
|
463
463
|
|
|
464
|
+
// src/render/adapters/http-adapter-utils.ts
|
|
465
|
+
function detectAdapterType(httpAdapterHost) {
|
|
466
|
+
const adapter = httpAdapterHost?.httpAdapter;
|
|
467
|
+
if (!adapter) return "unknown";
|
|
468
|
+
const instance = adapter.getInstance();
|
|
469
|
+
if (instance && typeof instance.register === "function") {
|
|
470
|
+
return "fastify";
|
|
471
|
+
}
|
|
472
|
+
if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
|
|
473
|
+
return "express";
|
|
474
|
+
}
|
|
475
|
+
return "unknown";
|
|
476
|
+
}
|
|
477
|
+
__name(detectAdapterType, "detectAdapterType");
|
|
478
|
+
function isFastifyLikeResponse(res) {
|
|
479
|
+
return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
|
|
480
|
+
}
|
|
481
|
+
__name(isFastifyLikeResponse, "isFastifyLikeResponse");
|
|
482
|
+
function getRawResponse(res) {
|
|
483
|
+
if (isFastifyLikeResponse(res)) {
|
|
484
|
+
return res.raw;
|
|
485
|
+
}
|
|
486
|
+
return res;
|
|
487
|
+
}
|
|
488
|
+
__name(getRawResponse, "getRawResponse");
|
|
489
|
+
function isHeadersSent(res) {
|
|
490
|
+
if (typeof res.sent === "boolean") {
|
|
491
|
+
return res.sent;
|
|
492
|
+
}
|
|
493
|
+
return res.headersSent === true;
|
|
494
|
+
}
|
|
495
|
+
__name(isHeadersSent, "isHeadersSent");
|
|
496
|
+
|
|
464
497
|
// src/render/streaming-error-handler.ts
|
|
465
498
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
466
499
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -496,21 +529,19 @@ exports.StreamingErrorHandler = class _StreamingErrorHandler {
|
|
|
496
529
|
*/
|
|
497
530
|
handleShellError(error, res, viewPath, isDevelopment) {
|
|
498
531
|
this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
|
|
499
|
-
|
|
532
|
+
const rawRes = getRawResponse(res);
|
|
533
|
+
if (isHeadersSent(res)) {
|
|
500
534
|
this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
|
|
501
|
-
if (!
|
|
502
|
-
|
|
503
|
-
|
|
535
|
+
if (!rawRes.writableEnded) {
|
|
536
|
+
rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
|
|
537
|
+
rawRes.end();
|
|
504
538
|
}
|
|
505
539
|
return;
|
|
506
540
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
} else {
|
|
512
|
-
res.send(this.renderProductionErrorPage());
|
|
513
|
-
}
|
|
541
|
+
rawRes.statusCode = 500;
|
|
542
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
543
|
+
const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
|
|
544
|
+
rawRes.end(html);
|
|
514
545
|
}
|
|
515
546
|
/**
|
|
516
547
|
* Handle error that occurred during streaming
|
|
@@ -666,7 +697,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
666
697
|
*
|
|
667
698
|
* @param viewComponent - The React component to render
|
|
668
699
|
* @param data - Data to pass to the component
|
|
669
|
-
* @param res -
|
|
700
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
670
701
|
* @param context - Render context with Vite and manifest info
|
|
671
702
|
* @param head - Head data for SEO tags
|
|
672
703
|
*/
|
|
@@ -708,20 +739,21 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
708
739
|
const { PassThrough } = await import('stream');
|
|
709
740
|
const reactStream = new PassThrough();
|
|
710
741
|
let allReadyFired = false;
|
|
742
|
+
const rawRes = getRawResponse(res);
|
|
711
743
|
const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
|
|
712
744
|
onShellReady: /* @__PURE__ */ __name(() => {
|
|
713
745
|
shellReadyTime = Date.now();
|
|
714
|
-
if (!
|
|
715
|
-
|
|
716
|
-
|
|
746
|
+
if (!rawRes.headersSent) {
|
|
747
|
+
rawRes.statusCode = didError ? 500 : 200;
|
|
748
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
717
749
|
}
|
|
718
750
|
let htmlStart = templateParts.htmlStart;
|
|
719
751
|
htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
|
|
720
752
|
htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
|
|
721
|
-
|
|
722
|
-
|
|
753
|
+
rawRes.write(htmlStart);
|
|
754
|
+
rawRes.write(templateParts.rootStart);
|
|
723
755
|
pipe(reactStream);
|
|
724
|
-
reactStream.pipe(
|
|
756
|
+
reactStream.pipe(rawRes, {
|
|
725
757
|
end: false
|
|
726
758
|
});
|
|
727
759
|
if (context.isDevelopment) {
|
|
@@ -746,11 +778,11 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
746
778
|
if (shellErrorOccurred) {
|
|
747
779
|
return;
|
|
748
780
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
781
|
+
rawRes.write(inlineScripts);
|
|
782
|
+
rawRes.write(clientScript);
|
|
783
|
+
rawRes.write(templateParts.rootEnd);
|
|
784
|
+
rawRes.write(templateParts.htmlEnd);
|
|
785
|
+
rawRes.end();
|
|
754
786
|
if (context.isDevelopment) {
|
|
755
787
|
const totalTime = Date.now() - startTime;
|
|
756
788
|
const streamTime = Date.now() - shellReadyTime;
|
|
@@ -762,7 +794,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
762
794
|
reactStream.on("error", (error) => {
|
|
763
795
|
reject(error);
|
|
764
796
|
});
|
|
765
|
-
|
|
797
|
+
rawRes.on("close", () => {
|
|
766
798
|
abort();
|
|
767
799
|
resolve();
|
|
768
800
|
});
|
|
@@ -1202,9 +1234,10 @@ exports.RenderInterceptor = class RenderInterceptor {
|
|
|
1202
1234
|
if (typeof data === "string") {
|
|
1203
1235
|
return data;
|
|
1204
1236
|
}
|
|
1237
|
+
const requestPath = request.path ?? request.url?.split("?")[0] ?? "/";
|
|
1205
1238
|
const renderContext = {
|
|
1206
1239
|
url: request.url,
|
|
1207
|
-
path:
|
|
1240
|
+
path: requestPath,
|
|
1208
1241
|
query: request.query,
|
|
1209
1242
|
params: request.params,
|
|
1210
1243
|
method: request.method
|
|
@@ -1342,7 +1375,7 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1342
1375
|
if (isDevelopment) {
|
|
1343
1376
|
await this.setupDevelopmentMode();
|
|
1344
1377
|
} else {
|
|
1345
|
-
this.setupProductionMode();
|
|
1378
|
+
await this.setupProductionMode();
|
|
1346
1379
|
}
|
|
1347
1380
|
}
|
|
1348
1381
|
async setupDevelopmentMode() {
|
|
@@ -1384,18 +1417,38 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1384
1417
|
this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
|
|
1385
1418
|
}
|
|
1386
1419
|
}
|
|
1387
|
-
setupProductionMode() {
|
|
1420
|
+
async setupProductionMode() {
|
|
1388
1421
|
try {
|
|
1389
1422
|
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
1390
|
-
if (httpAdapter)
|
|
1391
|
-
|
|
1392
|
-
|
|
1423
|
+
if (!httpAdapter) return;
|
|
1424
|
+
const app = httpAdapter.getInstance();
|
|
1425
|
+
const { join: join2 } = __require("path");
|
|
1426
|
+
const staticPath = join2(process.cwd(), "dist/client");
|
|
1427
|
+
const adapterType = detectAdapterType(this.httpAdapterHost);
|
|
1428
|
+
if (adapterType === "fastify") {
|
|
1429
|
+
try {
|
|
1430
|
+
const fastifyStatic = await import('@fastify/static').catch(() => null);
|
|
1431
|
+
if (fastifyStatic) {
|
|
1432
|
+
await app.register(fastifyStatic.default, {
|
|
1433
|
+
root: staticPath,
|
|
1434
|
+
prefix: "/",
|
|
1435
|
+
index: false,
|
|
1436
|
+
maxAge: 31536e6
|
|
1437
|
+
});
|
|
1438
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
|
|
1439
|
+
} else {
|
|
1440
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1441
|
+
}
|
|
1442
|
+
} catch {
|
|
1443
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1444
|
+
}
|
|
1445
|
+
} else {
|
|
1393
1446
|
const express = __require("express");
|
|
1394
|
-
app.use(express.static(
|
|
1447
|
+
app.use(express.static(staticPath, {
|
|
1395
1448
|
index: false,
|
|
1396
1449
|
maxAge: "1y"
|
|
1397
1450
|
}));
|
|
1398
|
-
this.logger.log("\u2713 Static assets configured (dist/client)");
|
|
1451
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
|
|
1399
1452
|
}
|
|
1400
1453
|
} catch (error) {
|
|
1401
1454
|
this.logger.warn(`Failed to setup static assets: ${error.message}`);
|
package/dist/render/index.mjs
CHANGED
|
@@ -455,6 +455,39 @@ function ErrorPageProduction() {
|
|
|
455
455
|
}
|
|
456
456
|
__name(ErrorPageProduction, "ErrorPageProduction");
|
|
457
457
|
|
|
458
|
+
// src/render/adapters/http-adapter-utils.ts
|
|
459
|
+
function detectAdapterType(httpAdapterHost) {
|
|
460
|
+
const adapter = httpAdapterHost?.httpAdapter;
|
|
461
|
+
if (!adapter) return "unknown";
|
|
462
|
+
const instance = adapter.getInstance();
|
|
463
|
+
if (instance && typeof instance.register === "function") {
|
|
464
|
+
return "fastify";
|
|
465
|
+
}
|
|
466
|
+
if (instance && typeof instance.use === "function" && typeof instance.get === "function") {
|
|
467
|
+
return "express";
|
|
468
|
+
}
|
|
469
|
+
return "unknown";
|
|
470
|
+
}
|
|
471
|
+
__name(detectAdapterType, "detectAdapterType");
|
|
472
|
+
function isFastifyLikeResponse(res) {
|
|
473
|
+
return res != null && typeof res === "object" && "raw" in res && res.raw != null && typeof res.raw.write === "function";
|
|
474
|
+
}
|
|
475
|
+
__name(isFastifyLikeResponse, "isFastifyLikeResponse");
|
|
476
|
+
function getRawResponse(res) {
|
|
477
|
+
if (isFastifyLikeResponse(res)) {
|
|
478
|
+
return res.raw;
|
|
479
|
+
}
|
|
480
|
+
return res;
|
|
481
|
+
}
|
|
482
|
+
__name(getRawResponse, "getRawResponse");
|
|
483
|
+
function isHeadersSent(res) {
|
|
484
|
+
if (typeof res.sent === "boolean") {
|
|
485
|
+
return res.sent;
|
|
486
|
+
}
|
|
487
|
+
return res.headersSent === true;
|
|
488
|
+
}
|
|
489
|
+
__name(isHeadersSent, "isHeadersSent");
|
|
490
|
+
|
|
458
491
|
// src/render/streaming-error-handler.ts
|
|
459
492
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
460
493
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -490,21 +523,19 @@ var StreamingErrorHandler = class _StreamingErrorHandler {
|
|
|
490
523
|
*/
|
|
491
524
|
handleShellError(error, res, viewPath, isDevelopment) {
|
|
492
525
|
this.logger.error(`Shell error rendering ${viewPath}: ${error.message}`, error.stack);
|
|
493
|
-
|
|
526
|
+
const rawRes = getRawResponse(res);
|
|
527
|
+
if (isHeadersSent(res)) {
|
|
494
528
|
this.logger.error(`Cannot send error page for ${viewPath} - headers already sent (streaming started)`);
|
|
495
|
-
if (!
|
|
496
|
-
|
|
497
|
-
|
|
529
|
+
if (!rawRes.writableEnded) {
|
|
530
|
+
rawRes.write(this.renderInlineErrorOverlay(error, viewPath, isDevelopment));
|
|
531
|
+
rawRes.end();
|
|
498
532
|
}
|
|
499
533
|
return;
|
|
500
534
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
} else {
|
|
506
|
-
res.send(this.renderProductionErrorPage());
|
|
507
|
-
}
|
|
535
|
+
rawRes.statusCode = 500;
|
|
536
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
537
|
+
const html = isDevelopment ? this.renderDevelopmentErrorPage(error, viewPath, "shell") : this.renderProductionErrorPage();
|
|
538
|
+
rawRes.end(html);
|
|
508
539
|
}
|
|
509
540
|
/**
|
|
510
541
|
* Handle error that occurred during streaming
|
|
@@ -660,7 +691,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
660
691
|
*
|
|
661
692
|
* @param viewComponent - The React component to render
|
|
662
693
|
* @param data - Data to pass to the component
|
|
663
|
-
* @param res -
|
|
694
|
+
* @param res - HTTP response object (Express or Fastify)
|
|
664
695
|
* @param context - Render context with Vite and manifest info
|
|
665
696
|
* @param head - Head data for SEO tags
|
|
666
697
|
*/
|
|
@@ -702,20 +733,21 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
702
733
|
const { PassThrough } = await import('stream');
|
|
703
734
|
const reactStream = new PassThrough();
|
|
704
735
|
let allReadyFired = false;
|
|
736
|
+
const rawRes = getRawResponse(res);
|
|
705
737
|
const { pipe, abort } = renderModule.renderComponentStream(viewComponent, data, {
|
|
706
738
|
onShellReady: /* @__PURE__ */ __name(() => {
|
|
707
739
|
shellReadyTime = Date.now();
|
|
708
|
-
if (!
|
|
709
|
-
|
|
710
|
-
|
|
740
|
+
if (!rawRes.headersSent) {
|
|
741
|
+
rawRes.statusCode = didError ? 500 : 200;
|
|
742
|
+
rawRes.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
711
743
|
}
|
|
712
744
|
let htmlStart = templateParts.htmlStart;
|
|
713
745
|
htmlStart = htmlStart.replace("<!--styles-->", stylesheetTags);
|
|
714
746
|
htmlStart = htmlStart.replace("<!--head-meta-->", headTags);
|
|
715
|
-
|
|
716
|
-
|
|
747
|
+
rawRes.write(htmlStart);
|
|
748
|
+
rawRes.write(templateParts.rootStart);
|
|
717
749
|
pipe(reactStream);
|
|
718
|
-
reactStream.pipe(
|
|
750
|
+
reactStream.pipe(rawRes, {
|
|
719
751
|
end: false
|
|
720
752
|
});
|
|
721
753
|
if (context.isDevelopment) {
|
|
@@ -740,11 +772,11 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
740
772
|
if (shellErrorOccurred) {
|
|
741
773
|
return;
|
|
742
774
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
775
|
+
rawRes.write(inlineScripts);
|
|
776
|
+
rawRes.write(clientScript);
|
|
777
|
+
rawRes.write(templateParts.rootEnd);
|
|
778
|
+
rawRes.write(templateParts.htmlEnd);
|
|
779
|
+
rawRes.end();
|
|
748
780
|
if (context.isDevelopment) {
|
|
749
781
|
const totalTime = Date.now() - startTime;
|
|
750
782
|
const streamTime = Date.now() - shellReadyTime;
|
|
@@ -756,7 +788,7 @@ var StreamRenderer = class _StreamRenderer {
|
|
|
756
788
|
reactStream.on("error", (error) => {
|
|
757
789
|
reject(error);
|
|
758
790
|
});
|
|
759
|
-
|
|
791
|
+
rawRes.on("close", () => {
|
|
760
792
|
abort();
|
|
761
793
|
resolve();
|
|
762
794
|
});
|
|
@@ -1196,9 +1228,10 @@ var RenderInterceptor = class {
|
|
|
1196
1228
|
if (typeof data === "string") {
|
|
1197
1229
|
return data;
|
|
1198
1230
|
}
|
|
1231
|
+
const requestPath = request.path ?? request.url?.split("?")[0] ?? "/";
|
|
1199
1232
|
const renderContext = {
|
|
1200
1233
|
url: request.url,
|
|
1201
|
-
path:
|
|
1234
|
+
path: requestPath,
|
|
1202
1235
|
query: request.query,
|
|
1203
1236
|
params: request.params,
|
|
1204
1237
|
method: request.method
|
|
@@ -1336,7 +1369,7 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1336
1369
|
if (isDevelopment) {
|
|
1337
1370
|
await this.setupDevelopmentMode();
|
|
1338
1371
|
} else {
|
|
1339
|
-
this.setupProductionMode();
|
|
1372
|
+
await this.setupProductionMode();
|
|
1340
1373
|
}
|
|
1341
1374
|
}
|
|
1342
1375
|
async setupDevelopmentMode() {
|
|
@@ -1378,18 +1411,38 @@ var ViteInitializerService = class _ViteInitializerService {
|
|
|
1378
1411
|
this.logger.warn(`Failed to setup Vite proxy: ${error.message}. Make sure http-proxy-middleware is installed.`);
|
|
1379
1412
|
}
|
|
1380
1413
|
}
|
|
1381
|
-
setupProductionMode() {
|
|
1414
|
+
async setupProductionMode() {
|
|
1382
1415
|
try {
|
|
1383
1416
|
const httpAdapter = this.httpAdapterHost.httpAdapter;
|
|
1384
|
-
if (httpAdapter)
|
|
1385
|
-
|
|
1386
|
-
|
|
1417
|
+
if (!httpAdapter) return;
|
|
1418
|
+
const app = httpAdapter.getInstance();
|
|
1419
|
+
const { join: join2 } = __require("path");
|
|
1420
|
+
const staticPath = join2(process.cwd(), "dist/client");
|
|
1421
|
+
const adapterType = detectAdapterType(this.httpAdapterHost);
|
|
1422
|
+
if (adapterType === "fastify") {
|
|
1423
|
+
try {
|
|
1424
|
+
const fastifyStatic = await import('@fastify/static').catch(() => null);
|
|
1425
|
+
if (fastifyStatic) {
|
|
1426
|
+
await app.register(fastifyStatic.default, {
|
|
1427
|
+
root: staticPath,
|
|
1428
|
+
prefix: "/",
|
|
1429
|
+
index: false,
|
|
1430
|
+
maxAge: 31536e6
|
|
1431
|
+
});
|
|
1432
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Fastify]");
|
|
1433
|
+
} else {
|
|
1434
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1435
|
+
}
|
|
1436
|
+
} catch {
|
|
1437
|
+
this.logger.warn("For Fastify static file serving, install @fastify/static: npm install @fastify/static");
|
|
1438
|
+
}
|
|
1439
|
+
} else {
|
|
1387
1440
|
const express = __require("express");
|
|
1388
|
-
app.use(express.static(
|
|
1441
|
+
app.use(express.static(staticPath, {
|
|
1389
1442
|
index: false,
|
|
1390
1443
|
maxAge: "1y"
|
|
1391
1444
|
}));
|
|
1392
|
-
this.logger.log("\u2713 Static assets configured (dist/client)");
|
|
1445
|
+
this.logger.log("\u2713 Static assets configured (dist/client) [Express]");
|
|
1393
1446
|
}
|
|
1394
1447
|
} catch (error) {
|
|
1395
1448
|
this.logger.warn(`Failed to setup static assets: ${error.message}`);
|
|
@@ -279,4 +279,4 @@ declare const useHeader: (name: string) => string | undefined;
|
|
|
279
279
|
declare const useCookies: () => Record<string, string>;
|
|
280
280
|
declare const useCookie: (name: string) => string | undefined;
|
|
281
281
|
|
|
282
|
-
export { type PageProps as P, PageContextProvider as a,
|
|
282
|
+
export { type PageProps as P, PageContextProvider as a, useCookies as b, createSSRHooks as c, useHeader as d, useHeaders as e, usePageContext as f, useParams as g, useQuery as h, useRequest as i, updatePageContext as j, useCookie as u };
|
|
@@ -279,4 +279,4 @@ declare const useHeader: (name: string) => string | undefined;
|
|
|
279
279
|
declare const useCookies: () => Record<string, string>;
|
|
280
280
|
declare const useCookie: (name: string) => string | undefined;
|
|
281
281
|
|
|
282
|
-
export { type PageProps as P, PageContextProvider as a,
|
|
282
|
+
export { type PageProps as P, PageContextProvider as a, useCookies as b, createSSRHooks as c, useHeader as d, useHeaders as e, usePageContext as f, useParams as g, useQuery as h, useRequest as i, updatePageContext as j, useCookie as u };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs-ssr/react",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "React SSR for NestJS that respects Clean Architecture. Proper DI, SOLID principles, clear separation of concerns.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nestjs",
|
|
@@ -109,9 +109,11 @@
|
|
|
109
109
|
}
|
|
110
110
|
],
|
|
111
111
|
"peerDependencies": {
|
|
112
|
+
"@fastify/static": "^8.0.0 || ^7.0.0",
|
|
112
113
|
"@nestjs/common": "^11.0.0",
|
|
113
114
|
"@nestjs/core": "^11.0.0",
|
|
114
115
|
"@nestjs/platform-express": "^11.0.0",
|
|
116
|
+
"@nestjs/platform-fastify": "^11.0.0",
|
|
115
117
|
"http-proxy-middleware": "^3.0.0 || ^2.0.0",
|
|
116
118
|
"react": "^19.0.0",
|
|
117
119
|
"react-dom": "^19.0.0",
|
|
@@ -119,43 +121,52 @@
|
|
|
119
121
|
"vite": "^7.0.0 || ^6.0.0"
|
|
120
122
|
},
|
|
121
123
|
"peerDependenciesMeta": {
|
|
124
|
+
"@nestjs/platform-express": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
127
|
+
"@nestjs/platform-fastify": {
|
|
128
|
+
"optional": true
|
|
129
|
+
},
|
|
130
|
+
"@fastify/static": {
|
|
131
|
+
"optional": true
|
|
132
|
+
},
|
|
122
133
|
"http-proxy-middleware": {
|
|
123
134
|
"optional": true
|
|
124
135
|
}
|
|
125
136
|
},
|
|
126
137
|
"dependencies": {
|
|
127
|
-
"citty": "^0.
|
|
138
|
+
"citty": "^0.2.0",
|
|
128
139
|
"consola": "^3.4.2",
|
|
129
|
-
"devalue": "^5.6.
|
|
140
|
+
"devalue": "^5.6.2",
|
|
130
141
|
"escape-html": "^1.0.3"
|
|
131
142
|
},
|
|
132
143
|
"devDependencies": {
|
|
133
|
-
"@microsoft/api-extractor": "^7.
|
|
134
|
-
"@nestjs/common": "^11.1.
|
|
135
|
-
"@nestjs/core": "^11.1.
|
|
136
|
-
"@nestjs/platform-express": "^11.1.
|
|
137
|
-
"@nestjs/testing": "^11.1.
|
|
138
|
-
"@playwright/test": "^1.
|
|
144
|
+
"@microsoft/api-extractor": "^7.56.2",
|
|
145
|
+
"@nestjs/common": "^11.1.13",
|
|
146
|
+
"@nestjs/core": "^11.1.13",
|
|
147
|
+
"@nestjs/platform-express": "^11.1.13",
|
|
148
|
+
"@nestjs/testing": "^11.1.13",
|
|
149
|
+
"@playwright/test": "^1.58.1",
|
|
139
150
|
"@testing-library/jest-dom": "^6.9.1",
|
|
140
|
-
"@testing-library/react": "^16.3.
|
|
151
|
+
"@testing-library/react": "^16.3.2",
|
|
141
152
|
"@types/escape-html": "^1.0.4",
|
|
142
153
|
"@types/express": "^5.0.6",
|
|
143
|
-
"@types/node": "^25.
|
|
144
|
-
"@types/react": "^19.2.
|
|
154
|
+
"@types/node": "^25.2.1",
|
|
155
|
+
"@types/react": "^19.2.13",
|
|
145
156
|
"@types/react-dom": "^19.2.3",
|
|
146
157
|
"@types/supertest": "^6.0.3",
|
|
147
|
-
"@vitejs/plugin-react": "^5.1.
|
|
148
|
-
"@vitest/coverage-v8": "^4.0.
|
|
149
|
-
"@vitest/ui": "^4.0.
|
|
150
|
-
"happy-dom": "^20.0
|
|
151
|
-
"react": "^19.2.
|
|
152
|
-
"react-dom": "^19.2.
|
|
158
|
+
"@vitejs/plugin-react": "^5.1.3",
|
|
159
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
160
|
+
"@vitest/ui": "^4.0.18",
|
|
161
|
+
"happy-dom": "^20.5.0",
|
|
162
|
+
"react": "^19.2.4",
|
|
163
|
+
"react-dom": "^19.2.4",
|
|
153
164
|
"rxjs": "^7.8.2",
|
|
154
|
-
"supertest": "^7.
|
|
165
|
+
"supertest": "^7.2.2",
|
|
155
166
|
"tsup": "^8.5.1",
|
|
156
167
|
"typescript": "^5.9.3",
|
|
157
|
-
"vite": "^7.
|
|
158
|
-
"vitest": "^4.0.
|
|
168
|
+
"vite": "^7.3.1",
|
|
169
|
+
"vitest": "^4.0.18"
|
|
159
170
|
},
|
|
160
171
|
"publishConfig": {
|
|
161
172
|
"access": "public"
|