@bananacool467/authtics-host 0.0.1-beta.6 → 0.0.1-beta.7

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # Authtics Host
2
2
 
3
- Version 0.0.1-beta.6
3
+ Version 0.0.1-beta.7
4
4
  License: MIT
5
5
 
6
- (NOTE: This version (v0.0.1-beta.1) is in BETA, bugs are expected)
6
+ (NOTE: This version is in BETA, bugs are expected)
7
7
 
8
8
  Authtics Host is a framework inspired by Next.js. Authtics Host supports SSR (Server-Side Rendering) and uses esbuild.
9
9
 
@@ -138,6 +138,32 @@ node --experimental-strip-types index.ts
138
138
 
139
139
  ## Result
140
140
 
141
- Then when you run your project, you will get a page just saying **"Hello, World!"**
141
+ Then when you run your project, you will get a page just saying **"Hello, World!"** and you should see a panel at the bottom-right.
142
+
143
+ ## Developer Panel Notes and Warnings And DAT (Developer Access Token)
144
+
145
+ A DAT (Developer Access Token) is your token that is used to access the Developer Panel.
146
+
147
+ The Developer Panel can be turned off if you change `devMode` to `false` in **authtics_host.config.ts**.
148
+
149
+ You can restrict the Developer Panel's access to developer(s) only by copying your DAT and then adding it to **authtics_host.config.ts** `defineConfig` export:
150
+ ```typescript
151
+ "dat": "YOUR DAT HERE"
152
+ ```
153
+
154
+ But if you have multiple DATs, then use:
155
+ ```typescript
156
+ "dat": [
157
+ "DAT 1",
158
+ "DAT 2",
159
+ "DAT 3"
160
+ ]
161
+ ```
162
+
163
+ There isn't any limit of DATs you can add.
164
+
165
+ **(Warning: Make sure `devMode` is set to `false` in production. If `devMode` is on and DAT restriction is disabled, anyone can access the restart and shutdown endpoints.)**
166
+
167
+ ## Contacting
142
168
 
143
169
  If you ever encounter a bug, report it to (or have questions, contact): authtics@proton.me
package/dist/cli.js CHANGED
@@ -244,12 +244,13 @@ export default class App {
244
244
  datMatched = true;
245
245
  if (datMatched) {
246
246
  const pathname = reqBody.pathname;
247
- const filePath = pathname == "/" ? path.join(process.cwd(), "pages", "index.tsx") : path.join(process.cwd(), "pages", pathname + ".tsx");
248
- const fileExists = fs.existsSync(filePath);
247
+ const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
248
+ const filePath = pagesDir ? path.join(pagesDir, pathname + ".tsx") : undefined;
249
+ const fileExists = filePath ? fs.existsSync(filePath) : true;
249
250
  res.writeHead(200, { "Content-Type": "application/json" });
250
251
  res.end(JSON.stringify({
251
252
  fileExists,
252
- filePath
253
+ filePath: (filePath ? filePath : "Cannot find file because autoPage is disabled.")
253
254
  }));
254
255
  }
255
256
  });
@@ -302,7 +303,7 @@ export default class App {
302
303
  const notFoundPath = path.join(__dirname, '404.js');
303
304
  if (fs.existsSync(notFoundPath)) {
304
305
  try {
305
- let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload);
306
+ let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload, (config_.autoPage != false));
306
307
  res.setHeader("Content-Type", "text/html");
307
308
  res.writeHead(404);
308
309
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
@@ -357,19 +358,25 @@ async function start() {
357
358
  console.log(JSON.stringify(config));
358
359
  const PORT = config.port ?? 3000;
359
360
  const showPanel = config.devMode !== false;
361
+ const autoPaging = config.autoPage !== false;
360
362
  const compiler = config.compilerType === 'babel' ? 'babel' : 'esbuild';
361
363
  const hotReload = config.hotReload === true;
362
364
  const pagesDir = config.autoPage === true ? path.join(process.cwd(), config.autoPageDir || "") : undefined;
363
365
  const publicDir = config.autoFile === true ? path.join(process.cwd(), config.autoFileDir || "") : undefined;
364
366
  const apiDir = pagesDir ? path.join(pagesDir, "api") : undefined;
365
367
  const server = createServer(async (req, res) => {
368
+ //const body = await getJsonBody(req) as any;
369
+ const actuallyShowPanel = showPanel; /* && (config.dat != undefined ? (body.dat == config.dat || (Array.isArray(config.dat) && config.dat.includes(body.dat))) : true)*/
366
370
  const r = augmentRes(res);
367
371
  const { url = "/", method } = req;
368
372
  // Strip query string, hash, trailing slash
369
373
  let pathname = url.split("?")[0].split("#")[0];
370
374
  if (pathname !== "/" && pathname.endsWith("/"))
371
375
  pathname = pathname.slice(0, -1);
372
- if (pathname !== "/__authtics_host_apis__/ping" && pathname !== "/__authtics_host_apis__/get-connection" && pathname !== "/__authtics_hmr__" && pathname !== "/__authtics_host_apis__/get-file-by-pathname" && pathname !== "/__authtics_host_apis__/get-is-ssr" && pathname !== "/__authtics_host_apis__/get-compiler" && pathname !== "/__authtics_host_apis__/restart" && pathname !== "/__authtics_host_apis__/shutdown" && pathname !== "/__authtics_host_apis__/get-server-info" && pathname !== "/__authtics_host_apis__/get-cpu_memory") {
376
+ /*if (pathname !== "/__authtics_host_apis__/ping" && pathname !== "/__authtics_host_apis__/get-connection" && pathname !== "/__authtics_hmr__" && pathname !== "/__authtics_host_apis__/get-file-by-pathname" && pathname !== "/__authtics_host_apis__/get-is-ssr" && pathname !== "/__authtics_host_apis__/get-compiler" && pathname !== "/__authtics_host_apis__/restart" && pathname !== "/__authtics_host_apis__/shutdown" && pathname !== "/__authtics_host_apis__/get-server-info" && pathname !== "/__authtics_host_apis__/get-cpu_memory") {
377
+ totalRequests++;
378
+ }*/
379
+ if (!pathname.includes('/__authtics_host_apis__/')) {
373
380
  totalRequests++;
374
381
  }
375
382
  // ── 1. Registered routes (from app.get/post/etc.) ──────────────────────
@@ -444,7 +451,7 @@ async function start() {
444
451
  const htmlPath = pagesDir ? path.join(pagesDir, `${urlPath}.html`) : undefined;
445
452
  if (tsxPath && fs.existsSync(tsxPath)) {
446
453
  try {
447
- const html = await renderPage(tsxPath, url, showPanel, compiler, hotReload);
454
+ const html = await renderPage(tsxPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
448
455
  res.setHeader("Content-Type", "text/html");
449
456
  return res.end(html);
450
457
  }
@@ -465,7 +472,7 @@ async function start() {
465
472
  const appPath = path.join(process.cwd(), appTsxPath);
466
473
  if (fs.existsSync(appPath)) {
467
474
  try {
468
- const html = await renderPage(appPath, url, showPanel, compiler, hotReload);
475
+ const html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
469
476
  res.setHeader("Content-Type", "text/html");
470
477
  return res.end(html);
471
478
  }
@@ -480,7 +487,7 @@ async function start() {
480
487
  const notFoundPath = path.join(__dirname, '404.js');
481
488
  if (fs.existsSync(notFoundPath)) {
482
489
  try {
483
- let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload);
490
+ let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
484
491
  res.setHeader("Content-Type", "text/html");
485
492
  res.writeHead(404);
486
493
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
package/dist/devPanel.js CHANGED
@@ -5,7 +5,7 @@ import { ShieldCheck, CircleX, ChevronDown, ChevronUp, Bug, AlertTriangle, Info,
5
5
  import Prism from 'prismjs';
6
6
  import 'prismjs/components/prism-javascript';
7
7
  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/;
8
- const isMobile = true;
8
+ //const isMobile = true;
9
9
  function getCallerSource() {
10
10
  try {
11
11
  const stack = new Error().stack ?? '';
@@ -1088,15 +1088,6 @@ useEffect(() => {
1088
1088
  border: '1px solid #eee',
1089
1089
  fontSize: '12px',
1090
1090
  color: '#333',
1091
- }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Device Type" }), _jsx("span", { style: { fontSize: '12px', color: 'blue' }, children: isMobile ? 'Mobile' : 'PC' })] }), _jsxs("div", { style: {
1092
- display: 'flex',
1093
- justifyContent: 'space-between',
1094
- padding: '6px 10px',
1095
- background: '#fff',
1096
- borderRadius: '10px',
1097
- border: '1px solid #eee',
1098
- fontSize: '12px',
1099
- color: '#333',
1100
1091
  }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "FPS" }), _jsx("span", { style: { fontSize: '12px', color: (frames.current < 30 ? '#e53e3e' : frames.current < 60 ? '#d97706' : '#16a34a') }, ref: fpsSpanRef, children: "\u2014" })] })] })] })) : aboutHostOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
1101
1092
  padding: '6px 8px',
1102
1093
  borderBottom: '1px solid #ddd',
@@ -1113,7 +1104,7 @@ useEffect(() => {
1113
1104
  border: '1px solid #eee',
1114
1105
  fontSize: '12px',
1115
1106
  color: '#333',
1116
- }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Version" }), _jsx("span", { style: { fontSize: '12px', color: 'blue' }, children: "v0.0-beta.1" })] }), _jsxs("div", { style: {
1107
+ }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Version" }), _jsx("span", { style: { fontSize: '12px', color: 'blue' }, children: "v0.0.1-beta.7" })] }), _jsxs("div", { style: {
1117
1108
  display: 'flex',
1118
1109
  justifyContent: 'space-between',
1119
1110
  padding: '6px 10px',
@@ -1133,7 +1124,7 @@ useEffect(() => {
1133
1124
  color: '#333',
1134
1125
  cursor: 'pointer',
1135
1126
  textDecoration: 'none'
1136
- }, href: "https://bananakitssu.github.io/authtics-host-documentation", children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Documentation" }), _jsx("span", { style: { fontSize: '12px', color: '#333' }, children: _jsx(ChevronRight, { size: 12 }) })] })] })] })) : serverInfoOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
1127
+ }, href: "https://www.npmjs.com/package/@bananacool467/authtics-host", children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Documentation" }), _jsx("span", { style: { fontSize: '12px', color: '#333' }, children: _jsx(ChevronRight, { size: 12 }) })] })] })] })) : serverInfoOpen ? (_jsxs(_Fragment, { children: [_jsxs("div", { style: {
1137
1128
  padding: '6px 8px',
1138
1129
  borderBottom: '1px solid #ddd',
1139
1130
  background: '#fff',
@@ -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): Promise<string>;
3
+ export declare function renderPage(tsxPath: string, reqUrl?: string, showPanel?: boolean, compiler?: CompilerType, hotReload?: boolean, autoPaging?: boolean): Promise<string>;
@@ -191,7 +191,7 @@ const HMR_SCRIPT = `
191
191
  })();
192
192
  </script>
193
193
  `;
194
- export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = 'esbuild', hotReload = false) {
194
+ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = 'esbuild', hotReload = false, autoPaging = true) {
195
195
  ensureTempDirs();
196
196
  if (!fs.existsSync(tsxPath)) {
197
197
  throw new Error(`renderPage: source file not found: ${tsxPath}`);
@@ -206,7 +206,7 @@ export async function renderPage(tsxPath, reqUrl, showPanel = true, compiler = '
206
206
  const serverCjsPath = tempPath.replace(/\.json$/, ".server.cjs");
207
207
  let clientCode;
208
208
  let serverCode;
209
- if (isCacheValid(tsxPath, tempPath, serverCjsPath, templatePath, devPanelPath)) {
209
+ if (isCacheValid(tsxPath, tempPath, serverCjsPath, templatePath, devPanelPath) && autoPaging) {
210
210
  try {
211
211
  const parsed = JSON.parse(readTempFile(tempPath));
212
212
  clientCode = parsed.clientCode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananacool467/authtics-host",
3
- "version": "0.0.1-beta.6",
3
+ "version": "0.0.1-beta.7",
4
4
  "description": "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",
@@ -1 +0,0 @@
1
- export declare function hydrate(Component: any): Promise<void>;
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import { hydrateRoot } from 'react-dom/client';
3
- // This function will be called by the browser
4
- export async function hydrate(Component) {
5
- hydrateRoot(document.getElementById('root'), React.createElement(Component));
6
- }
@@ -1 +0,0 @@
1
- export declare function createTempFiles(tsxPath: string): Promise<string>;
@@ -1,35 +0,0 @@
1
- import * as esbuild from "esbuild";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- export async function createTempFiles(tsxPath) {
5
- const TEMP_DIR = path.join(process.cwd(), ".authtics_host", "%temp%", "jsx_to_js");
6
- if (!fs.existsSync(TEMP_DIR))
7
- fs.mkdirSync(TEMP_DIR, { recursive: true });
8
- const fileName = path.basename(tsxPath);
9
- const outPath = path.join(TEMP_DIR, `${fileName}.atx_js`);
10
- const source = fs.readFileSync(tsxPath, "utf8");
11
- // 1. Separate the "Brain" (Logic) from the "Body" (JSX)
12
- // We look for everything inside the function before the 'return'
13
- const logicRegex = /export default function.*?\s*\{([\s\S]*?)return\s*\(/;
14
- const match = source.match(logicRegex);
15
- const rawLogic = match ? match[1] : "";
16
- // 2. Add the Authtics "Hook Shim"
17
- // This makes sure 'useState' works without the full React library!
18
- const shimmedLogic = `
19
- const hooks = [];
20
- let currentHook = 0;
21
- function useState(initialValue) {
22
- const pair = [initialValue, (newVal) => { /* logic to update DOM */ }];
23
- return pair;
24
- }
25
-
26
- // Original Logic:
27
- ${rawLogic}
28
- `;
29
- const result = await esbuild.transform(shimmedLogic, {
30
- loader: "ts",
31
- format: "esm",
32
- });
33
- fs.writeFileSync(outPath, result.code);
34
- return outPath;
35
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * rewriteBareImports(virtualSource, fromDir)
3
- * - virtualSource: string source code that may contain bare imports like `import x from "pkg"`
4
- * - fromDir: directory to resolve from (usually process.cwd())
5
- *
6
- * Returns: { code: string, resolvedMap: Record<string,string> }
7
- * - code: source with bare imports rewritten to absolute file paths
8
- * - resolvedMap: mapping from original specifier -> resolved absolute path
9
- *
10
- * NOTE: This uses require.resolve to find package entry points. It prefers ESM entry if package.json.module exists,
11
- * otherwise falls back to main. For CJS-only packages this may still work because esbuild can bundle CJS.
12
- */
13
- export declare function rewriteBareImports(virtualSource: string, fromDir: string): {
14
- code: string;
15
- resolvedMap: Record<string, string>;
16
- };
@@ -1,76 +0,0 @@
1
- import path from "node:path";
2
- /**
3
- * rewriteBareImports(virtualSource, fromDir)
4
- * - virtualSource: string source code that may contain bare imports like `import x from "pkg"`
5
- * - fromDir: directory to resolve from (usually process.cwd())
6
- *
7
- * Returns: { code: string, resolvedMap: Record<string,string> }
8
- * - code: source with bare imports rewritten to absolute file paths
9
- * - resolvedMap: mapping from original specifier -> resolved absolute path
10
- *
11
- * NOTE: This uses require.resolve to find package entry points. It prefers ESM entry if package.json.module exists,
12
- * otherwise falls back to main. For CJS-only packages this may still work because esbuild can bundle CJS.
13
- */
14
- export function rewriteBareImports(virtualSource, fromDir) {
15
- // quick regex to find import/export statements with bare specifiers
16
- // This is a pragmatic approach; not a full parser.
17
- const importRegex = /(?:import\s+(?:[^'"]+)\s+from\s+|import\s*\(\s*|export\s+.*\s+from\s+)(['"])([^'"]+)\1/g;
18
- const importSimpleRegex = /import\s+(['"])([^'"]+)\1/g; // import "side-effect"
19
- const resolvedMap = {};
20
- let code = virtualSource;
21
- function resolveSpecifier(spec) {
22
- // If it's relative or absolute, leave it
23
- if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("http://") || spec.startsWith("https://")) {
24
- return spec;
25
- }
26
- // Node built-in polyfill map (you can extend)
27
- const builtinPolyfills = {
28
- crypto: "crypto-browserify",
29
- stream: "stream-browserify",
30
- buffer: "buffer",
31
- util: "util",
32
- path: "path-browserify",
33
- os: "os-browserify/browser",
34
- };
35
- const mapped = builtinPolyfills[spec] ?? spec;
36
- try {
37
- // Try to resolve package.json "module" or "exports" if possible by checking package.json
38
- // First try require.resolve for mapped spec
39
- const resolved = require.resolve(mapped, { paths: [fromDir] });
40
- return resolved;
41
- }
42
- catch (e) {
43
- // fallback: try to resolve mapped + '/index.js'
44
- try {
45
- const resolved2 = require.resolve(path.join(mapped), { paths: [fromDir] });
46
- return resolved2;
47
- }
48
- catch (e2) {
49
- // give up: return original spec so esbuild can try to handle it (or fail)
50
- return spec;
51
- }
52
- }
53
- }
54
- // Replace matches from importRegex
55
- code = code.replace(importRegex, (full, quote, spec) => {
56
- const resolved = resolveSpecifier(spec);
57
- if (resolved !== spec) {
58
- resolvedMap[spec] = resolved;
59
- // convert to file:// absolute path so esbuild can import it
60
- const fileUrl = resolved.startsWith("/") ? resolved : path.resolve(fromDir, resolved);
61
- return full.replace(quote + spec + quote, JSON.stringify(fileUrl));
62
- }
63
- return full;
64
- });
65
- // handle import "side-effect" forms
66
- code = code.replace(importSimpleRegex, (full, quote, spec) => {
67
- const resolved = resolveSpecifier(spec);
68
- if (resolved !== spec) {
69
- resolvedMap[spec] = resolved;
70
- const fileUrl = resolved.startsWith("/") ? resolved : path.resolve(fromDir, resolved);
71
- return full.replace(quote + spec + quote, JSON.stringify(fileUrl));
72
- }
73
- return full;
74
- });
75
- return { code, resolvedMap };
76
- }