@bananacool467/authtics-host 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -12
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +92 -47
- package/dist/devPanel.d.ts +0 -1
- package/dist/devPanel.js +67 -33
- package/dist/renderEngine.d.ts +1 -1
- package/dist/renderEngine.js +91 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
# Authtics Host
|
|
2
2
|
|
|
3
|
-
Version 0.1.
|
|
3
|
+
Version 0.1.8
|
|
4
4
|
License: MIT
|
|
5
5
|
|
|
6
6
|
Authtics Host is a framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild.
|
|
7
7
|
|
|
8
8
|
**(NOTE: The short name for Authtics Host is HostJS or Host.js)**
|
|
9
9
|
|
|
10
|
+
**(Fixes we're applied on this version with security fixes too)**
|
|
11
|
+
**(From the Developer: I am having 2 small issues:**
|
|
12
|
+
1. **Web Socket Connections** are **not showing** in the DevPanel's Network tab
|
|
13
|
+
2. The page doesnt **refresh properly**. (Have to refresh by doing: refresh -> cancel -> refresh to prevent halting)
|
|
14
|
+
**I need help fixing those)**
|
|
15
|
+
|
|
10
16
|
## Setting Up
|
|
11
17
|
|
|
12
18
|
To get **Authtics Host** use:
|
|
@@ -151,13 +157,13 @@ Then when you run your project, you will get a page just saying **"Hello, World!
|
|
|
151
157
|
|
|
152
158
|
The Developer Panel is what you could use to help you debug your code. The Developer Panel has **7 tabs**:
|
|
153
159
|
|
|
154
|
-
**Console** — Shows current logs.
|
|
155
|
-
**Route** — Shows information about the current route.
|
|
156
|
-
**Webpage Info** — Shows information about the website/webpage.
|
|
157
|
-
**Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching.
|
|
158
|
-
**Client Info** — Shows information about your client's User Agent, OS **(Operating System)** and FPS **(Frames Per Second)**.
|
|
159
|
-
**About Host** — Shows the current version of *Authtics Host*.
|
|
160
|
-
**Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up.
|
|
160
|
+
* **Console** — Shows current logs.
|
|
161
|
+
* **Route** — Shows information about the current route.
|
|
162
|
+
* **Webpage Info** — Shows information about the website/webpage.
|
|
163
|
+
* **Network** — Shows the current ping and shows sent fetches from the client and shows received from the server after fetching.
|
|
164
|
+
* **Client Info** — Shows information about your client's User Agent, OS **(Operating System)** and FPS **(Frames Per Second)**.
|
|
165
|
+
* **About Host** — Shows the current version of *Authtics Host*.
|
|
166
|
+
* **Server Info** — Shows how much heap was used and how much CPU was used on the server and how much requests there were and how much users are currently on the site and how long the site has been up.
|
|
161
167
|
|
|
162
168
|
The information the Developer Panel shows outside of the tabs is just your **DAT** (Developer Access Token).
|
|
163
169
|
|
|
@@ -165,9 +171,9 @@ The information the Developer Panel shows outside of the tabs is just your **DAT
|
|
|
165
171
|
|
|
166
172
|
The Developer Panel also have remote buttons:
|
|
167
173
|
|
|
168
|
-
**Restart App** — Restarts the website.
|
|
169
|
-
**Shut Down App** — Stops the website.
|
|
170
|
-
**Pause Users**/**Resume Users** — Stops users from reaching a site and they will get a JSON error message like this when visiting if Pause Users is on:
|
|
174
|
+
* **Restart App** — Restarts the website.
|
|
175
|
+
* **Shut Down App** — Stops the website.
|
|
176
|
+
* **Pause Users**/**Resume Users** — Stops users from reaching a site and they will get a JSON error message like this when visiting if Pause Users is on:
|
|
171
177
|
```json
|
|
172
178
|
{ "message": "unhandled request" }
|
|
173
179
|
```
|
|
@@ -181,6 +187,51 @@ and then create a file like `paused.tsx` and then inside `App.tsx`, import `Paus
|
|
|
181
187
|
```
|
|
182
188
|
and if your using `autoPaging` then you just create a file named `_paused.tsx`.
|
|
183
189
|
|
|
190
|
+
## App APIs
|
|
191
|
+
|
|
192
|
+
You can add APIs like `get`, `post`, `del` and `put`.
|
|
193
|
+
|
|
194
|
+
You can use the get API, for example:
|
|
195
|
+
```typescript
|
|
196
|
+
app.get('/hi', (req, res) => {
|
|
197
|
+
res.text("Hello!");
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
Then when you go to `/hi` you see:
|
|
201
|
+
```
|
|
202
|
+
Hello!
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Notes about Authtics Host
|
|
206
|
+
|
|
207
|
+
Since Authtics Host is SSR, stuff like NPM packages that uses **Browser APIs** (e.g., `window`, `document`) will cause errors.
|
|
208
|
+
The developer (The one that is writing this README) may add a feature where Authtics Host converts:
|
|
209
|
+
```tsx
|
|
210
|
+
export function Component() {
|
|
211
|
+
return (
|
|
212
|
+
<p>{window.__status_code__}</p>
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
To:
|
|
217
|
+
```tsx
|
|
218
|
+
import { useState, useEffect } from 'react';
|
|
219
|
+
export function Component() {
|
|
220
|
+
const [__window, __set_window] = useState<any>(null);
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
if (window) __set_window(window);
|
|
223
|
+
}, []);
|
|
224
|
+
return (
|
|
225
|
+
<p>{__window.__status_code__}</p>
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The developer might also redesign the UI for the DevPanel using [UI Tools](https://npmjs.com/package/@bananakitssu/ui-tools).
|
|
231
|
+
|
|
232
|
+
> **Warning**:
|
|
233
|
+
> Asking AI about HostJS is not recommended, it will give an Auth platform and call HostJS/Authtics Host a typo, say it doesn't exist, say it was renamed, it is private, or the account doesn't exist. Or if it knows, it may swap your server script with regular **Node.js**/**ExpressJS**/**Next.js** or use **Next.js**-like code because this framework is **Next.js-inspired**
|
|
234
|
+
|
|
184
235
|
## Developer Panel Notes And DAT (Developer Access Token)
|
|
185
236
|
|
|
186
237
|
A DAT (Developer Access Token) is your token that is used to access the Developer Panel.
|
|
@@ -207,4 +258,4 @@ There isn't any limit of DATs you can add.
|
|
|
207
258
|
|
|
208
259
|
## Contacting The Developer Of Authtics Host
|
|
209
260
|
|
|
210
|
-
If you
|
|
261
|
+
If you have any questions, or encountered a bug while using HostJS, contact: authtics@proton.me
|
package/dist/cli.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export default class App {
|
|
|
8
8
|
post(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
9
9
|
put(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
10
10
|
delete(routePath: string, handler: (req: IncomingMessage, res: ServerResponse) => void): void;
|
|
11
|
+
remove(method: string, routePath: string): void;
|
|
11
12
|
}
|
package/dist/cli.js
CHANGED
|
@@ -15,16 +15,67 @@ const routes = new Map();
|
|
|
15
15
|
const __filename = url.fileURLToPath(import.meta.url);
|
|
16
16
|
const __dirname = path.dirname(__filename);
|
|
17
17
|
const hmrClients = new Set();
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
function safeWatch(target, onChange) {
|
|
19
|
+
const shouldReact = (filename) => {
|
|
20
|
+
if (!filename)
|
|
21
|
+
return false;
|
|
22
|
+
if (filename.includes('.authtics_host'))
|
|
23
|
+
return false;
|
|
24
|
+
if (filename.includes('node_modules'))
|
|
25
|
+
return false;
|
|
26
|
+
return /\.(tsx?|jsx?|html|css)$/i.test(filename);
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const stat = fs.statSync(target);
|
|
30
|
+
if (stat.isFile()) {
|
|
31
|
+
fs.watch(target, (_et, filename) => { if (shouldReact(filename ?? target))
|
|
32
|
+
onChange(); });
|
|
33
|
+
return;
|
|
22
34
|
}
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
fs.watch(target, { recursive: true }, (_et, filename) => {
|
|
36
|
+
if (shouldReact(filename))
|
|
37
|
+
onChange();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err.code === 'ERR_FEATURE_UNAVAILABLE_ON_PLATFORM' || err.code === 'EINVAL' || err.code === 'ENOSYS') {
|
|
42
|
+
try {
|
|
43
|
+
fs.watch(target, (_et, f) => { if (shouldReact(f))
|
|
44
|
+
onChange(); });
|
|
45
|
+
}
|
|
46
|
+
catch { }
|
|
47
|
+
try {
|
|
48
|
+
for (const entry of fs.readdirSync(target, { withFileTypes: true })) {
|
|
49
|
+
if (entry.isDirectory()) {
|
|
50
|
+
try {
|
|
51
|
+
const sub = path.join(target, entry.name);
|
|
52
|
+
fs.watch(sub, (_et, f) => { if (shouldReact(f))
|
|
53
|
+
onChange(); });
|
|
54
|
+
}
|
|
55
|
+
catch { }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch { }
|
|
25
60
|
}
|
|
26
61
|
}
|
|
27
62
|
}
|
|
63
|
+
let hmrDebounceTimer = null;
|
|
64
|
+
function notifyHmrClients() {
|
|
65
|
+
if (hmrDebounceTimer)
|
|
66
|
+
clearTimeout(hmrDebounceTimer);
|
|
67
|
+
hmrDebounceTimer = setTimeout(() => {
|
|
68
|
+
hmrDebounceTimer = null;
|
|
69
|
+
for (const client of hmrClients) {
|
|
70
|
+
try {
|
|
71
|
+
client.write('data: reload\n\n');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
hmrClients.delete(client);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, 120);
|
|
78
|
+
}
|
|
28
79
|
const MIME_TYPES = {
|
|
29
80
|
'.html': 'text/html',
|
|
30
81
|
'.css': 'text/css',
|
|
@@ -343,6 +394,10 @@ export default class App {
|
|
|
343
394
|
delete(routePath, handler) {
|
|
344
395
|
routes.set(`DELETE:${routePath}`, handler);
|
|
345
396
|
}
|
|
397
|
+
remove(method, routePath) {
|
|
398
|
+
if (routes.has(`${method}:${routePath}`))
|
|
399
|
+
routes.delete(`${method}:${routePath}`);
|
|
400
|
+
}
|
|
346
401
|
}
|
|
347
402
|
async function start() {
|
|
348
403
|
let config = {};
|
|
@@ -483,7 +538,7 @@ async function start() {
|
|
|
483
538
|
pathname = safePath;
|
|
484
539
|
if (pathname !== "/" && pathname.endsWith("/"))
|
|
485
540
|
pathname = pathname.slice(0, -1);
|
|
486
|
-
if (!pathname.includes('/__authtics')) {
|
|
541
|
+
if (!pathname.includes('/__authtics') && !pathname.includes('/hmr')) {
|
|
487
542
|
totalRequests++;
|
|
488
543
|
}
|
|
489
544
|
const routeKey = `${method}:${pathname}`;
|
|
@@ -498,7 +553,7 @@ async function start() {
|
|
|
498
553
|
res.setHeader("Content-Type", "application/javascript");
|
|
499
554
|
res.end(f);
|
|
500
555
|
});
|
|
501
|
-
}, req.cookies.dat, config_.dat);
|
|
556
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
502
557
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
503
558
|
res.setHeader("Content-Type", "text/html");
|
|
504
559
|
return res.end(html);
|
|
@@ -521,7 +576,7 @@ async function start() {
|
|
|
521
576
|
res.setHeader("Content-Type", "application/javascript");
|
|
522
577
|
res.end(f);
|
|
523
578
|
});
|
|
524
|
-
}, req.cookies.dat, config_.dat);
|
|
579
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
525
580
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
526
581
|
res.setHeader("Content-Type", "text/html");
|
|
527
582
|
return res.end(html);
|
|
@@ -551,7 +606,7 @@ async function start() {
|
|
|
551
606
|
res.setHeader("Content-Type", "application/javascript");
|
|
552
607
|
res.end(f);
|
|
553
608
|
});
|
|
554
|
-
}, req.cookies.dat, config_.dat);
|
|
609
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
555
610
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
556
611
|
res.setHeader("Content-Type", "text/html");
|
|
557
612
|
return res.end(html);
|
|
@@ -574,7 +629,7 @@ async function start() {
|
|
|
574
629
|
res.setHeader("Content-Type", "application/javascript");
|
|
575
630
|
res.end(f);
|
|
576
631
|
});
|
|
577
|
-
}, req.cookies.dat, config_.dat);
|
|
632
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
578
633
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
579
634
|
res.setHeader("Content-Type", "text/html");
|
|
580
635
|
return res.end(html);
|
|
@@ -602,7 +657,7 @@ async function start() {
|
|
|
602
657
|
return handler(req, res);
|
|
603
658
|
}
|
|
604
659
|
}
|
|
605
|
-
if (pathname === '/
|
|
660
|
+
if (pathname === '/hmr') {
|
|
606
661
|
res.writeHead(200, {
|
|
607
662
|
'Content-Type': 'text/event-stream',
|
|
608
663
|
'Cache-Control': 'no-cache',
|
|
@@ -625,7 +680,7 @@ async function start() {
|
|
|
625
680
|
res.setHeader("Content-Type", "application/javascript");
|
|
626
681
|
res.end(f);
|
|
627
682
|
});
|
|
628
|
-
}, req.cookies.dat, config_.dat);
|
|
683
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
629
684
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
630
685
|
res.setHeader("Content-Type", "text/html");
|
|
631
686
|
return res.end(html);
|
|
@@ -648,7 +703,7 @@ async function start() {
|
|
|
648
703
|
res.setHeader("Content-Type", "application/javascript");
|
|
649
704
|
res.end(f);
|
|
650
705
|
});
|
|
651
|
-
}, req.cookies.dat, config_.dat);
|
|
706
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
652
707
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
653
708
|
res.setHeader("Content-Type", "text/html");
|
|
654
709
|
return res.end(html);
|
|
@@ -678,7 +733,7 @@ async function start() {
|
|
|
678
733
|
res.setHeader("Content-Type", "application/javascript");
|
|
679
734
|
res.end(f);
|
|
680
735
|
});
|
|
681
|
-
}, req.cookies.dat, config_.dat);
|
|
736
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
682
737
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
683
738
|
res.setHeader("Content-Type", "text/html");
|
|
684
739
|
return res.end(html);
|
|
@@ -701,7 +756,7 @@ async function start() {
|
|
|
701
756
|
res.setHeader("Content-Type", "application/javascript");
|
|
702
757
|
res.end(f);
|
|
703
758
|
});
|
|
704
|
-
}, req.cookies.dat, config_.dat);
|
|
759
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
705
760
|
html = html.replace("<script>", "<script>\nwindow.__paused__ = true;");
|
|
706
761
|
res.setHeader("Content-Type", "text/html");
|
|
707
762
|
return res.end(html);
|
|
@@ -759,7 +814,7 @@ async function start() {
|
|
|
759
814
|
res.setHeader("Content-Type", "application/javascript");
|
|
760
815
|
res.end(f);
|
|
761
816
|
});
|
|
762
|
-
}, req.cookies.dat, config_.dat);
|
|
817
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
763
818
|
res.setHeader("Content-Type", "text/html");
|
|
764
819
|
res.writeHead(404);
|
|
765
820
|
html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
|
|
@@ -785,7 +840,7 @@ async function start() {
|
|
|
785
840
|
res.setHeader("Content-Type", "application/javascript");
|
|
786
841
|
res.end(f);
|
|
787
842
|
});
|
|
788
|
-
}, req.cookies.dat, config_.dat);
|
|
843
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
789
844
|
res.setHeader("Content-Type", "text/html");
|
|
790
845
|
return res.end(html);
|
|
791
846
|
}
|
|
@@ -809,7 +864,7 @@ async function start() {
|
|
|
809
864
|
res.setHeader("Content-Type", "application/javascript");
|
|
810
865
|
res.end(f);
|
|
811
866
|
});
|
|
812
|
-
}, req.cookies.dat, config_.dat);
|
|
867
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
813
868
|
res.setHeader("Content-Type", "text/html");
|
|
814
869
|
return res.end(html);
|
|
815
870
|
}
|
|
@@ -828,7 +883,7 @@ async function start() {
|
|
|
828
883
|
res.setHeader("Content-Type", "application/javascript");
|
|
829
884
|
res.end(f);
|
|
830
885
|
});
|
|
831
|
-
}, req.cookies.dat, config_.dat);
|
|
886
|
+
}, (p) => { routes.delete(`GET:${p}`); }, req.cookies.dat, config_.dat);
|
|
832
887
|
res.setHeader("Content-Type", "text/html");
|
|
833
888
|
res.writeHead(404);
|
|
834
889
|
html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
|
|
@@ -850,34 +905,24 @@ async function start() {
|
|
|
850
905
|
}, 1000);
|
|
851
906
|
});
|
|
852
907
|
if (config.hotReload === true) {
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
fs.watch(dir, { recursive: true }, (eventType, filename) => {
|
|
863
|
-
if (!filename)
|
|
864
|
-
return;
|
|
865
|
-
notifyHmrClients();
|
|
866
|
-
});
|
|
867
|
-
}
|
|
908
|
+
const watchSet = new Set();
|
|
909
|
+
watchSet.add(process.cwd());
|
|
910
|
+
if (pagesDir && fs.existsSync(pagesDir))
|
|
911
|
+
watchSet.add(pagesDir);
|
|
912
|
+
const appTsx = routes.get("APP_TSX");
|
|
913
|
+
if (appTsx) {
|
|
914
|
+
const appTsxDir = path.dirname(path.join(process.cwd(), appTsx));
|
|
915
|
+
if (fs.existsSync(appTsxDir))
|
|
916
|
+
watchSet.add(appTsxDir);
|
|
868
917
|
}
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
return;
|
|
878
|
-
notifyHmrClients();
|
|
879
|
-
});
|
|
880
|
-
}
|
|
918
|
+
const devPanelBuilt = path.join(__dirname, 'devPanel.js');
|
|
919
|
+
const _404Built = path.join(__dirname, '404.js');
|
|
920
|
+
if (fs.existsSync(devPanelBuilt))
|
|
921
|
+
watchSet.add(devPanelBuilt);
|
|
922
|
+
if (fs.existsSync(_404Built))
|
|
923
|
+
watchSet.add(_404Built);
|
|
924
|
+
for (const dir of watchSet) {
|
|
925
|
+
safeWatch(dir, notifyHmrClients);
|
|
881
926
|
}
|
|
882
927
|
}
|
|
883
928
|
return server;
|
package/dist/devPanel.d.ts
CHANGED
package/dist/devPanel.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect, useRef } from 'react';
|
|
3
3
|
import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info, ArrowLeft, Wifi, Terminal, Route, Globe, ChevronRight, ChevronLeft, Server, TriangleAlert, Eye, Zap } from 'lucide-react';
|
|
4
|
-
import Prism from 'prismjs';
|
|
5
|
-
import 'prismjs/components/prism-javascript';
|
|
6
|
-
Prism.languages.javascript['builtin'] = /\b(window|document|console|navigator|localStorage|sessionStorage|fetch|Promise|setTimeout|setInterval|clearTimeout|clearInterval|requestAnimationFrame|Math|JSON|Object|Array|String|Number|Boolean|Date|RegExp|Error|Map|Set|Symbol|Proxy|Reflect|performance|history|location|screen|crypto|indexedDB|alert|confirm|prompt)\b/;
|
|
7
4
|
function getCallerSource() {
|
|
8
5
|
try {
|
|
9
6
|
const stack = new Error().stack ?? '';
|
|
@@ -63,7 +60,7 @@ function Sparkline({ data, color, label, unit }) {
|
|
|
63
60
|
return _jsx("circle", { cx: last[0], cy: last[1], r: "2.5", fill: color });
|
|
64
61
|
})()] }))] })] }));
|
|
65
62
|
}
|
|
66
|
-
function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSource, onWebSocket, setWebSocket, onResource, setResource, onBytesClient, onBytesServer) {
|
|
63
|
+
function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSource, onWebSocket, setWebSocket, onResource, setResource, rmvResource, onBytesClient, onBytesServer) {
|
|
67
64
|
if (window.__authtics_network_intercepted__)
|
|
68
65
|
return;
|
|
69
66
|
window.__authtics_network_intercepted__ = true;
|
|
@@ -87,7 +84,7 @@ function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSou
|
|
|
87
84
|
try {
|
|
88
85
|
const resp = await originalFetch(...args);
|
|
89
86
|
const clone = resp.clone();
|
|
90
|
-
setFetch({ url, method, status:
|
|
87
|
+
setFetch({ url, method, status: clone.status, id: savedFetchId, response: await clone.text(), sent: body ? JSON.stringify(body, null, 2).replace('"{', '{')
|
|
91
88
|
.replace('}"', '}')
|
|
92
89
|
.replaceAll('\\"', '"') : null });
|
|
93
90
|
clone.arrayBuffer().then(buf => {
|
|
@@ -221,23 +218,60 @@ function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSou
|
|
|
221
218
|
};
|
|
222
219
|
window.EventSource.prototype = OriginalEventSource.prototype;
|
|
223
220
|
Object.assign(window.EventSource, OriginalEventSource);
|
|
224
|
-
|
|
221
|
+
let usedResourcesSlots = [];
|
|
222
|
+
let beforeResources = [];
|
|
223
|
+
let currentResources = [];
|
|
224
|
+
setInterval(() => {
|
|
225
|
+
beforeResources = currentResources;
|
|
226
|
+
currentResources = [];
|
|
225
227
|
const queryImg = document.querySelectorAll('img');
|
|
226
228
|
const queryScript = document.querySelectorAll('script');
|
|
227
229
|
const queryLink = document.querySelectorAll('link');
|
|
228
230
|
queryImg.forEach((img) => {
|
|
229
|
-
if (img.src)
|
|
230
|
-
|
|
231
|
+
if (img.src) {
|
|
232
|
+
fetchId++;
|
|
233
|
+
let savedFetchId = fetchId;
|
|
234
|
+
if (!usedResourcesSlots.includes({ url: img.src, type: 'img', id: savedFetchId }))
|
|
235
|
+
onResource({ url: img.src, type: 'img', id: savedFetchId });
|
|
236
|
+
currentResources.push({ url: img.src, type: 'img', id: savedFetchId });
|
|
237
|
+
if (usedResourcesSlots.includes({ url: img.src, type: 'img', id: savedFetchId }))
|
|
238
|
+
setResource({ url: img.src, type: 'img', id: savedFetchId });
|
|
239
|
+
if (!usedResourcesSlots.includes({ url: img.src, type: 'img', id: savedFetchId }))
|
|
240
|
+
usedResourcesSlots.push({ url: img.src, type: 'img', id: savedFetchId });
|
|
241
|
+
}
|
|
231
242
|
});
|
|
232
243
|
queryScript.forEach((script) => {
|
|
233
|
-
if (script.src)
|
|
234
|
-
|
|
244
|
+
if (script.src) {
|
|
245
|
+
fetchId++;
|
|
246
|
+
let savedFetchId = fetchId;
|
|
247
|
+
if (!usedResourcesSlots.includes({ url: script.src, type: 'script', id: savedFetchId }))
|
|
248
|
+
onResource({ url: script.src, type: 'script', id: savedFetchId });
|
|
249
|
+
currentResources.push({ url: script.src, type: 'script', id: savedFetchId });
|
|
250
|
+
if (usedResourcesSlots.includes({ url: script.src, type: 'script', id: savedFetchId }))
|
|
251
|
+
setResource({ url: script.src, type: 'script', id: savedFetchId });
|
|
252
|
+
if (!usedResourcesSlots.includes({ url: script.src, type: 'script', id: savedFetchId }))
|
|
253
|
+
usedResourcesSlots.push({ url: script.src, type: 'script', id: savedFetchId });
|
|
254
|
+
}
|
|
235
255
|
});
|
|
236
256
|
queryLink.forEach((link) => {
|
|
237
|
-
if (link.href)
|
|
238
|
-
|
|
257
|
+
if (link.href) {
|
|
258
|
+
fetchId++;
|
|
259
|
+
let savedFetchId = fetchId;
|
|
260
|
+
if (!usedResourcesSlots.includes({ url: link.href, type: 'link', id: savedFetchId }))
|
|
261
|
+
onResource({ url: link.href, type: 'link', id: savedFetchId });
|
|
262
|
+
currentResources.push({ url: link.href, type: 'link', id: savedFetchId });
|
|
263
|
+
if (usedResourcesSlots.includes({ url: link.href, type: 'link', id: savedFetchId }))
|
|
264
|
+
setResource({ url: link.href, type: 'link', id: savedFetchId });
|
|
265
|
+
if (!usedResourcesSlots.includes({ url: link.href, type: 'link', id: savedFetchId }))
|
|
266
|
+
usedResourcesSlots.push({ url: link.href, type: 'link', id: savedFetchId });
|
|
267
|
+
}
|
|
239
268
|
});
|
|
240
|
-
|
|
269
|
+
beforeResources.forEach((resource) => {
|
|
270
|
+
if (!currentResources.includes(resource)) {
|
|
271
|
+
rmvResource(resource);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}, 250);
|
|
241
275
|
}
|
|
242
276
|
function installConsoleInterceptor() {
|
|
243
277
|
if (window.__authtics_intercepted__)
|
|
@@ -260,7 +294,7 @@ function installConsoleInterceptor() {
|
|
|
260
294
|
});
|
|
261
295
|
}
|
|
262
296
|
function SecuredTab() {
|
|
263
|
-
return (_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', padding: '
|
|
297
|
+
return (_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', padding: '10px 10px', textAlign: 'center', gap: '8px' }, children: [_jsx(CircleX, { size: 32, color: 'red' }), _jsx("span", { style: { color: 'red', fontSize: 24 }, children: "This Tab Is Currently Not Accessible" }), _jsx("span", { style: { color: 'red', fontSize: 12 }, children: "To access this tab, you need to set \"dat\" in the Authtics Host config to set restriction and then restart." })] }));
|
|
264
298
|
}
|
|
265
299
|
function PanelButton({ onClick, onClick2, children, style, fullWidth, disabled }) {
|
|
266
300
|
const [hovered, setHovered] = useState(false);
|
|
@@ -309,7 +343,6 @@ export default function DevPanel() {
|
|
|
309
343
|
const [ping__, setPing__] = useState(0);
|
|
310
344
|
const [networkFetches, setNetworkFetches] = useState([]);
|
|
311
345
|
const [eventSources, setEventSources] = useState([]);
|
|
312
|
-
const [usersPaused, setUsersPaused] = useState(false);
|
|
313
346
|
const [usersPausedRealInfo, setUsersPausedRealInfo] = useState(false);
|
|
314
347
|
const [webSockets, setWebSockets] = useState([]);
|
|
315
348
|
const [resourcesFound, setResourcesFound] = useState([]);
|
|
@@ -324,7 +357,6 @@ export default function DevPanel() {
|
|
|
324
357
|
const heapUsage = useRef(0);
|
|
325
358
|
const [datMatch, setDatMatch] = useState(false);
|
|
326
359
|
const [compilerType, setCompilerType] = useState("?");
|
|
327
|
-
const [errorDetail, setErrorDetail] = useState(undefined);
|
|
328
360
|
const [httpVersion, setHttpVersion] = useState("v?.?");
|
|
329
361
|
const [errorBoxOpenable, setErrorBoxOpenable] = useState(false);
|
|
330
362
|
const [uptime, setUptime] = useState("00:00:00:00");
|
|
@@ -400,7 +432,6 @@ export default function DevPanel() {
|
|
|
400
432
|
if (resp3.status === 200) {
|
|
401
433
|
const data = await resp3.json();
|
|
402
434
|
paused = data.paused;
|
|
403
|
-
setUsersPaused(paused);
|
|
404
435
|
setUsersPausedRealInfo(data.realInfo);
|
|
405
436
|
}
|
|
406
437
|
if (!data.isMatching && !paused) {
|
|
@@ -603,7 +634,7 @@ export default function DevPanel() {
|
|
|
603
634
|
}, []);
|
|
604
635
|
useEffect(() => {
|
|
605
636
|
installConsoleInterceptor();
|
|
606
|
-
installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setEventSources(prev => [...prev.slice(-49), f]), (f) => setEventSources(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setWebSockets(prev => [...prev.slice(-49), f]), (f) => setWebSockets(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setResourcesFound(prev => [...prev.slice(-49), f]), (f) => setResourcesFound(prev => prev.map(p => p.id === f.id ? f : p)), (sent) => {
|
|
637
|
+
installNetworkInterceptor((f) => setNetworkFetches(prev => [...prev.slice(-49), f]), (f) => setNetworkFetches(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setEventSources(prev => [...prev.slice(-49), f]), (f) => setEventSources(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setWebSockets(prev => [...prev.slice(-49), f]), (f) => setWebSockets(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setResourcesFound(prev => [...prev.slice(-49), f]), (f) => setResourcesFound(prev => prev.map(p => p.id === f.id ? f : p)), (f) => setResourcesFound(prev => prev.filter(p => p.id !== f.id)), (sent) => {
|
|
607
638
|
pendingSent.current += sent;
|
|
608
639
|
}, (received) => {
|
|
609
640
|
pendingReceived.current += received;
|
|
@@ -615,7 +646,6 @@ export default function DevPanel() {
|
|
|
615
646
|
setHasIssue(true);
|
|
616
647
|
setErrorMsgs(prev => [...prev, detail.message]);
|
|
617
648
|
setErrorBoxOpen(true);
|
|
618
|
-
setErrorDetail(detail.source);
|
|
619
649
|
}
|
|
620
650
|
;
|
|
621
651
|
};
|
|
@@ -629,23 +659,27 @@ export default function DevPanel() {
|
|
|
629
659
|
setTokenLength(length);
|
|
630
660
|
}
|
|
631
661
|
else {
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
|
|
662
|
+
const cfg = window.__authtics_config__;
|
|
663
|
+
const serverDevMode = cfg?.devMode !== false;
|
|
664
|
+
const serverDatRestricted = cfg?.datRestricted === true;
|
|
665
|
+
if (serverDevMode && !serverDatRestricted) {
|
|
666
|
+
const newToken = generateToken();
|
|
635
667
|
try {
|
|
636
|
-
localStorageToken
|
|
668
|
+
let localStorageToken;
|
|
669
|
+
try {
|
|
670
|
+
localStorageToken = localStorage.getItem('dat');
|
|
671
|
+
}
|
|
672
|
+
catch (e) { }
|
|
673
|
+
cookie.set('dat', localStorageToken || newToken);
|
|
674
|
+
setToken(newToken);
|
|
675
|
+
let length_ = newToken?.split('');
|
|
676
|
+
let length;
|
|
677
|
+
length = length_?.length;
|
|
678
|
+
setTokenLength(length);
|
|
637
679
|
}
|
|
638
|
-
catch (
|
|
680
|
+
catch (error) {
|
|
681
|
+
console.error('[Authtics Host] Error storing token in localStorage:', error);
|
|
639
682
|
}
|
|
640
|
-
cookie.set('dat', localStorageToken || newToken);
|
|
641
|
-
setToken(newToken);
|
|
642
|
-
let length_ = newToken?.split('');
|
|
643
|
-
let length;
|
|
644
|
-
length = length_?.length;
|
|
645
|
-
setTokenLength(length);
|
|
646
|
-
}
|
|
647
|
-
catch (error) {
|
|
648
|
-
console.error('[Authtics Host] Error storing token in localStorage:', error);
|
|
649
683
|
}
|
|
650
684
|
}
|
|
651
685
|
}
|
package/dist/renderEngine.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type CompilerType = 'esbuild' | 'babel';
|
|
2
2
|
export declare function findFileUpwards(startDir: string, relativePath: string): string | null;
|
|
3
|
-
export declare function renderPage(tsxPath: string, reqUrl?: string, showPanel?: boolean, compiler?: CompilerType, hotReload?: boolean, autoPaging?: boolean, autoPageDir?: string, appDir?: string, fileHandler?: (f: string, p: string) => void, reqDAT?: string | undefined, configDAT?: string | string[] | undefined): Promise<string>;
|
|
3
|
+
export declare function renderPage(tsxPath: string, reqUrl?: string, showPanel?: boolean, compiler?: CompilerType, hotReload?: boolean, autoPaging?: boolean, autoPageDir?: string, appDir?: string, fileHandler?: (f: string, p: string) => void, rmvFileHandler?: (p: string) => void, reqDAT?: string | undefined, configDAT?: string | string[] | undefined): Promise<string>;
|
package/dist/renderEngine.js
CHANGED
|
@@ -9,6 +9,39 @@ import { renderToString } from "react-dom/server";
|
|
|
9
9
|
import { tempFileForTsx, writeTempFile, readTempFile, ensureTempDirs, } from "./rendererTempFiles.js";
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = path.dirname(__filename);
|
|
12
|
+
const NODE_BUILTINS = [
|
|
13
|
+
'fs', 'path', 'http', 'https', 'net', 'tls', 'os', 'url', 'dns',
|
|
14
|
+
'crypto', 'stream', 'buffer', 'events', 'util', 'zlib', 'assert',
|
|
15
|
+
'child_process', 'cluster', 'dgram', 'readline', 'repl', 'vm',
|
|
16
|
+
'worker_threads', 'timers', 'module', 'process', 'string_decoder',
|
|
17
|
+
'querystring', 'punycode', 'domain', 'constants', 'sys',
|
|
18
|
+
'node:fs', 'node:path', 'node:http', 'node:https', 'node:net', 'node:tls',
|
|
19
|
+
'node:os', 'node:url', 'node:dns', 'node:crypto', 'node:stream',
|
|
20
|
+
'node:buffer', 'node:events', 'node:util', 'node:zlib', 'node:assert',
|
|
21
|
+
'node:child_process', 'node:cluster', 'node:dgram', 'node:readline',
|
|
22
|
+
'node:repl', 'node:vm', 'node:worker_threads', 'node:timers',
|
|
23
|
+
'node:module', 'node:process', 'node:string_decoder', 'node:querystring',
|
|
24
|
+
'express', 'jiti',
|
|
25
|
+
];
|
|
26
|
+
const nodeStubPlugin = {
|
|
27
|
+
name: 'browser-node-stub',
|
|
28
|
+
setup(build) {
|
|
29
|
+
const escapedNames = NODE_BUILTINS.map(n => n.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
30
|
+
const filter = new RegExp(`^(${escapedNames.join('|')})$`);
|
|
31
|
+
build.onResolve({ filter }, args => ({
|
|
32
|
+
path: args.path,
|
|
33
|
+
namespace: 'browser-node-stub',
|
|
34
|
+
}));
|
|
35
|
+
build.onLoad({ filter: /.*/, namespace: 'browser-node-stub' }, () => ({
|
|
36
|
+
contents: `
|
|
37
|
+
// Node.js built-in stub for browser builds
|
|
38
|
+
const stub = new Proxy({}, { get: () => () => undefined });
|
|
39
|
+
export default stub;
|
|
40
|
+
`,
|
|
41
|
+
loader: 'js',
|
|
42
|
+
}));
|
|
43
|
+
},
|
|
44
|
+
};
|
|
12
45
|
async function buildWithBabel(entryPath, virtualContent, platform) {
|
|
13
46
|
const presets = [
|
|
14
47
|
[babelPresetEnv, {
|
|
@@ -26,6 +59,7 @@ async function buildWithBabel(entryPath, virtualContent, platform) {
|
|
|
26
59
|
return result.code;
|
|
27
60
|
}
|
|
28
61
|
async function buildWithEsbuild(virtualContent, resolveDir, platform) {
|
|
62
|
+
const toFwdSlash = (p) => p.split(path.sep).join('/');
|
|
29
63
|
const isNode = platform === 'node';
|
|
30
64
|
const result = await esbuild.build({
|
|
31
65
|
stdin: {
|
|
@@ -38,19 +72,23 @@ async function buildWithEsbuild(virtualContent, resolveDir, platform) {
|
|
|
38
72
|
format: isNode ? 'cjs' : 'iife',
|
|
39
73
|
platform,
|
|
40
74
|
jsx: 'automatic',
|
|
41
|
-
sourcemap: isNode ? false :
|
|
75
|
+
sourcemap: isNode ? false : false,
|
|
42
76
|
target: isNode ? ['node18'] : ['es2020'],
|
|
43
|
-
minify:
|
|
77
|
+
minify: true,
|
|
44
78
|
treeShaking: true,
|
|
79
|
+
plugins: isNode ? [] : [nodeStubPlugin],
|
|
45
80
|
external: isNode
|
|
46
|
-
? ['react', 'react-dom', 'react-dom/server', 'react/jsx-runtime', 'react/jsx-dev-runtime',
|
|
47
|
-
'node:path',
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
path.join(__dirname, '
|
|
81
|
+
? ['react', 'react-dom', 'react-dom/server', 'react/jsx-runtime', 'react/jsx-dev-runtime',
|
|
82
|
+
'node:http', 'node:path', 'node:fs', 'node:url', 'tls',
|
|
83
|
+
toFwdSlash(path.join(__dirname, 'cli.js')),
|
|
84
|
+
toFwdSlash(path.join(__dirname, 'config.js')),
|
|
85
|
+
toFwdSlash(path.join(__dirname, 'renderEngine.js')),
|
|
86
|
+
toFwdSlash(path.join(__dirname, 'rendererTempFiles.js'))]
|
|
52
87
|
: [
|
|
53
|
-
path.join(__dirname, 'cli.js')
|
|
88
|
+
toFwdSlash(path.join(__dirname, 'cli.js')),
|
|
89
|
+
toFwdSlash(path.join(__dirname, 'config.js')),
|
|
90
|
+
toFwdSlash(path.join(__dirname, 'renderEngine.js')),
|
|
91
|
+
toFwdSlash(path.join(__dirname, 'rendererTempFiles.js'))
|
|
54
92
|
],
|
|
55
93
|
});
|
|
56
94
|
return result.outputFiles[0].text;
|
|
@@ -86,7 +124,8 @@ function resolveTemplate(appDir, autoPageDir, autoPaging) {
|
|
|
86
124
|
return nextToCli;
|
|
87
125
|
}
|
|
88
126
|
function buildHtml(opts) {
|
|
89
|
-
const { pageHtml, clientCode, devPanelContainer, templatePath, hotReload, fileName } = opts;
|
|
127
|
+
const { pageHtml, clientCode, devPanelContainer, templatePath, hotReload, fileName, datRestricted, devMode } = opts;
|
|
128
|
+
const configScript = `<script>window.__authtics_config__={datRestricted:${datRestricted ? 'true' : 'false'},devMode:${devMode !== false ? 'true' : 'false'}};</script>`;
|
|
90
129
|
const hmrScript = hotReload ? HMR_SCRIPT : '';
|
|
91
130
|
if (templatePath && fs.existsSync(templatePath)) {
|
|
92
131
|
let template = fs.readFileSync(templatePath, "utf-8");
|
|
@@ -94,8 +133,8 @@ function buildHtml(opts) {
|
|
|
94
133
|
if (contentTag.test(template)) {
|
|
95
134
|
template = template.replace(contentTag, `<div id="root">${pageHtml}</div>\n ${devPanelContainer}`);
|
|
96
135
|
template = template.includes("</body>")
|
|
97
|
-
? template.replace("</body>", ` ${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}\n${hmrScript}</body>`)
|
|
98
|
-
: template + `\n${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}${hmrScript}`;
|
|
136
|
+
? template.replace("</body>", ` ${configScript}${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}\n${hmrScript}</body>`)
|
|
137
|
+
: template + `\n${configScript}${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}\n${hmrScript}`;
|
|
99
138
|
return template;
|
|
100
139
|
}
|
|
101
140
|
console.warn('[authtics] _template.html has no <authtics_host_content /> — using default layout.');
|
|
@@ -109,6 +148,7 @@ function buildHtml(opts) {
|
|
|
109
148
|
<body>
|
|
110
149
|
<div id="root">${pageHtml}</div>
|
|
111
150
|
${devPanelContainer}
|
|
151
|
+
${configScript}
|
|
112
152
|
${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}
|
|
113
153
|
${hmrScript}
|
|
114
154
|
</body>
|
|
@@ -131,39 +171,47 @@ function isCacheValid(tsxPath, tempPath, serverCjsPath, templatePath, devPanelPa
|
|
|
131
171
|
return false;
|
|
132
172
|
}
|
|
133
173
|
}
|
|
134
|
-
const HMR_SCRIPT =
|
|
135
|
-
|
|
136
|
-
(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
174
|
+
const HMR_SCRIPT = `<script>(function(){
|
|
175
|
+
var reloading=false;
|
|
176
|
+
var es=new EventSource('/hmr');
|
|
177
|
+
es.onmessage=function(e){
|
|
178
|
+
if(e.data==='reload'&&!reloading){
|
|
179
|
+
reloading=true;
|
|
180
|
+
es.close();
|
|
181
|
+
window.location.reload();
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
es.onerror=function(){
|
|
185
|
+
// onerror fires on both server-down AND on page-unload (SSE closed by navigation).
|
|
186
|
+
// Guard with reloading so a navigate-away never schedules a second reload.
|
|
187
|
+
if(!reloading){
|
|
188
|
+
setTimeout(function(){
|
|
189
|
+
if(!reloading){reloading=true;window.location.reload();}
|
|
190
|
+
},1500);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
})();</script>`;
|
|
194
|
+
export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = 'esbuild', hotReload = false, autoPaging = true, autoPageDir, appDir, fileHandler, rmvFileHandler, reqDAT, configDAT) {
|
|
148
195
|
ensureTempDirs();
|
|
149
196
|
if (!fs.existsSync(tsxPath)) {
|
|
150
197
|
throw new Error(`renderPage: source file not found: ${tsxPath}`);
|
|
151
198
|
}
|
|
152
199
|
let usesDevPanel = showPanel && devPanelPath !== null;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
datMatched
|
|
160
|
-
|
|
161
|
-
|
|
200
|
+
if (usesDevPanel) {
|
|
201
|
+
let datMatched = configDAT === undefined;
|
|
202
|
+
if (configDAT && configDAT === reqDAT)
|
|
203
|
+
datMatched = true;
|
|
204
|
+
if (configDAT && Array.isArray(configDAT) && configDAT.includes(reqDAT ?? ""))
|
|
205
|
+
datMatched = true;
|
|
206
|
+
if (!datMatched)
|
|
207
|
+
usesDevPanel = false;
|
|
208
|
+
}
|
|
162
209
|
const templatePath = resolveTemplate(appDir, autoPageDir, autoPaging);
|
|
163
210
|
const tempPath = tempFileForTsx(tsxPath);
|
|
164
211
|
const serverCjsPath = tempPath.replace(/\.json$/, ".server.cjs");
|
|
165
212
|
let clientCode;
|
|
166
213
|
let serverCode;
|
|
214
|
+
let freshWrite = false;
|
|
167
215
|
if (isCacheValid(tsxPath, tempPath, serverCjsPath, templatePath, devPanelPath) && autoPaging) {
|
|
168
216
|
try {
|
|
169
217
|
const parsed = JSON.parse(readTempFile(tempPath));
|
|
@@ -203,8 +251,10 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
|
|
|
203
251
|
}
|
|
204
252
|
fs.writeFileSync(serverCjsPath, serverCode, "utf-8");
|
|
205
253
|
writeTempFile(tempPath, JSON.stringify({ clientCode }));
|
|
254
|
+
freshWrite = true;
|
|
206
255
|
}
|
|
207
|
-
|
|
256
|
+
fileHandler ? fileHandler(clientCode, `/${path.basename(tempPath).replace(".json", ".js").replace(".tsx_", ".").toLowerCase()}`) : null;
|
|
257
|
+
const serverModule = await import(freshWrite ? `${serverCjsPath}?t=${Date.now()}` : serverCjsPath);
|
|
208
258
|
const exports = serverModule.default ?? serverModule;
|
|
209
259
|
const PageComponent = exports.default ?? exports.Page ?? exports.page ?? null;
|
|
210
260
|
const DevPanelComponent = usesDevPanel ? (exports.DevPanel ?? null) : null;
|
|
@@ -218,6 +268,9 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
|
|
|
218
268
|
const devPanelContainer = usesDevPanel
|
|
219
269
|
? `<div id="authtics-dev-panel-root">${devPanelHtml}</div>`
|
|
220
270
|
: "";
|
|
221
|
-
|
|
222
|
-
|
|
271
|
+
return buildHtml({ pageHtml, clientCode, devPanelContainer, templatePath, hotReload,
|
|
272
|
+
fileName: `/${path.basename(tempPath).replace(".json", ".js").replace(".tsx_", ".").toLowerCase()}`,
|
|
273
|
+
datRestricted: configDAT !== undefined,
|
|
274
|
+
devMode: showPanel,
|
|
275
|
+
});
|
|
223
276
|
}
|
package/package.json
CHANGED