@noego/forge 0.0.22 → 0.0.24

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.
@@ -29,7 +29,51 @@ export class BaseHTMLRender {
29
29
  }
30
30
  async renderHTML(data) {
31
31
  const template = Handlebars.compile(await this.getTemplate());
32
- return template(data);
32
+ let html = template(data);
33
+ // Inject window.__CONFIGURATION__ from environment variable
34
+ const configJson = process.env.NOEGO_CONFIGURATION;
35
+ 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>`);
40
+ }
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;
48
+ }
49
+ }
50
+ // Transform module script tags to automatically call default exports
51
+ // Match: <script type="module" src="/path/to/module.ts"></script>
52
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
53
+ // Convert to inline script that imports and calls default export
54
+ // Wait for DOMContentLoaded and configuration to be available
55
+ return `<script type="module">
56
+ import initApp from '${src}';
57
+ function initializeApp() {
58
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
59
+ const result = initApp();
60
+ if (result instanceof Promise) {
61
+ result.catch(err => console.error('Failed to initialize app:', err));
62
+ }
63
+ } else {
64
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
65
+ }
66
+ }
67
+ // Wait for DOM to be ready
68
+ if (document.readyState === 'loading') {
69
+ document.addEventListener('DOMContentLoaded', initializeApp);
70
+ } else {
71
+ // DOM already loaded
72
+ initializeApp();
73
+ }
74
+ </script>`;
75
+ });
76
+ return html;
33
77
  }
34
78
  }
35
79
  export class DefaultHTMLRender extends BaseHTMLRender {
@@ -43,7 +87,51 @@ export class LiveHTMLRender {
43
87
  }
44
88
  async renderHTML(data) {
45
89
  const template = Handlebars.compile(await this.getTemplate());
46
- return template(data);
90
+ let html = template(data);
91
+ // Inject window.__CONFIGURATION__ from environment variable
92
+ const configJson = process.env.NOEGO_CONFIGURATION;
93
+ 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}`);
102
+ }
103
+ else {
104
+ // Fallback: inject at the beginning
105
+ html = configScript + '\n' + html;
106
+ }
107
+ }
108
+ // Transform module script tags to automatically call default exports
109
+ // Match: <script type="module" src="/path/to/module.ts"></script>
110
+ html = html.replace(/<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi, (match, src) => {
111
+ // Convert to inline script that imports and calls default export
112
+ // Wait for DOMContentLoaded and configuration to be available
113
+ return `<script type="module">
114
+ import initApp from '${src}';
115
+ function initializeApp() {
116
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
117
+ const result = initApp();
118
+ if (result instanceof Promise) {
119
+ result.catch(err => console.error('Failed to initialize app:', err));
120
+ }
121
+ } else {
122
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
123
+ }
124
+ }
125
+ // Wait for DOM to be ready
126
+ if (document.readyState === 'loading') {
127
+ document.addEventListener('DOMContentLoaded', initializeApp);
128
+ } else {
129
+ // DOM already loaded
130
+ initializeApp();
131
+ }
132
+ </script>`;
133
+ });
134
+ return html;
47
135
  }
48
136
  async getTemplate() {
49
137
  const file_content = await fs.readFile(this.html_path, 'utf8');
@@ -1 +1 @@
1
- {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,MAAM,aAAa,CAAA;AAE5B,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;CAmBxB,CAAA;AAUD,MAAM,OAAO,cAAc;IACvB,YAAoB,WAAkB,gBAAgB;QAAlC,aAAQ,GAAR,QAAQ,CAA0B;IAEtD,CAAC;IACH,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAEC,KAAK,CAAC,UAAU,CAAC,IAAQ;QACrB,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QAC7D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;CACJ;AAED,MAAM,OAAO,iBAAkB,SAAQ,cAAc;IACjD;QACI,KAAK,EAAE,CAAA;IACX,CAAC;CACJ;AAID,MAAM,OAAO,cAAc;IACzB,YAAoB,SAAgB;QAAhB,cAAS,GAAT,SAAS,CAAO;IACpC,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAS;QACxB,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QAC7D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAA;IACvB,CAAC;IACD,KAAK,CAAC,WAAW;QACf,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC9D,OAAO,YAAY,CAAA;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"html_render.js","sourceRoot":"","sources":["../../../../src/routing/html_render/html_render.ts"],"names":[],"mappings":"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"}
@@ -169,7 +169,46 @@ class BaseHTMLRender {
169
169
  }
170
170
  async renderHTML(data) {
171
171
  const template = Handlebars.compile(await this.getTemplate());
172
- return template(data);
172
+ let html = template(data);
173
+ const configJson = process.env.NOEGO_CONFIGURATION;
174
+ if (configJson) {
175
+ const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
176
+ if (html.includes("</head>")) {
177
+ html = html.replace("</head>", `${configScript}
178
+ </head>`);
179
+ } else if (html.includes("<body")) {
180
+ html = html.replace(/(<body[^>]*>)/, `$1
181
+ ${configScript}`);
182
+ } else {
183
+ html = configScript + "\n" + html;
184
+ }
185
+ }
186
+ html = html.replace(
187
+ /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
188
+ (match, src) => {
189
+ return `<script type="module">
190
+ import initApp from '${src}';
191
+ function initializeApp() {
192
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
193
+ const result = initApp();
194
+ if (result instanceof Promise) {
195
+ result.catch(err => console.error('Failed to initialize app:', err));
196
+ }
197
+ } else {
198
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
199
+ }
200
+ }
201
+ // Wait for DOM to be ready
202
+ if (document.readyState === 'loading') {
203
+ document.addEventListener('DOMContentLoaded', initializeApp);
204
+ } else {
205
+ // DOM already loaded
206
+ initializeApp();
207
+ }
208
+ <\/script>`;
209
+ }
210
+ );
211
+ return html;
173
212
  }
174
213
  }
175
214
  class DefaultHTMLRender extends BaseHTMLRender {
@@ -183,7 +222,46 @@ class LiveHTMLRender {
183
222
  }
184
223
  async renderHTML(data) {
185
224
  const template = Handlebars.compile(await this.getTemplate());
186
- return template(data);
225
+ let html = template(data);
226
+ const configJson = process.env.NOEGO_CONFIGURATION;
227
+ if (configJson) {
228
+ const configScript = `<script>window.__CONFIGURATION__ = ${configJson};<\/script>`;
229
+ if (html.includes("</head>")) {
230
+ html = html.replace("</head>", `${configScript}
231
+ </head>`);
232
+ } else if (html.includes("<body")) {
233
+ html = html.replace(/(<body[^>]*>)/, `$1
234
+ ${configScript}`);
235
+ } else {
236
+ html = configScript + "\n" + html;
237
+ }
238
+ }
239
+ html = html.replace(
240
+ /<script\s+type=["']module["']\s+src=["']([^"']+)["'][^>]*><\/script>/gi,
241
+ (match, src) => {
242
+ return `<script type="module">
243
+ import initApp from '${src}';
244
+ function initializeApp() {
245
+ if (typeof initApp === 'function' && typeof window !== 'undefined' && window.__CONFIGURATION__) {
246
+ const result = initApp();
247
+ if (result instanceof Promise) {
248
+ result.catch(err => console.error('Failed to initialize app:', err));
249
+ }
250
+ } else {
251
+ console.warn('App initialization skipped: initApp or window.__CONFIGURATION__ not available');
252
+ }
253
+ }
254
+ // Wait for DOM to be ready
255
+ if (document.readyState === 'loading') {
256
+ document.addEventListener('DOMContentLoaded', initializeApp);
257
+ } else {
258
+ // DOM already loaded
259
+ initializeApp();
260
+ }
261
+ <\/script>`;
262
+ }
263
+ );
264
+ return html;
187
265
  }
188
266
  async getTemplate() {
189
267
  const file_content = await fs$1.readFile(this.html_path, "utf8");
@@ -371,7 +449,16 @@ class ManifestBuilder {
371
449
  }
372
450
  }
373
451
  async function requires_server(route, loader) {
374
- return await layout_requires_server(route, loader) || await view_requires_server(route, loader);
452
+ const has_middleware = route.middleware && route.middleware.length > 0;
453
+ const has_loaders = await layout_requires_server(route, loader) || await view_requires_server(route, loader);
454
+ const requires_server2 = has_middleware || has_loaders;
455
+ console.log("[MANIFEST]", route.path, {
456
+ has_middleware,
457
+ middleware: route.middleware,
458
+ has_loaders,
459
+ requires_server: requires_server2
460
+ });
461
+ return requires_server2;
375
462
  }
376
463
  async function layout_requires_server(route, loader) {
377
464
  const layout = route.layout;
@@ -945,8 +1032,18 @@ class ExpressServerAdapter extends ServerAdapter {
945
1032
  body: req.body,
946
1033
  context
947
1034
  };
1035
+ console.log("[SERVER] Handling request", req.url, {
1036
+ middleware: route.middleware,
1037
+ accept: req.headers.accept,
1038
+ route_path: route.path,
1039
+ server_api_call
1040
+ });
948
1041
  try {
949
1042
  await this.middleware_adapter.handleMiddleware(req, res, route.middleware || []);
1043
+ console.log("[SERVER] Middleware complete", {
1044
+ headersSent: res.headersSent,
1045
+ statusCode: res.statusCode
1046
+ });
950
1047
  } catch (e) {
951
1048
  console.log("Error in middleware", e);
952
1049
  res.status(500).send(`
@@ -957,6 +1054,10 @@ ${e.stack}</pre>
957
1054
  `);
958
1055
  return;
959
1056
  }
1057
+ if (res.headersSent) {
1058
+ console.log("[SERVER] Headers already sent by middleware, returning early");
1059
+ return;
1060
+ }
960
1061
  let server_data = await this.api_adapter.getApiData(route, request_data);
961
1062
  if (server_api_call) {
962
1063
  res.header("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate").header("Pragma", "no-cache").header("Expires", "0").type("application/json").send(server_data);
@@ -1013,6 +1114,7 @@ ${e.stack}</pre>
1013
1114
 
1014
1115
  <script type='text/javascript'>
1015
1116
  window.__MANIFEST__ = ${JSON.stringify(manifest)}
1117
+ console.log('[MANIFEST INJECTED]', window.__MANIFEST__);
1016
1118
  <\/script>
1017
1119
 
1018
1120
  <script type='text/javascript'>