@nestjs-ssr/react 0.2.0 → 0.2.2

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.js ADDED
@@ -0,0 +1,207 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var React__default = /*#__PURE__*/_interopDefault(React);
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
11
+ var PageContext = /* @__PURE__ */ React.createContext(null);
12
+ function PageContextProvider({ context, children }) {
13
+ return /* @__PURE__ */ React__default.default.createElement(PageContext.Provider, {
14
+ value: context
15
+ }, children);
16
+ }
17
+ __name(PageContextProvider, "PageContextProvider");
18
+ function createSSRHooks() {
19
+ return {
20
+ /**
21
+ * Hook to access the full page context with your app's type.
22
+ * Contains URL metadata, headers, and any custom properties you've added.
23
+ */
24
+ usePageContext: /* @__PURE__ */ __name(() => {
25
+ const context = React.useContext(PageContext);
26
+ if (!context) {
27
+ throw new Error("usePageContext must be used within PageContextProvider");
28
+ }
29
+ return context;
30
+ }, "usePageContext"),
31
+ /**
32
+ * Hook to access route parameters.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // Route: /users/:id
37
+ * const params = useParams();
38
+ * console.log(params.id); // '123'
39
+ * ```
40
+ */
41
+ useParams: /* @__PURE__ */ __name(() => {
42
+ const context = React.useContext(PageContext);
43
+ if (!context) {
44
+ throw new Error("useParams must be used within PageContextProvider");
45
+ }
46
+ return context.params;
47
+ }, "useParams"),
48
+ /**
49
+ * Hook to access query string parameters.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * // URL: /search?q=react&sort=date
54
+ * const query = useQuery();
55
+ * console.log(query.q); // 'react'
56
+ * console.log(query.sort); // 'date'
57
+ * ```
58
+ */
59
+ useQuery: /* @__PURE__ */ __name(() => {
60
+ const context = React.useContext(PageContext);
61
+ if (!context) {
62
+ throw new Error("useQuery must be used within PageContextProvider");
63
+ }
64
+ return context.query;
65
+ }, "useQuery"),
66
+ /**
67
+ * Alias for usePageContext() with a more intuitive name.
68
+ * Returns the full request context with your app's type.
69
+ *
70
+ * @example
71
+ * ```tsx
72
+ * const request = useRequest();
73
+ * console.log(request.path); // '/users/123'
74
+ * console.log(request.method); // 'GET'
75
+ * console.log(request.params); // { id: '123' }
76
+ * console.log(request.query); // { search: 'foo' }
77
+ * ```
78
+ */
79
+ useRequest: /* @__PURE__ */ __name(() => {
80
+ const context = React.useContext(PageContext);
81
+ if (!context) {
82
+ throw new Error("useRequest must be used within PageContextProvider");
83
+ }
84
+ return context;
85
+ }, "useRequest"),
86
+ /**
87
+ * Hook to access headers configured via allowedHeaders.
88
+ * Returns all headers as a Record.
89
+ *
90
+ * Configure in module registration:
91
+ * ```typescript
92
+ * RenderModule.register({
93
+ * allowedHeaders: ['user-agent', 'x-tenant-id', 'x-api-version']
94
+ * })
95
+ * ```
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * const headers = useHeaders();
100
+ * console.log(headers['user-agent']); // 'Mozilla/5.0...'
101
+ * console.log(headers['x-tenant-id']); // 'tenant-123'
102
+ * console.log(headers['x-api-version']); // 'v2'
103
+ * ```
104
+ */
105
+ useHeaders: /* @__PURE__ */ __name(() => {
106
+ const context = React.useContext(PageContext);
107
+ if (!context) {
108
+ throw new Error("useHeaders must be used within PageContextProvider");
109
+ }
110
+ const baseKeys = /* @__PURE__ */ new Set([
111
+ "url",
112
+ "path",
113
+ "query",
114
+ "params",
115
+ "method",
116
+ "cookies"
117
+ ]);
118
+ const headers = {};
119
+ for (const [key, value] of Object.entries(context)) {
120
+ if (!baseKeys.has(key) && typeof value === "string") {
121
+ headers[key] = value;
122
+ }
123
+ }
124
+ return headers;
125
+ }, "useHeaders"),
126
+ /**
127
+ * Hook to access a specific custom header by name.
128
+ * Returns undefined if the header is not configured or not present.
129
+ *
130
+ * @param name - The header name (as configured in allowedHeaders)
131
+ *
132
+ * @example
133
+ * ```tsx
134
+ * const tenantId = useHeader('x-tenant-id');
135
+ * if (tenantId) {
136
+ * console.log(`Tenant: ${tenantId}`);
137
+ * }
138
+ * ```
139
+ */
140
+ useHeader: /* @__PURE__ */ __name((name) => {
141
+ const context = React.useContext(PageContext);
142
+ if (!context) {
143
+ throw new Error("useHeader must be used within PageContextProvider");
144
+ }
145
+ const value = context[name];
146
+ return typeof value === "string" ? value : void 0;
147
+ }, "useHeader"),
148
+ /**
149
+ * Hook to access cookies configured via allowedCookies.
150
+ * Returns all allowed cookies as a Record.
151
+ *
152
+ * Configure in module registration:
153
+ * ```typescript
154
+ * RenderModule.register({
155
+ * allowedCookies: ['theme', 'locale', 'consent']
156
+ * })
157
+ * ```
158
+ *
159
+ * @example
160
+ * ```tsx
161
+ * const cookies = useCookies();
162
+ * console.log(cookies.theme); // 'dark'
163
+ * console.log(cookies.locale); // 'en-US'
164
+ * ```
165
+ */
166
+ useCookies: /* @__PURE__ */ __name(() => {
167
+ const context = React.useContext(PageContext);
168
+ if (!context) {
169
+ throw new Error("useCookies must be used within PageContextProvider");
170
+ }
171
+ const cookies = context.cookies;
172
+ return typeof cookies === "object" && cookies !== null ? cookies : {};
173
+ }, "useCookies"),
174
+ /**
175
+ * Hook to access a specific cookie by name.
176
+ * Returns undefined if the cookie is not configured or not present.
177
+ *
178
+ * @param name - The cookie name (as configured in allowedCookies)
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * const theme = useCookie('theme');
183
+ * if (theme === 'dark') {
184
+ * console.log('Dark mode enabled');
185
+ * }
186
+ * ```
187
+ */
188
+ useCookie: /* @__PURE__ */ __name((name) => {
189
+ const context = React.useContext(PageContext);
190
+ if (!context) {
191
+ throw new Error("useCookie must be used within PageContextProvider");
192
+ }
193
+ const contextObj = context;
194
+ const cookies = contextObj.cookies;
195
+ if (typeof cookies === "object" && cookies !== null && !Array.isArray(cookies)) {
196
+ const cookiesRecord = cookies;
197
+ const value = cookiesRecord[name];
198
+ return typeof value === "string" ? value : void 0;
199
+ }
200
+ return void 0;
201
+ }, "useCookie")
202
+ };
203
+ }
204
+ __name(createSSRHooks, "createSSRHooks");
205
+
206
+ exports.PageContextProvider = PageContextProvider;
207
+ exports.createSSRHooks = createSSRHooks;
@@ -0,0 +1,200 @@
1
+ import React, { createContext, useContext } from 'react';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
+ var PageContext = /* @__PURE__ */ createContext(null);
6
+ function PageContextProvider({ context, children }) {
7
+ return /* @__PURE__ */ React.createElement(PageContext.Provider, {
8
+ value: context
9
+ }, children);
10
+ }
11
+ __name(PageContextProvider, "PageContextProvider");
12
+ function createSSRHooks() {
13
+ return {
14
+ /**
15
+ * Hook to access the full page context with your app's type.
16
+ * Contains URL metadata, headers, and any custom properties you've added.
17
+ */
18
+ usePageContext: /* @__PURE__ */ __name(() => {
19
+ const context = useContext(PageContext);
20
+ if (!context) {
21
+ throw new Error("usePageContext must be used within PageContextProvider");
22
+ }
23
+ return context;
24
+ }, "usePageContext"),
25
+ /**
26
+ * Hook to access route parameters.
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // Route: /users/:id
31
+ * const params = useParams();
32
+ * console.log(params.id); // '123'
33
+ * ```
34
+ */
35
+ useParams: /* @__PURE__ */ __name(() => {
36
+ const context = useContext(PageContext);
37
+ if (!context) {
38
+ throw new Error("useParams must be used within PageContextProvider");
39
+ }
40
+ return context.params;
41
+ }, "useParams"),
42
+ /**
43
+ * Hook to access query string parameters.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * // URL: /search?q=react&sort=date
48
+ * const query = useQuery();
49
+ * console.log(query.q); // 'react'
50
+ * console.log(query.sort); // 'date'
51
+ * ```
52
+ */
53
+ useQuery: /* @__PURE__ */ __name(() => {
54
+ const context = useContext(PageContext);
55
+ if (!context) {
56
+ throw new Error("useQuery must be used within PageContextProvider");
57
+ }
58
+ return context.query;
59
+ }, "useQuery"),
60
+ /**
61
+ * Alias for usePageContext() with a more intuitive name.
62
+ * Returns the full request context with your app's type.
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * const request = useRequest();
67
+ * console.log(request.path); // '/users/123'
68
+ * console.log(request.method); // 'GET'
69
+ * console.log(request.params); // { id: '123' }
70
+ * console.log(request.query); // { search: 'foo' }
71
+ * ```
72
+ */
73
+ useRequest: /* @__PURE__ */ __name(() => {
74
+ const context = useContext(PageContext);
75
+ if (!context) {
76
+ throw new Error("useRequest must be used within PageContextProvider");
77
+ }
78
+ return context;
79
+ }, "useRequest"),
80
+ /**
81
+ * Hook to access headers configured via allowedHeaders.
82
+ * Returns all headers as a Record.
83
+ *
84
+ * Configure in module registration:
85
+ * ```typescript
86
+ * RenderModule.register({
87
+ * allowedHeaders: ['user-agent', 'x-tenant-id', 'x-api-version']
88
+ * })
89
+ * ```
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * const headers = useHeaders();
94
+ * console.log(headers['user-agent']); // 'Mozilla/5.0...'
95
+ * console.log(headers['x-tenant-id']); // 'tenant-123'
96
+ * console.log(headers['x-api-version']); // 'v2'
97
+ * ```
98
+ */
99
+ useHeaders: /* @__PURE__ */ __name(() => {
100
+ const context = useContext(PageContext);
101
+ if (!context) {
102
+ throw new Error("useHeaders must be used within PageContextProvider");
103
+ }
104
+ const baseKeys = /* @__PURE__ */ new Set([
105
+ "url",
106
+ "path",
107
+ "query",
108
+ "params",
109
+ "method",
110
+ "cookies"
111
+ ]);
112
+ const headers = {};
113
+ for (const [key, value] of Object.entries(context)) {
114
+ if (!baseKeys.has(key) && typeof value === "string") {
115
+ headers[key] = value;
116
+ }
117
+ }
118
+ return headers;
119
+ }, "useHeaders"),
120
+ /**
121
+ * Hook to access a specific custom header by name.
122
+ * Returns undefined if the header is not configured or not present.
123
+ *
124
+ * @param name - The header name (as configured in allowedHeaders)
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * const tenantId = useHeader('x-tenant-id');
129
+ * if (tenantId) {
130
+ * console.log(`Tenant: ${tenantId}`);
131
+ * }
132
+ * ```
133
+ */
134
+ useHeader: /* @__PURE__ */ __name((name) => {
135
+ const context = useContext(PageContext);
136
+ if (!context) {
137
+ throw new Error("useHeader must be used within PageContextProvider");
138
+ }
139
+ const value = context[name];
140
+ return typeof value === "string" ? value : void 0;
141
+ }, "useHeader"),
142
+ /**
143
+ * Hook to access cookies configured via allowedCookies.
144
+ * Returns all allowed cookies as a Record.
145
+ *
146
+ * Configure in module registration:
147
+ * ```typescript
148
+ * RenderModule.register({
149
+ * allowedCookies: ['theme', 'locale', 'consent']
150
+ * })
151
+ * ```
152
+ *
153
+ * @example
154
+ * ```tsx
155
+ * const cookies = useCookies();
156
+ * console.log(cookies.theme); // 'dark'
157
+ * console.log(cookies.locale); // 'en-US'
158
+ * ```
159
+ */
160
+ useCookies: /* @__PURE__ */ __name(() => {
161
+ const context = useContext(PageContext);
162
+ if (!context) {
163
+ throw new Error("useCookies must be used within PageContextProvider");
164
+ }
165
+ const cookies = context.cookies;
166
+ return typeof cookies === "object" && cookies !== null ? cookies : {};
167
+ }, "useCookies"),
168
+ /**
169
+ * Hook to access a specific cookie by name.
170
+ * Returns undefined if the cookie is not configured or not present.
171
+ *
172
+ * @param name - The cookie name (as configured in allowedCookies)
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * const theme = useCookie('theme');
177
+ * if (theme === 'dark') {
178
+ * console.log('Dark mode enabled');
179
+ * }
180
+ * ```
181
+ */
182
+ useCookie: /* @__PURE__ */ __name((name) => {
183
+ const context = useContext(PageContext);
184
+ if (!context) {
185
+ throw new Error("useCookie must be used within PageContextProvider");
186
+ }
187
+ const contextObj = context;
188
+ const cookies = contextObj.cookies;
189
+ if (typeof cookies === "object" && cookies !== null && !Array.isArray(cookies)) {
190
+ const cookiesRecord = cookies;
191
+ const value = cookiesRecord[name];
192
+ return typeof value === "string" ? value : void 0;
193
+ }
194
+ return void 0;
195
+ }, "useCookie")
196
+ };
197
+ }
198
+ __name(createSSRHooks, "createSSRHooks");
199
+
200
+ export { PageContextProvider, createSSRHooks };
@@ -1,114 +1,12 @@
1
1
  import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
2
  import { ComponentType } from 'react';
3
+ import { H as HeadData } from './render-response.interface-Dc-Kwb09.js';
3
4
  import { ViteDevServer } from 'vite';
4
5
  import { Response } from 'express';
5
6
  import { Reflector } from '@nestjs/core';
6
7
  import { Observable } from 'rxjs';
7
8
  import * as react_jsx_runtime from 'react/jsx-runtime';
8
9
 
9
- /**
10
- * HTML head data for SEO and page metadata
11
- */
12
- interface HeadData {
13
- /** Page title (appears in browser tab and search results) */
14
- title?: string;
15
- /** Page description for search engines */
16
- description?: string;
17
- /** Page keywords (legacy, less important for modern SEO) */
18
- keywords?: string;
19
- /** Canonical URL for duplicate content */
20
- canonical?: string;
21
- /** Open Graph title for social media sharing */
22
- ogTitle?: string;
23
- /** Open Graph description for social media sharing */
24
- ogDescription?: string;
25
- /** Open Graph image URL for social media previews */
26
- ogImage?: string;
27
- /** Additional link tags (fonts, icons, preloads, etc.) */
28
- links?: Array<{
29
- rel: string;
30
- href: string;
31
- as?: string;
32
- type?: string;
33
- crossorigin?: string;
34
- [key: string]: any;
35
- }>;
36
- /** Additional meta tags */
37
- meta?: Array<{
38
- name?: string;
39
- property?: string;
40
- content: string;
41
- [key: string]: any;
42
- }>;
43
- /** Script tags for analytics, tracking, etc. */
44
- scripts?: Array<{
45
- src?: string;
46
- async?: boolean;
47
- defer?: boolean;
48
- type?: string;
49
- innerHTML?: string;
50
- [key: string]: any;
51
- }>;
52
- /** JSON-LD structured data for search engines */
53
- jsonLd?: Array<Record<string, any>>;
54
- /** Attributes to add to <html> tag (e.g., lang, dir) */
55
- htmlAttributes?: Record<string, string>;
56
- /** Attributes to add to <body> tag (e.g., class, data-theme) */
57
- bodyAttributes?: Record<string, string>;
58
- }
59
- /**
60
- * Response structure for SSR rendering
61
- *
62
- * Can be returned from controllers decorated with @Render.
63
- * For backwards compatibility, controllers can also return plain objects
64
- * which will be auto-wrapped as { props: data }.
65
- *
66
- * @example
67
- * ```typescript
68
- * // Simple case - just props (auto-wrapped)
69
- * @Render('views/home')
70
- * getHome() {
71
- * return { message: 'Hello' };
72
- * // Treated as: { props: { message: 'Hello' } }
73
- * }
74
- *
75
- * // Advanced case - with head data and layout props
76
- * @Render('views/user')
77
- * getUser(@Param('id') id: string) {
78
- * const user = await this.userService.findOne(id);
79
- * return {
80
- * props: { user },
81
- * layoutProps: {
82
- * title: user.name,
83
- * subtitle: 'User Profile'
84
- * },
85
- * head: {
86
- * title: `${user.name} - Profile`,
87
- * description: user.bio,
88
- * ogImage: user.avatar
89
- * }
90
- * };
91
- * }
92
- * ```
93
- */
94
- interface RenderResponse<T = any> {
95
- /** Props passed to the React component */
96
- props: T;
97
- /** HTML head data (title, meta tags, links) */
98
- head?: HeadData;
99
- /**
100
- * Props passed to layout components (dynamic, per-request)
101
- *
102
- * These props are merged with static layout props from decorators:
103
- * - Static props from @Layout decorator (controller level)
104
- * - Static props from @Render decorator (method level)
105
- * - Dynamic props from this field (highest priority)
106
- *
107
- * All layout components in the hierarchy receive the merged props.
108
- */
109
- layoutProps?: Record<string, any>;
110
- }
111
-
112
10
  /**
113
11
  * SSR rendering mode configuration
114
12
  */
@@ -533,4 +431,4 @@ declare function ErrorPageDevelopment({ error, viewPath, phase, }: ErrorPageDeve
533
431
  */
534
432
  declare function ErrorPageProduction(): react_jsx_runtime.JSX.Element;
535
433
 
536
- export { ErrorPageDevelopment as E, type HeadData as H, type RenderResponse as R, StreamingErrorHandler as S, TemplateParserService as T, RenderModule as a, RenderService as b, RenderInterceptor as c, type RenderConfig as d, type SSRMode as e, ErrorPageProduction as f };
434
+ export { ErrorPageDevelopment as E, RenderModule as R, StreamingErrorHandler as S, TemplateParserService as T, RenderService as a, RenderInterceptor as b, type RenderConfig as c, type SSRMode as d, ErrorPageProduction as e };
@@ -1,114 +1,12 @@
1
1
  import { DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
2
  import { ComponentType } from 'react';
3
+ import { H as HeadData } from './render-response.interface-Dc-Kwb09.mjs';
3
4
  import { ViteDevServer } from 'vite';
4
5
  import { Response } from 'express';
5
6
  import { Reflector } from '@nestjs/core';
6
7
  import { Observable } from 'rxjs';
7
8
  import * as react_jsx_runtime from 'react/jsx-runtime';
8
9
 
9
- /**
10
- * HTML head data for SEO and page metadata
11
- */
12
- interface HeadData {
13
- /** Page title (appears in browser tab and search results) */
14
- title?: string;
15
- /** Page description for search engines */
16
- description?: string;
17
- /** Page keywords (legacy, less important for modern SEO) */
18
- keywords?: string;
19
- /** Canonical URL for duplicate content */
20
- canonical?: string;
21
- /** Open Graph title for social media sharing */
22
- ogTitle?: string;
23
- /** Open Graph description for social media sharing */
24
- ogDescription?: string;
25
- /** Open Graph image URL for social media previews */
26
- ogImage?: string;
27
- /** Additional link tags (fonts, icons, preloads, etc.) */
28
- links?: Array<{
29
- rel: string;
30
- href: string;
31
- as?: string;
32
- type?: string;
33
- crossorigin?: string;
34
- [key: string]: any;
35
- }>;
36
- /** Additional meta tags */
37
- meta?: Array<{
38
- name?: string;
39
- property?: string;
40
- content: string;
41
- [key: string]: any;
42
- }>;
43
- /** Script tags for analytics, tracking, etc. */
44
- scripts?: Array<{
45
- src?: string;
46
- async?: boolean;
47
- defer?: boolean;
48
- type?: string;
49
- innerHTML?: string;
50
- [key: string]: any;
51
- }>;
52
- /** JSON-LD structured data for search engines */
53
- jsonLd?: Array<Record<string, any>>;
54
- /** Attributes to add to <html> tag (e.g., lang, dir) */
55
- htmlAttributes?: Record<string, string>;
56
- /** Attributes to add to <body> tag (e.g., class, data-theme) */
57
- bodyAttributes?: Record<string, string>;
58
- }
59
- /**
60
- * Response structure for SSR rendering
61
- *
62
- * Can be returned from controllers decorated with @Render.
63
- * For backwards compatibility, controllers can also return plain objects
64
- * which will be auto-wrapped as { props: data }.
65
- *
66
- * @example
67
- * ```typescript
68
- * // Simple case - just props (auto-wrapped)
69
- * @Render('views/home')
70
- * getHome() {
71
- * return { message: 'Hello' };
72
- * // Treated as: { props: { message: 'Hello' } }
73
- * }
74
- *
75
- * // Advanced case - with head data and layout props
76
- * @Render('views/user')
77
- * getUser(@Param('id') id: string) {
78
- * const user = await this.userService.findOne(id);
79
- * return {
80
- * props: { user },
81
- * layoutProps: {
82
- * title: user.name,
83
- * subtitle: 'User Profile'
84
- * },
85
- * head: {
86
- * title: `${user.name} - Profile`,
87
- * description: user.bio,
88
- * ogImage: user.avatar
89
- * }
90
- * };
91
- * }
92
- * ```
93
- */
94
- interface RenderResponse<T = any> {
95
- /** Props passed to the React component */
96
- props: T;
97
- /** HTML head data (title, meta tags, links) */
98
- head?: HeadData;
99
- /**
100
- * Props passed to layout components (dynamic, per-request)
101
- *
102
- * These props are merged with static layout props from decorators:
103
- * - Static props from @Layout decorator (controller level)
104
- * - Static props from @Render decorator (method level)
105
- * - Dynamic props from this field (highest priority)
106
- *
107
- * All layout components in the hierarchy receive the merged props.
108
- */
109
- layoutProps?: Record<string, any>;
110
- }
111
-
112
10
  /**
113
11
  * SSR rendering mode configuration
114
12
  */
@@ -533,4 +431,4 @@ declare function ErrorPageDevelopment({ error, viewPath, phase, }: ErrorPageDeve
533
431
  */
534
432
  declare function ErrorPageProduction(): react_jsx_runtime.JSX.Element;
535
433
 
536
- export { ErrorPageDevelopment as E, type HeadData as H, type RenderResponse as R, StreamingErrorHandler as S, TemplateParserService as T, RenderModule as a, RenderService as b, RenderInterceptor as c, type RenderConfig as d, type SSRMode as e, ErrorPageProduction as f };
434
+ export { ErrorPageDevelopment as E, RenderModule as R, StreamingErrorHandler as S, TemplateParserService as T, RenderService as a, RenderInterceptor as b, type RenderConfig as c, type SSRMode as d, ErrorPageProduction as e };