@noego/forge 0.0.24 → 0.0.26

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.
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LiveHTMLRender = exports.DefaultHTMLRender = exports.BaseHTMLRender = void 0;
7
7
  const handlebars_1 = __importDefault(require("handlebars"));
8
8
  const promises_1 = __importDefault(require("fs/promises"));
9
+ const devalue_1 = require("devalue");
9
10
  const default_template = `
10
11
  <!DOCTYPE html>
11
12
  <html lang="en">
@@ -39,27 +40,37 @@ class BaseHTMLRender {
39
40
  // Inject window.__CONFIGURATION__ from environment variable
40
41
  const configJson = process.env.NOEGO_CONFIGURATION;
41
42
  if (configJson) {
42
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
43
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
44
- if (html.includes('</head>')) {
45
- html = html.replace('</head>', `${configScript}\n</head>`);
43
+ try {
44
+ // Parse and re-serialize with devalue to prevent XSS
45
+ const configData = JSON.parse(configJson);
46
+ const safeConfigJson = (0, devalue_1.stringify)(configData);
47
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
48
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
49
+ if (html.includes('</head>')) {
50
+ html = html.replace('</head>', `${configScript}\n</head>`);
51
+ }
52
+ else if (html.includes('<body')) {
53
+ // Find the opening body tag and inject after it
54
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
55
+ }
56
+ else {
57
+ // Fallback: inject at the beginning
58
+ html = configScript + '\n' + html;
59
+ }
46
60
  }
47
- else if (html.includes('<body')) {
48
- // Find the opening body tag and inject after it
49
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
50
- }
51
- else {
52
- // Fallback: inject at the beginning
53
- html = configScript + '\n' + html;
61
+ catch (e) {
62
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
54
63
  }
55
64
  }
56
65
  // Transform module script tags to automatically call default exports
57
66
  // Match: <script type="module" src="/path/to/module.ts"></script>
58
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
67
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
68
+ // Escape single quotes in src to prevent string breakout
69
+ const safeSrc = src.replace(/'/g, "\\'");
59
70
  // Convert to inline script that imports and calls default export
60
71
  // Wait for DOMContentLoaded and configuration to be available
61
72
  return `<script type="module">
62
- import initApp from '${src}';
73
+ import initApp from '${safeSrc}';
63
74
  function initializeApp() {
64
75
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
65
76
  const result = initApp();
@@ -99,27 +110,37 @@ class LiveHTMLRender {
99
110
  // Inject window.__CONFIGURATION__ from environment variable
100
111
  const configJson = process.env.NOEGO_CONFIGURATION;
101
112
  if (configJson) {
102
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
103
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
104
- if (html.includes('</head>')) {
105
- html = html.replace('</head>', `${configScript}\n</head>`);
106
- }
107
- else if (html.includes('<body')) {
108
- // Find the opening body tag and inject after it
109
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
113
+ try {
114
+ // Parse and re-serialize with devalue to prevent XSS
115
+ const configData = JSON.parse(configJson);
116
+ const safeConfigJson = (0, devalue_1.stringify)(configData);
117
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
118
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
119
+ if (html.includes('</head>')) {
120
+ html = html.replace('</head>', `${configScript}\n</head>`);
121
+ }
122
+ else if (html.includes('<body')) {
123
+ // Find the opening body tag and inject after it
124
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
125
+ }
126
+ else {
127
+ // Fallback: inject at the beginning
128
+ html = configScript + '\n' + html;
129
+ }
110
130
  }
111
- else {
112
- // Fallback: inject at the beginning
113
- html = configScript + '\n' + html;
131
+ catch (e) {
132
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
114
133
  }
115
134
  }
116
135
  // Transform module script tags to automatically call default exports
117
136
  // Match: <script type="module" src="/path/to/module.ts"></script>
118
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
137
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
138
+ // Escape single quotes in src to prevent string breakout
139
+ const safeSrc = src.replace(/'/g, "\\'");
119
140
  // Convert to inline script that imports and calls default export
120
141
  // Wait for DOMContentLoaded and configuration to be available
121
142
  return `<script type="module">
122
- import initApp from '${src}';
143
+ import initApp from '${safeSrc}';
123
144
  function initializeApp() {
124
145
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
125
146
  const result = initApp();
@@ -1 +1 @@
1
- {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import Handlebars from 'handlebars';
2
2
  import fs from "fs/promises";
3
+ import { stringify } from 'devalue';
3
4
  const default_template = `
4
5
  <!DOCTYPE html>
5
6
  <html lang="en">
@@ -33,27 +34,37 @@ export class BaseHTMLRender {
33
34
  // Inject window.__CONFIGURATION__ from environment variable
34
35
  const configJson = process.env.NOEGO_CONFIGURATION;
35
36
  if (configJson) {
36
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
37
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
38
- if (html.includes('</head>')) {
39
- html = html.replace('</head>', `${configScript}\n</head>`);
37
+ try {
38
+ // Parse and re-serialize with devalue to prevent XSS
39
+ const configData = JSON.parse(configJson);
40
+ const safeConfigJson = stringify(configData);
41
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
42
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
43
+ if (html.includes('</head>')) {
44
+ html = html.replace('</head>', `${configScript}\n</head>`);
45
+ }
46
+ else if (html.includes('<body')) {
47
+ // Find the opening body tag and inject after it
48
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
49
+ }
50
+ else {
51
+ // Fallback: inject at the beginning
52
+ html = configScript + '\n' + html;
53
+ }
40
54
  }
41
- else if (html.includes('<body')) {
42
- // Find the opening body tag and inject after it
43
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
44
- }
45
- else {
46
- // Fallback: inject at the beginning
47
- html = configScript + '\n' + html;
55
+ catch (e) {
56
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
48
57
  }
49
58
  }
50
59
  // Transform module script tags to automatically call default exports
51
60
  // Match: <script type="module" src="/path/to/module.ts"></script>
52
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
61
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
62
+ // Escape single quotes in src to prevent string breakout
63
+ const safeSrc = src.replace(/'/g, "\\'");
53
64
  // Convert to inline script that imports and calls default export
54
65
  // Wait for DOMContentLoaded and configuration to be available
55
66
  return `<script type="module">
56
- import initApp from '${src}';
67
+ import initApp from '${safeSrc}';
57
68
  function initializeApp() {
58
69
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
59
70
  const result = initApp();
@@ -91,27 +102,37 @@ export class LiveHTMLRender {
91
102
  // Inject window.__CONFIGURATION__ from environment variable
92
103
  const configJson = process.env.NOEGO_CONFIGURATION;
93
104
  if (configJson) {
94
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
95
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
96
- if (html.includes('</head>')) {
97
- html = html.replace('</head>', `${configScript}\n</head>`);
98
- }
99
- else if (html.includes('<body')) {
100
- // Find the opening body tag and inject after it
101
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
105
+ try {
106
+ // Parse and re-serialize with devalue to prevent XSS
107
+ const configData = JSON.parse(configJson);
108
+ const safeConfigJson = stringify(configData);
109
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
110
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
111
+ if (html.includes('</head>')) {
112
+ html = html.replace('</head>', `${configScript}\n</head>`);
113
+ }
114
+ else if (html.includes('<body')) {
115
+ // Find the opening body tag and inject after it
116
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
117
+ }
118
+ else {
119
+ // Fallback: inject at the beginning
120
+ html = configScript + '\n' + html;
121
+ }
102
122
  }
103
- else {
104
- // Fallback: inject at the beginning
105
- html = configScript + '\n' + html;
123
+ catch (e) {
124
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
106
125
  }
107
126
  }
108
127
  // Transform module script tags to automatically call default exports
109
128
  // Match: <script type="module" src="/path/to/module.ts"></script>
110
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
129
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
130
+ // Escape single quotes in src to prevent string breakout
131
+ const safeSrc = src.replace(/'/g, "\\'");
111
132
  // Convert to inline script that imports and calls default export
112
133
  // Wait for DOMContentLoaded and configuration to be available
113
134
  return `<script type="module">
114
- import initApp from '${src}';
135
+ import initApp from '${safeSrc}';
115
136
  function initializeApp() {
116
137
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
117
138
  const result = initApp();
@@ -1 +1 @@
1
- {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import Handlebars from 'handlebars';
2
2
  import fs from "fs/promises";
3
+ import { stringify } from 'devalue';
3
4
  const default_template = `
4
5
  <!DOCTYPE html>
5
6
  <html lang="en">
@@ -33,27 +34,37 @@ export class BaseHTMLRender {
33
34
  // Inject window.__CONFIGURATION__ from environment variable
34
35
  const configJson = process.env.NOEGO_CONFIGURATION;
35
36
  if (configJson) {
36
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
37
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
38
- if (html.includes('</head>')) {
39
- html = html.replace('</head>', `${configScript}\n</head>`);
37
+ try {
38
+ // Parse and re-serialize with devalue to prevent XSS
39
+ const configData = JSON.parse(configJson);
40
+ const safeConfigJson = stringify(configData);
41
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
42
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
43
+ if (html.includes('</head>')) {
44
+ html = html.replace('</head>', `${configScript}\n</head>`);
45
+ }
46
+ else if (html.includes('<body')) {
47
+ // Find the opening body tag and inject after it
48
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
49
+ }
50
+ else {
51
+ // Fallback: inject at the beginning
52
+ html = configScript + '\n' + html;
53
+ }
40
54
  }
41
- else if (html.includes('<body')) {
42
- // Find the opening body tag and inject after it
43
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
44
- }
45
- else {
46
- // Fallback: inject at the beginning
47
- html = configScript + '\n' + html;
55
+ catch (e) {
56
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
48
57
  }
49
58
  }
50
59
  // Transform module script tags to automatically call default exports
51
60
  // Match: <script type="module" src="/path/to/module.ts"></script>
52
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
61
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
62
+ // Escape single quotes in src to prevent string breakout
63
+ const safeSrc = src.replace(/'/g, "\\'");
53
64
  // Convert to inline script that imports and calls default export
54
65
  // Wait for DOMContentLoaded and configuration to be available
55
66
  return `<script type="module">
56
- import initApp from '${src}';
67
+ import initApp from '${safeSrc}';
57
68
  function initializeApp() {
58
69
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
59
70
  const result = initApp();
@@ -91,27 +102,37 @@ export class LiveHTMLRender {
91
102
  // Inject window.__CONFIGURATION__ from environment variable
92
103
  const configJson = process.env.NOEGO_CONFIGURATION;
93
104
  if (configJson) {
94
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};</script>`;
95
- // Inject before closing </head> tag, or at the beginning of <body> if no </head>
96
- if (html.includes('</head>')) {
97
- html = html.replace('</head>', `${configScript}\n</head>`);
98
- }
99
- else if (html.includes('<body')) {
100
- // Find the opening body tag and inject after it
101
- html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
105
+ try {
106
+ // Parse and re-serialize with devalue to prevent XSS
107
+ const configData = JSON.parse(configJson);
108
+ const safeConfigJson = stringify(configData);
109
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};</script>`;
110
+ // Inject before closing </head> tag, or at the beginning of <body> if no </head>
111
+ if (html.includes('</head>')) {
112
+ html = html.replace('</head>', `${configScript}\n</head>`);
113
+ }
114
+ else if (html.includes('<body')) {
115
+ // Find the opening body tag and inject after it
116
+ html = html.replace(/(<body[^>]*>)/, `$1\n${configScript}`);
117
+ }
118
+ else {
119
+ // Fallback: inject at the beginning
120
+ html = configScript + '\n' + html;
121
+ }
102
122
  }
103
- else {
104
- // Fallback: inject at the beginning
105
- html = configScript + '\n' + html;
123
+ catch (e) {
124
+ console.error('Failed to parse NOEGO_CONFIGURATION:', e);
106
125
  }
107
126
  }
108
127
  // Transform module script tags to automatically call default exports
109
128
  // Match: <script type="module" src="/path/to/module.ts"></script>
110
- html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
129
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (_match, src) => {
130
+ // Escape single quotes in src to prevent string breakout
131
+ const safeSrc = src.replace(/'/g, "\\'");
111
132
  // Convert to inline script that imports and calls default export
112
133
  // Wait for DOMContentLoaded and configuration to be available
113
134
  return `<script type="module">
114
- import initApp from '${src}';
135
+ import initApp from '${safeSrc}';
115
136
  function initializeApp() {
116
137
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
117
138
  const result = initApp();
@@ -1 +1 @@
1
- {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,7 @@ const deepmerge = require("deepmerge");
31
31
  const url = require("url");
32
32
  const Handlebars = require("handlebars");
33
33
  const fs$1 = require("fs/promises");
34
+ const devalue = require("devalue");
34
35
  const yaml = require("js-yaml");
35
36
  require("clone-deep");
36
37
  const join = require("url-join");
@@ -172,22 +173,29 @@ class BaseHTMLRender {
172
173
  let html = template(data);
173
174
  const configJson = process.env.NOEGO_CONFIGURATION;
174
175
  if (configJson) {
175
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
176
- if (html.includes("</head>")) {
177
- html = html.replace("</head>", `${configScript}
176
+ try {
177
+ const configData = JSON.parse(configJson);
178
+ const safeConfigJson = devalue.stringify(configData);
179
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};<\/script>`;
180
+ if (html.includes("</head>")) {
181
+ html = html.replace("</head>", `${configScript}
178
182
  </head>`);
179
- } else if (html.includes("<body")) {
180
- html = html.replace(/(<body[^>]*>)/, `$1
183
+ } else if (html.includes("<body")) {
184
+ html = html.replace(/(<body[^>]*>)/, `$1
181
185
  ${configScript}`);
182
- } else {
183
- html = configScript + "\n" + html;
186
+ } else {
187
+ html = configScript + "\n" + html;
188
+ }
189
+ } catch (e) {
190
+ console.error("Failed to parse NOEGO_CONFIGURATION:", e);
184
191
  }
185
192
  }
186
193
  html = html.replace(
187
194
  /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
188
- (match, src) => {
195
+ (_match, src) => {
196
+ const safeSrc = src.replace(/'/g, "\\'");
189
197
  return `<script type="module">
190
- import initApp from '${src}';
198
+ import initApp from '${safeSrc}';
191
199
  function initializeApp() {
192
200
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
193
201
  const result = initApp();
@@ -225,22 +233,29 @@ class LiveHTMLRender {
225
233
  let html = template(data);
226
234
  const configJson = process.env.NOEGO_CONFIGURATION;
227
235
  if (configJson) {
228
- const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
229
- if (html.includes("</head>")) {
230
- html = html.replace("</head>", `${configScript}
236
+ try {
237
+ const configData = JSON.parse(configJson);
238
+ const safeConfigJson = devalue.stringify(configData);
239
+ const configScript = `<script>window.__CONFIGURATION__ = ${safeConfigJson};<\/script>`;
240
+ if (html.includes("</head>")) {
241
+ html = html.replace("</head>", `${configScript}
231
242
  </head>`);
232
- } else if (html.includes("<body")) {
233
- html = html.replace(/(<body[^>]*>)/, `$1
243
+ } else if (html.includes("<body")) {
244
+ html = html.replace(/(<body[^>]*>)/, `$1
234
245
  ${configScript}`);
235
- } else {
236
- html = configScript + "\n" + html;
246
+ } else {
247
+ html = configScript + "\n" + html;
248
+ }
249
+ } catch (e) {
250
+ console.error("Failed to parse NOEGO_CONFIGURATION:", e);
237
251
  }
238
252
  }
239
253
  html = html.replace(
240
254
  /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
241
- (match, src) => {
255
+ (_match, src) => {
256
+ const safeSrc = src.replace(/'/g, "\\'");
242
257
  return `<script type="module">
243
- import initApp from '${src}';
258
+ import initApp from '${safeSrc}';
244
259
  function initializeApp() {
245
260
  if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
246
261
  const result = initApp();
@@ -689,16 +704,21 @@ class ComponentManager {
689
704
  continue;
690
705
  }
691
706
  try {
707
+ console.log(`[ComponentManager] Trying loader path: ${loaderFilePath}`);
692
708
  const module2 = await import(url.pathToFileURL(loaderFilePath).href);
693
709
  const loader = module2 == null ? void 0 : module2.default;
710
+ console.log(`[ComponentManager] Imported loader module: default=${typeof loader}`);
694
711
  if (typeof loader === "function") {
712
+ console.log(`[ComponentManager] Loaded loader function from: ${loaderFilePath}`);
695
713
  return loader;
696
714
  }
697
715
  } catch (error) {
698
- if ((error == null ? void 0 : error.code) === "MODULE_NOT_FOUND" || (error == null ? void 0 : error.code) === "ERR_MODULE_NOT_FOUND") {
716
+ const code = (error == null ? void 0 : error.code) || (error == null ? void 0 : error.name) || "UNKNOWN_ERROR";
717
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
718
+ console.warn(`[ComponentManager] Loader not found at ${loaderFilePath} (${ext}): ${(error == null ? void 0 : error.message) || code}`);
699
719
  continue;
700
720
  }
701
- console.error(`[ComponentManager] Failed to load loader for ${componentPath} (${ext}):`, error);
721
+ console.error(`[ComponentManager] Failed to load loader for ${componentPath} (${ext}) at ${loaderFilePath}:`, error);
702
722
  }
703
723
  }
704
724
  return null;
@@ -1106,23 +1126,43 @@ ${e.stack}</pre>
1106
1126
  });
1107
1127
  const body_render = renderedHtml;
1108
1128
  console.log("[SSR DEBUG] render result - body length:", (body_render == null ? void 0 : body_render.length) || 0);
1109
- const clientComponentDir = this.isProd ? "assets" : this.componentDir;
1129
+ const deriveClientBase = (dir) => {
1130
+ try {
1131
+ const norm = String(dir || "").replace(/\\/g, "/");
1132
+ const marker = "/ssr/";
1133
+ const idx = norm.indexOf(marker);
1134
+ if (idx >= 0) {
1135
+ const suffix = norm.slice(idx + marker.length).replace(/^\/+/, "");
1136
+ return suffix ? `/assets/${suffix}` : "/assets";
1137
+ }
1138
+ for (const hint of ["/components", "/pages"]) {
1139
+ const hIdx = norm.indexOf(hint);
1140
+ if (hIdx >= 0) {
1141
+ const suffix = norm.slice(hIdx + 1).replace(/^\/+/, "");
1142
+ return suffix ? `/assets/${suffix}` : "/assets";
1143
+ }
1144
+ }
1145
+ } catch {
1146
+ }
1147
+ return "/assets";
1148
+ };
1149
+ const clientComponentDir = this.isProd ? deriveClientBase(this.componentDir || "") : this.componentDir || "/assets";
1110
1150
  const head_routing = `
1111
1151
  <script type='text/javascript'>
1112
- window.__ROUTING__ = ${JSON.stringify(this.clientRoutes)}
1152
+ window.__ROUTING__ = ${devalue.stringify(this.clientRoutes)}
1113
1153
  <\/script>
1114
1154
 
1115
1155
  <script type='text/javascript'>
1116
- window.__MANIFEST__ = ${JSON.stringify(manifest)}
1156
+ window.__MANIFEST__ = ${devalue.stringify(manifest)}
1117
1157
  console.log('[MANIFEST INJECTED]', window.__MANIFEST__);
1118
1158
  <\/script>
1119
1159
 
1120
1160
  <script type='text/javascript'>
1121
- window.__INITIAL_DATA__ = ${JSON.stringify(server_data || {}).trim()}
1161
+ window.__INITIAL_DATA__ = ${devalue.stringify(server_data || {})}
1122
1162
  <\/script>
1123
1163
 
1124
1164
  <script type='text/javascript'>
1125
- window.__COMPONENT_DIR__ = ${JSON.stringify(clientComponentDir)}
1165
+ window.__COMPONENT_DIR__ = ${devalue.stringify(clientComponentDir)}
1126
1166
  <\/script>
1127
1167
  `;
1128
1168
  console.log("[SSR DEBUG] About to render HTML with APP length:", (body_render == null ? void 0 : body_render.length) || 0);
@@ -1247,8 +1287,6 @@ async function createServer(app, options) {
1247
1287
  let componentLoader;
1248
1288
  let vite;
1249
1289
  console.log(`Serving components from ${COMPONENT_DIR}`);
1250
- const rendererFullPath = typeof full_options.renderer === "string" && full_options.renderer !== "default" ? ensureFullPath(root, full_options.renderer) : ensureFullPath(root, "index.html");
1251
- path.dirname(rendererFullPath);
1252
1290
  const resolveAssetRoot = (entry) => {
1253
1291
  if (typeof entry === "function") {
1254
1292
  return entry;