@bananacool467/authtics-host 0.1.4 → 0.1.6

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/config.d.ts CHANGED
@@ -6,10 +6,11 @@ export interface AuthticsConfig {
6
6
  compilerType?: 'esbuild' | 'babel';
7
7
  hotReload?: boolean;
8
8
  dat?: string | string[];
9
- showError?: boolean | null;
10
- autoPage?: boolean | null;
9
+ showError?: boolean;
10
+ autoPage?: boolean;
11
11
  autoPageDir?: string;
12
- autoFile?: boolean | null;
12
+ autoFile?: boolean;
13
13
  autoFileDir?: string;
14
+ hasPausedRoute?: boolean;
14
15
  }
15
16
  export declare function defineConfig(config: AuthticsConfig): AuthticsConfig;
package/dist/config.js CHANGED
@@ -1,7 +1,19 @@
1
1
  export function defineConfig(config) {
2
- if (config.autoPage == null)
2
+ if (config.autoPage == undefined)
3
3
  config.autoPage = true;
4
- if (config.autoFile == null)
4
+ if (config.autoFile == undefined)
5
5
  config.autoFile = true;
6
+ if (config.showError == undefined)
7
+ config.showError = true;
8
+ if (config.compilerType == undefined)
9
+ config.compilerType = 'esbuild';
10
+ if (config.ssr == undefined)
11
+ config.ssr = true;
12
+ if (config.port == undefined || config.port == 0)
13
+ config.port = 3000;
14
+ if (config.devMode == undefined)
15
+ config.devMode = true;
16
+ if (config.hasPausedRoute == undefined)
17
+ config.hasPausedRoute = false;
6
18
  return config;
7
19
  }
package/dist/devPanel.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useEffect, useRef } from 'react';
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
4
  import Prism from 'prismjs';
5
5
  import 'prismjs/components/prism-javascript';
@@ -221,21 +221,23 @@ function installNetworkInterceptor(onFetch, setFetch, onEventSource, setEventSou
221
221
  };
222
222
  window.EventSource.prototype = OriginalEventSource.prototype;
223
223
  Object.assign(window.EventSource, OriginalEventSource);
224
- const queryImg = document.querySelectorAll('img');
225
- const queryScript = document.querySelectorAll('script');
226
- const queryLink = document.querySelectorAll('link');
227
- queryImg.forEach((img) => {
228
- if (img.src)
229
- onResource({ url: img.src, type: 'img', id: fetchId++ });
230
- });
231
- queryScript.forEach((script) => {
232
- if (script.src)
233
- onResource({ url: script.src, type: 'script', id: fetchId++ });
234
- });
235
- queryLink.forEach((link) => {
236
- if (link.href)
237
- onResource({ url: link.href, type: 'link', id: fetchId++ });
238
- });
224
+ setTimeout(() => {
225
+ const queryImg = document.querySelectorAll('img');
226
+ const queryScript = document.querySelectorAll('script');
227
+ const queryLink = document.querySelectorAll('link');
228
+ queryImg.forEach((img) => {
229
+ if (img.src)
230
+ onResource({ url: img.src, type: 'img', id: fetchId++ });
231
+ });
232
+ queryScript.forEach((script) => {
233
+ if (script.src)
234
+ onResource({ url: script.src, type: 'script', id: fetchId++ });
235
+ });
236
+ queryLink.forEach((link) => {
237
+ if (link.href)
238
+ onResource({ url: link.href, type: 'link', id: fetchId++ });
239
+ });
240
+ }, 5000);
239
241
  }
240
242
  function installConsoleInterceptor() {
241
243
  if (window.__authtics_intercepted__)
@@ -258,7 +260,7 @@ function installConsoleInterceptor() {
258
260
  });
259
261
  }
260
262
  function SecuredTab() {
261
- return (_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', padding: '8px 10px', textAlign: 'center', gap: '8px' }, children: [_jsx(CircleX, { size: 32, color: 'red' }), _jsx("span", { style: { color: 'red', fontSize: 24 }, children: "Tab Isn't 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." })] }));
263
+ return (_jsxs("div", { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', padding: '8px 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." })] }));
262
264
  }
263
265
  function PanelButton({ onClick, onClick2, children, style, fullWidth, disabled }) {
264
266
  const [hovered, setHovered] = useState(false);
@@ -303,22 +305,19 @@ export default function DevPanel() {
303
305
  const [clientInfoOpen, setClientInfoOpen] = useState(false);
304
306
  const [aboutHostOpen, setAboutHostOpen] = useState(false);
305
307
  const [serverInfoOpen, setServerInfoOpen] = useState(false);
306
- const [siteInspectOpen, setSiteInspectOpen] = useState(false);
307
308
  const [hasIssue, setHasIssue] = useState(false);
308
309
  const [ping__, setPing__] = useState(0);
309
310
  const [networkFetches, setNetworkFetches] = useState([]);
310
311
  const [eventSources, setEventSources] = useState([]);
312
+ const [usersPaused, setUsersPaused] = useState(false);
313
+ const [usersPausedRealInfo, setUsersPausedRealInfo] = useState(false);
311
314
  const [webSockets, setWebSockets] = useState([]);
312
315
  const [resourcesFound, setResourcesFound] = useState([]);
313
316
  const [status, setStatus] = useState(200);
314
- const [code, setCode] = useState('');
315
317
  const [pathName, setPathName] = useState(undefined);
316
318
  const [hostName, setHostName] = useState(undefined);
317
319
  const [protocol, setProtocol] = useState(undefined);
318
320
  const [path, setPath] = useState(undefined);
319
- const contextMenuTimeoutMobile = useRef(undefined);
320
- const [cursorPosition, setCursorPosition] = useState({ x: 0, y: 0 });
321
- const [contextMenuShown, setContextMenuShown] = useState(false);
322
321
  const [isSsr, setIsSsr] = useState(false);
323
322
  const datRestrictionMissingRef = useRef(true);
324
323
  const cpuUsage = useRef(0);
@@ -335,20 +334,19 @@ export default function DevPanel() {
335
334
  const [token, setToken] = useState(null);
336
335
  const [tokenLength, setTokenLength] = useState(0);
337
336
  const [tokenHidden, setTokenHidden] = useState(true);
338
- const [consoleInputFocused, setConsoleInputFocused] = useState(false);
339
- const consoleInputRef = useRef(null);
340
- const overlayRef = useRef(null);
341
337
  const fpsSpanRef = useRef(null);
342
338
  const frameCount = useRef(0);
343
339
  const frames = useRef(0);
344
340
  const consoleScrollRef = useRef(null);
345
341
  const [isAtBottom, setIsAtBottom] = useState(true);
346
342
  const [datRestrictionMissing, setDatRestrictionMissing] = useState(true);
347
- const [pos, setPos] = React.useState({ x: 20, y: 20 });
348
- const [dragging, setDragging] = React.useState(false);
349
- const offset = React.useRef({ x: 0, y: 0 });
350
- const [selected, setSelected] = React.useState(null);
351
- const [rootEl, setRootEl] = useState(null);
343
+ const cookie = {
344
+ set: (k, v) => document.cookie = `${k}=${v}; path=/`,
345
+ get: (k) => Object.fromEntries(document.cookie.split(";")
346
+ .filter(Boolean)
347
+ .map(c => c.trim().split("=")))[k],
348
+ del: (k) => document.cookie = `${k}=; path=/; max-age=0`
349
+ };
352
350
  const [doc, setDoc] = useState(null);
353
351
  const [filters, setFilters] = useState({
354
352
  Log: true, Info: true, Warn: true, Error: true, Debug: false
@@ -377,7 +375,7 @@ export default function DevPanel() {
377
375
  const resp = await fetch('/__authtics_host_apis__/get-file-by-pathname', {
378
376
  method: 'POST',
379
377
  headers: { 'Content-Type': 'application/json' },
380
- body: JSON.stringify({ pathname: window.location.pathname, dat: localStorage.getItem('dat') })
378
+ body: JSON.stringify({ pathname: window.location.pathname, })
381
379
  });
382
380
  if (resp.status === 200) {
383
381
  const data = await resp.json();
@@ -388,18 +386,30 @@ export default function DevPanel() {
388
386
  const resp = await fetch('/__authtics_host_apis__/get-dat-matching', {
389
387
  method: 'POST',
390
388
  headers: { 'Content-Type': 'application/json' },
391
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
389
+ body: JSON.stringify({})
392
390
  });
393
391
  if (resp.status === 200) {
394
392
  const data = await resp.json();
395
393
  setDatMatch(data.isMatching);
396
- if (!data.isMatching) {
394
+ const resp3 = await fetch('/__authtics_host_apis__/is-users-paused', {
395
+ method: 'POST',
396
+ headers: { 'Content-Type': 'application/json' },
397
+ body: JSON.stringify({})
398
+ });
399
+ let paused = false;
400
+ if (resp3.status === 200) {
401
+ const data = await resp3.json();
402
+ paused = data.paused;
403
+ setUsersPaused(paused);
404
+ setUsersPausedRealInfo(data.realInfo);
405
+ }
406
+ if (!data.isMatching && !paused) {
397
407
  doc?.getElementById('authtics-dev-panel-root')?.remove();
398
408
  }
399
409
  const resp2 = await fetch('/__authtics_host_apis__/get-dat-restriction-missing', {
400
410
  method: 'POST',
401
411
  headers: { 'Content-Type': 'application/json' },
402
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
412
+ body: JSON.stringify({})
403
413
  });
404
414
  if (resp2.status === 200) {
405
415
  const data = await resp2.json();
@@ -414,7 +424,7 @@ export default function DevPanel() {
414
424
  const resp = await fetch('/__authtics_host_apis__/get-is-ssr', {
415
425
  method: 'POST',
416
426
  headers: { 'Content-Type': 'application/json' },
417
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
427
+ body: JSON.stringify({})
418
428
  });
419
429
  if (resp.status === 200) {
420
430
  const data = await resp.json();
@@ -425,7 +435,7 @@ export default function DevPanel() {
425
435
  const resp = await fetch('/__authtics_host_apis__/get-cpu_memory', {
426
436
  method: 'POST',
427
437
  headers: { 'Content-Type': 'application/json' },
428
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
438
+ body: JSON.stringify({})
429
439
  });
430
440
  if (resp.status === 200) {
431
441
  const data = await resp.json();
@@ -437,7 +447,7 @@ export default function DevPanel() {
437
447
  const resp = await fetch('/__authtics_host_apis__/get-host-ver', {
438
448
  method: 'POST',
439
449
  headers: { 'Content-Type': 'application/json' },
440
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
450
+ body: JSON.stringify({})
441
451
  });
442
452
  if (resp.status === 200) {
443
453
  const data = await resp.json();
@@ -448,7 +458,7 @@ export default function DevPanel() {
448
458
  const resp = await fetch('/__authtics_host_apis__/get-compiler', {
449
459
  method: 'POST',
450
460
  headers: { 'Content-Type': 'application/json' },
451
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
461
+ body: JSON.stringify({})
452
462
  });
453
463
  if (resp.status === 200) {
454
464
  const data = await resp.json();
@@ -459,7 +469,7 @@ export default function DevPanel() {
459
469
  const resp = await fetch('/__authtics_host_apis__/get-connection', {
460
470
  method: 'POST',
461
471
  headers: { 'Content-Type': 'application/json' },
462
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
472
+ body: JSON.stringify({})
463
473
  });
464
474
  if (resp.status === 200) {
465
475
  const data = await resp.json();
@@ -478,7 +488,7 @@ export default function DevPanel() {
478
488
  const resp = await fetch('/__authtics_host_apis__/get-user-settings', {
479
489
  method: 'POST',
480
490
  headers: { 'Content-Type': 'application/json' },
481
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
491
+ body: JSON.stringify({})
482
492
  });
483
493
  if (resp.status === 200) {
484
494
  const data = await resp.json();
@@ -489,7 +499,7 @@ export default function DevPanel() {
489
499
  const resp = await fetch('/__authtics_host_apis__/get-server-info', {
490
500
  method: 'POST',
491
501
  headers: { 'Content-Type': 'application/json' },
492
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
502
+ body: JSON.stringify({})
493
503
  });
494
504
  if (resp.status === 200) {
495
505
  const data = await resp.json();
@@ -516,30 +526,18 @@ export default function DevPanel() {
516
526
  }, 250);
517
527
  }, 250);
518
528
  }, []);
519
- const datTouchStart = (e) => {
520
- e.preventDefault();
521
- setCursorPosition({ x: e.clientX || e.touches[0].clientX, y: e.clientY || e.touches[0].clientY });
522
- contextMenuTimeoutMobile.current = setTimeout(() => {
523
- setContextMenuShown(true);
524
- clearTimeout(contextMenuTimeoutMobile.current);
525
- }, 1000);
526
- };
527
- const datTouchEnd = (e) => {
528
- e.preventDefault();
529
- clearTimeout(contextMenuTimeoutMobile.current);
530
- };
531
529
  const restart = async () => {
532
- const resp = await fetch('/__authtics_host_apis__/restart', {
530
+ await fetch('/__authtics_host_apis__/restart', {
533
531
  method: 'POST',
534
532
  headers: { 'Content-Type': 'application/json' },
535
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
533
+ body: JSON.stringify({})
536
534
  });
537
535
  };
538
536
  const shutDown = async () => {
539
- const resp = await fetch('/__authtics_host_apis__/shutdown', {
537
+ await fetch('/__authtics_host_apis__/shutdown', {
540
538
  method: 'POST',
541
539
  headers: { 'Content-Type': 'application/json' },
542
- body: JSON.stringify({ dat: localStorage.getItem('dat') })
540
+ body: JSON.stringify({})
543
541
  });
544
542
  };
545
543
  useEffect(() => {
@@ -568,14 +566,13 @@ export default function DevPanel() {
568
566
  ? '320px'
569
567
  : '320px';
570
568
  useEffect(() => {
571
- const dat = localStorage.getItem('dat');
572
569
  const interval = setInterval(async () => {
573
570
  try {
574
571
  const timeStart = Date.now();
575
572
  const resp = await fetch('/__authtics_host_apis__/ping', {
576
573
  method: 'POST',
577
574
  headers: { 'Content-Type': 'application/json' },
578
- body: JSON.stringify({ dat })
575
+ body: JSON.stringify({})
579
576
  });
580
577
  if (resp.status === 200) {
581
578
  const data = await resp.json();
@@ -623,7 +620,7 @@ export default function DevPanel() {
623
620
  ;
624
621
  };
625
622
  try {
626
- const existingToken = localStorage.getItem('dat');
623
+ const existingToken = cookie.get('dat');
627
624
  if (existingToken) {
628
625
  setToken(existingToken);
629
626
  let length_ = existingToken?.split('');
@@ -634,7 +631,13 @@ export default function DevPanel() {
634
631
  else {
635
632
  const newToken = generateToken();
636
633
  try {
637
- localStorage.setItem('dat', newToken);
634
+ let localStorageToken;
635
+ try {
636
+ localStorageToken = localStorage.getItem('dat');
637
+ }
638
+ catch (e) {
639
+ }
640
+ cookie.set('dat', localStorageToken || newToken);
638
641
  setToken(newToken);
639
642
  let length_ = newToken?.split('');
640
643
  let length;
@@ -722,15 +725,31 @@ export default function DevPanel() {
722
725
  };
723
726
  __();
724
727
  }, []);
725
- const showSelfConsoleLog = (message) => {
726
- const event = window.dispatchEvent(new CustomEvent('authtics:log', {
727
- detail: {
728
- type: "Eval",
729
- message: message,
730
- time: Date.now(),
731
- source: "console.js"
728
+ const pause_Resume_Users = async () => {
729
+ if (usersPausedRealInfo) {
730
+ const resp = await fetch('/__authtics_host_apis__/set-users-paused', {
731
+ method: 'POST',
732
+ headers: { 'Content-Type': 'application/json' },
733
+ body: JSON.stringify({
734
+ paused: false
735
+ })
736
+ });
737
+ if (resp.status === 200) {
738
+ setUsersPausedRealInfo(false);
739
+ }
740
+ }
741
+ else {
742
+ const resp = await fetch('/__authtics_host_apis__/set-users-paused', {
743
+ method: 'POST',
744
+ headers: { 'Content-Type': 'application/json' },
745
+ body: JSON.stringify({
746
+ paused: true
747
+ })
748
+ });
749
+ if (resp.status === 200) {
750
+ setUsersPausedRealInfo(true);
732
751
  }
733
- }));
752
+ }
734
753
  };
735
754
  return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
736
755
  position: 'absolute',
@@ -908,7 +927,7 @@ export default function DevPanel() {
908
927
  border: '1px solid #eee',
909
928
  fontSize: '11px',
910
929
  fontFamily: 'monospace'
911
- }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsx("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: r.type }), _jsx("span", { style: { flex: 1, overflow: 'hidden', color: '#333' }, children: r.url })] }) }, i)))] })] })) : routeOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
930
+ }, children: _jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '8px', padding: '6px 10px' }, children: [_jsx("span", { style: { color: '#3b82f6', display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }, children: r.type }), _jsx("span", { style: { flex: 1, color: '#333' }, children: r.url })] }) }, i)))] })] })) : routeOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
912
931
  padding: '6px 8px',
913
932
  borderBottom: '1px solid #ddd',
914
933
  background: '#fff',
@@ -1152,7 +1171,7 @@ export default function DevPanel() {
1152
1171
  gap: '6px',
1153
1172
  color: '#fff',
1154
1173
  flexDirection: 'row',
1155
- }, children: "Updates to security. Apps with version 0.0.1-beta.9 and over will now require DAT restriction to access remote features like restarting and shutting down the app." }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Restarting the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Shutting down the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {}))] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1174
+ }, children: "Updates to security. Apps with version 0.0.1-beta.9 and over will now require DAT restriction to access remote features like restarting and shutting down the app." }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Restarting the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Shutting down the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { pause_Resume_Users(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, disabled: datRestrictionMissing, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: usersPausedRealInfo ? "Resume Users" : "Pause Users" }) }), datRestrictionMissing ? (_jsxs("span", { style: { display: 'flex', opacity: 0.5, fontSize: 10, justifyContent: 'center', alignItems: 'center', gap: '4px' }, children: [_jsx(Info, { size: 10 }), "Pausing users from accessing the app is unavaliable. Set \"dat\" in the Authtics Host config to set restriction and then restart."] })) : (_jsx(_Fragment, {}))] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1156
1175
  display: 'flex',
1157
1176
  flexDirection: 'row',
1158
1177
  alignItems: 'center',
package/dist/index.d.ts CHANGED
@@ -1,5 +1,30 @@
1
+ declare module "http" {
2
+ interface IncomingMessage {
3
+ ip: string | undefined;
4
+ ipType: number;
5
+ body: any;
6
+ cookies: Record<string, string>;
7
+ ua: string | undefined;
8
+ os: any;
9
+ browser: any;
10
+ dat: string | undefined;
11
+ bodySize: number;
12
+ bodyType: string;
13
+ sentTime: number;
14
+ }
15
+ interface ServerResponse {
16
+ redirect: (url: string) => void;
17
+ html: (content: string) => void;
18
+ json: (content: any) => void;
19
+ text: (content: string) => void;
20
+ file: (path_: string) => void;
21
+ status: (code: number) => ServerResponse;
22
+ reload: () => void;
23
+ setCookie: (name: string, value: string) => void;
24
+ rmvCookie: (name: string) => void;
25
+ }
26
+ }
1
27
  import { defineConfig } from './config.js';
2
28
  import App from './cli.js';
3
- import { Route } from './route.js';
4
- import { RouteMap } from './route.js';
5
- export { App, Route, RouteMap, defineConfig };
29
+ import { Route, RouteMap, Paused } from './route.js';
30
+ export { App, Route, RouteMap, Paused, defineConfig };
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { defineConfig } from './config.js';
2
2
  import App from './cli.js';
3
- import { Route } from './route.js';
4
- import { RouteMap } from './route.js';
5
- export { App, Route, RouteMap, defineConfig };
3
+ import { Route, RouteMap, Paused } from './route.js';
4
+ export { App, Route, RouteMap, Paused, defineConfig };
@@ -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): 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, reqDAT?: string | undefined, configDAT?: string | string[] | undefined): Promise<string>;
@@ -86,7 +86,7 @@ function resolveTemplate(appDir, autoPageDir, autoPaging) {
86
86
  return nextToCli;
87
87
  }
88
88
  function buildHtml(opts) {
89
- const { pageHtml, clientCode, devPanelContainer, templatePath, hotReload } = opts;
89
+ const { pageHtml, clientCode, devPanelContainer, templatePath, hotReload, fileName } = opts;
90
90
  const hmrScript = hotReload ? HMR_SCRIPT : '';
91
91
  if (templatePath && fs.existsSync(templatePath)) {
92
92
  let template = fs.readFileSync(templatePath, "utf-8");
@@ -94,8 +94,8 @@ function buildHtml(opts) {
94
94
  if (contentTag.test(template)) {
95
95
  template = template.replace(contentTag, `<div id="root">${pageHtml}</div>\n ${devPanelContainer}`);
96
96
  template = template.includes("</body>")
97
- ? template.replace("</body>", ` <script>${clientCode}</script>\n${hmrScript}</body>`)
98
- : template + `\n<script>${clientCode}</script>${hmrScript}`;
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}`;
99
99
  return template;
100
100
  }
101
101
  console.warn('[authtics] _template.html has no <authtics_host_content /> — using default layout.');
@@ -109,7 +109,7 @@ function buildHtml(opts) {
109
109
  <body>
110
110
  <div id="root">${pageHtml}</div>
111
111
  ${devPanelContainer}
112
- <script>${clientCode}</script>
112
+ ${fileName ? `<script src="${fileName}"></script>` : `<script>${clientCode}</script>`}
113
113
  ${hmrScript}
114
114
  </body>
115
115
  </html>`;
@@ -137,15 +137,28 @@ const HMR_SCRIPT = `
137
137
  const es = new EventSource('/__authtics_hmr__');
138
138
  es.onmessage = function(e) { if (e.data === 'reload') window.location.reload(); };
139
139
  es.onerror = function() { setTimeout(function() { window.location.reload(); }, 1000); };
140
+ window.onbeforeunload = function() {
141
+ es.close();
142
+ es = null;
143
+ };
140
144
  })();
141
145
  </script>
142
146
  `;
143
- export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = 'esbuild', hotReload = false, autoPaging = true, autoPageDir, appDir) {
147
+ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = 'esbuild', hotReload = false, autoPaging = true, autoPageDir, appDir, fileHandler, reqDAT, configDAT) {
144
148
  ensureTempDirs();
145
149
  if (!fs.existsSync(tsxPath)) {
146
150
  throw new Error(`renderPage: source file not found: ${tsxPath}`);
147
151
  }
148
- const usesDevPanel = showPanel && devPanelPath !== null;
152
+ let usesDevPanel = showPanel && devPanelPath !== null;
153
+ let datMatched = false;
154
+ if (configDAT && configDAT == reqDAT)
155
+ datMatched = true;
156
+ if (configDAT && Array.isArray(configDAT) && configDAT.includes(reqDAT || ""))
157
+ datMatched = true;
158
+ if (configDAT == undefined)
159
+ datMatched = true;
160
+ if (!datMatched && usesDevPanel)
161
+ usesDevPanel = false;
149
162
  const templatePath = resolveTemplate(appDir, autoPageDir, autoPaging);
150
163
  const tempPath = tempFileForTsx(tsxPath);
151
164
  const serverCjsPath = tempPath.replace(/\.json$/, ".server.cjs");
@@ -205,5 +218,6 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
205
218
  const devPanelContainer = usesDevPanel
206
219
  ? `<div id="authtics-dev-panel-root">${devPanelHtml}</div>`
207
220
  : "";
208
- return buildHtml({ pageHtml, clientCode, devPanelContainer, templatePath, hotReload });
221
+ fileHandler ? fileHandler(clientCode.replace('\n', ''), `/${tsxPath.substring(tsxPath.lastIndexOf('/') + 1).replace(".tsx", ".js").toLowerCase()}`) : null;
222
+ return buildHtml({ pageHtml, clientCode, devPanelContainer, templatePath, hotReload, fileName: `/${tsxPath.substring(tsxPath.lastIndexOf('/') + 1).replace(".tsx", ".js").toLowerCase()}` });
209
223
  }
@@ -1,5 +1,6 @@
1
1
  export declare function ensureTempDirs(): void;
2
2
  export declare function tempFileForTsx(tsxPath: string): string;
3
+ export declare function tempFileForDev(): string;
3
4
  export declare function isTempUpToDate(tsxPath: string, tempPath: string): boolean;
4
5
  export declare function writeTempFile(tempPath: string, content: string): void;
5
6
  export declare function readTempFile(tempPath: string): string;
@@ -1,12 +1,15 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  const AUTHTICS_DIR = path.join(process.cwd(), ".authtics_host");
4
+ const DEV_CACHE_DIR = path.join(AUTHTICS_DIR, "dev-cache");
4
5
  const CACHE_DIR = path.join(AUTHTICS_DIR, "cache");
5
6
  export function ensureTempDirs() {
6
7
  if (!fs.existsSync(AUTHTICS_DIR))
7
8
  fs.mkdirSync(AUTHTICS_DIR, { recursive: true });
8
9
  if (!fs.existsSync(CACHE_DIR))
9
10
  fs.mkdirSync(CACHE_DIR, { recursive: true });
11
+ if (!fs.existsSync(DEV_CACHE_DIR))
12
+ fs.mkdirSync(DEV_CACHE_DIR, { recursive: true });
10
13
  }
11
14
  export function tempFileForTsx(tsxPath) {
12
15
  ensureTempDirs();
@@ -14,6 +17,10 @@ export function tempFileForTsx(tsxPath) {
14
17
  const hash = simpleHash(tsxPath);
15
18
  return path.join(CACHE_DIR, `${base}_${hash}.json`);
16
19
  }
20
+ export function tempFileForDev() {
21
+ ensureTempDirs();
22
+ return path.join(DEV_CACHE_DIR, "page.cache.json");
23
+ }
17
24
  export function isTempUpToDate(tsxPath, tempPath) {
18
25
  try {
19
26
  const srcMtime = fs.statSync(tsxPath).mtimeMs;
package/dist/route.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export declare function RouteMap({ children }: {
2
2
  children?: React.ReactNode;
3
3
  }): import("react/jsx-runtime").JSX.Element;
4
+ export declare function Paused({ page, statusCode }: {
5
+ page: Function;
6
+ statusCode?: number;
7
+ }): import("react/jsx-runtime").JSX.Element;
4
8
  export declare function Route({ page, statusCode, at }: {
5
9
  page: Function;
6
10
  statusCode?: number;
package/dist/route.js CHANGED
@@ -15,20 +15,27 @@ export function RouteMap({ children }) {
15
15
  const childrenToProcess = Array.isArray(childArray.current)
16
16
  ? childArray.current
17
17
  : [childArray.current];
18
+ setCurrentlyAwaiting(false);
18
19
  childrenToProcess.forEach((child) => {
19
- if (child?.props?.at === path) {
20
+ if (child?.type?.name === "Paused") {
21
+ if (window.__paused__ === true) {
22
+ matched.current = child.props;
23
+ }
24
+ }
25
+ if (child?.props?.at === path && !window.__paused__ && !matched.current) {
20
26
  matched.current = child.props;
21
27
  }
22
28
  });
23
- if (!matched.current) {
24
- childrenToProcess.forEach((child) => {
25
- if (child?.props?.at === undefined) {
26
- matched.current = child.props;
27
- setAt404(true);
28
- }
29
- });
30
- }
31
- setCurrentlyAwaiting(false);
29
+ setTimeout(() => {
30
+ if (!matched.current && !window.__paused__) {
31
+ childrenToProcess.forEach((child) => {
32
+ if (child?.props?.at === undefined && child?.type?.name !== "Paused" && !window.__paused__) {
33
+ matched.current = child.props;
34
+ setAt404(true);
35
+ }
36
+ });
37
+ }
38
+ }, 500);
32
39
  }, [path]);
33
40
  useEffect(() => {
34
41
  if (matched.current && !At404) {
@@ -50,6 +57,9 @@ export function RouteMap({ children }) {
50
57
  return _jsx(_Fragment, {});
51
58
  return _jsx(NotFound, {});
52
59
  }
60
+ export function Paused({ page, statusCode }) {
61
+ return (_jsx(_Fragment, {}));
62
+ }
53
63
  export function Route({ page, statusCode, at }) {
54
64
  return (_jsx(_Fragment, {}));
55
65
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bananacool467/authtics-host",
3
- "version": "0.1.4",
4
- "description": "A Next.js-inspired SSR framework for Node.js with TypeScript and JSX support.",
3
+ "version": "0.1.6",
4
+ "description": "Authtics Host, A Next.js-inspired SSR framework for Node.js with TypeScript and JSX support.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "type": "module",
@@ -32,12 +32,14 @@
32
32
  "tsx",
33
33
  "jsx",
34
34
  "html",
35
+ "js",
35
36
  "lightweight",
36
37
  "hot-reload",
37
38
  "dev",
38
39
  "developer",
39
40
  "HostJS",
40
- "Host.js"
41
+ "Host.js",
42
+ "website"
41
43
  ],
42
44
  "author": "bananacool467",
43
45
  "license": "MIT",
@@ -49,8 +51,7 @@
49
51
  "esbuild": "^0.27.3",
50
52
  "jiti": "^2.6.1",
51
53
  "lucide-react": "^0.577.0",
52
- "prismjs": "^1.30.0",
53
- "react-device-detect": "^2.2.3"
54
+ "prismjs": "^1.30.0"
54
55
  },
55
56
  "peerDependencies": {
56
57
  "react": "^19.2.4",
@@ -1,4 +0,0 @@
1
- export default function locate(fileName: string, fileName2: string): {
2
- resolved: string;
3
- exists: boolean;
4
- } | undefined;