@bananacool467/authtics-host 0.0.1-beta.6 → 0.0.1-beta.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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # Authtics Host
2
2
 
3
- Version 0.0.1-beta.6
3
+ Version 0.0.1-beta.8
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
 
@@ -33,14 +33,14 @@ To make your app, with auto paging and auto filing, your file tree should look l
33
33
 
34
34
  **(NOTE: the public folder is for auto filing)**
35
35
 
36
- index.ts should look like:
36
+ `index.ts` should look like:
37
37
  ```ts
38
38
  import { App } from "@bananacool467/authtics-host";
39
39
 
40
40
  const app = new App();
41
41
  ```
42
42
 
43
- authtics_host.config.ts should look like:
43
+ `authtics_host.config.ts` should look like:
44
44
  ```ts
45
45
  import { defineConfig } from "@bananacool467/authtics-host";
46
46
 
@@ -55,7 +55,7 @@ export default defineConfig({
55
55
  })
56
56
  ```
57
57
 
58
- client/pages/index.tsx should look like:
58
+ `client/pages/index.tsx` should look like:
59
59
  ```tsx
60
60
  export default function Index () {
61
61
  return (
@@ -75,7 +75,7 @@ To make your app, without auto paging and auto filing, your file tree should loo
75
75
  index.tsx
76
76
  ```
77
77
 
78
- index.ts should look like:
78
+ `index.ts` should look like:
79
79
  ```ts
80
80
  import { App } from "@bananacool467/authtics-host";
81
81
 
@@ -83,7 +83,7 @@ const app = new App();
83
83
  app.registerApp("client/app.tsx");
84
84
  ```
85
85
 
86
- authtics_host.config.ts should look like:
86
+ `authtics_host.config.ts` should look like:
87
87
  ```ts
88
88
  import { defineConfig } from "@bananacool467/authtics-host";
89
89
 
@@ -96,7 +96,7 @@ export default defineConfig({
96
96
  })
97
97
  ```
98
98
 
99
- client/app.tsx should look like:
99
+ `client/app.tsx` should look like:
100
100
  ```tsx
101
101
  import { Route } from "@bananacool467/authtics-host";
102
102
  import Index from "./pages/index";
@@ -110,7 +110,7 @@ export default function App() {
110
110
  }
111
111
  ```
112
112
 
113
- client/pages/index.tsx should look like:
113
+ `client/pages/index.tsx` should look like:
114
114
  ```tsx
115
115
  export default function Index () {
116
116
  return (
@@ -119,14 +119,14 @@ export default function Index () {
119
119
  }
120
120
  ```
121
121
 
122
- ## To run the project
122
+ ## To Run The Project
123
123
 
124
- Make sure Node 22 is installed:
124
+ Make sure **Node 22** is installed:
125
125
  ```
126
126
  nvm install 22
127
127
  ```
128
128
 
129
- To switch to Node 22 use:
129
+ To switch to **Node 22** use:
130
130
  ```
131
131
  nvm use 22
132
132
  ```
@@ -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 clickable Developer 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 The Developer Of Authtics Host
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
@@ -110,6 +110,20 @@ export default class App {
110
110
  server;
111
111
  constructor() {
112
112
  this.server = start();
113
+ this.post('/__authtics_host_apis__/get-dat-matching', async (req, res) => {
114
+ const reqBody = (await getJsonBody(req));
115
+ let datMatched = false;
116
+ if (config_.dat && config_.dat == reqBody.dat)
117
+ datMatched = true;
118
+ if (config_.dat == undefined)
119
+ datMatched = true;
120
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
121
+ datMatched = true;
122
+ res.writeHead(200, { "Content-Type": "application/json" });
123
+ res.end(JSON.stringify({
124
+ isMatching: datMatched
125
+ }));
126
+ });
113
127
  this.post('/__authtics_host_apis__/get-cpu_memory', async (req, res) => {
114
128
  const reqBody = (await getJsonBody(req));
115
129
  let datMatched = false;
@@ -233,6 +247,27 @@ export default class App {
233
247
  }));
234
248
  }
235
249
  });
250
+ this.post("/__authtics_host_apis__/get-host-ver", async (req, res) => {
251
+ const reqBody = (await getJsonBody(req));
252
+ let datMatched = false;
253
+ if (config_.dat && config_.dat == reqBody.dat)
254
+ datMatched = true;
255
+ if (config_.dat == undefined)
256
+ datMatched = true;
257
+ if (config_.dat && Array.isArray(config_.dat) && config_.dat.includes(reqBody.dat))
258
+ datMatched = true;
259
+ if (datMatched) {
260
+ const packageJsonPath = path.join(__dirname, '../package.json');
261
+ let packageJson;
262
+ if (fs.existsSync(packageJsonPath))
263
+ packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
264
+ const packageJsonVersion = packageJson.version || "Unknown";
265
+ res.writeHead(200, { "Content-Type": "application/json" });
266
+ res.end(JSON.stringify({
267
+ version: packageJsonVersion
268
+ }));
269
+ }
270
+ });
236
271
  this.post("/__authtics_host_apis__/get-file-by-pathname", async (req, res) => {
237
272
  const reqBody = (await getJsonBody(req));
238
273
  let datMatched = false;
@@ -244,12 +279,14 @@ export default class App {
244
279
  datMatched = true;
245
280
  if (datMatched) {
246
281
  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);
282
+ const pagesDir = config_.autoPage === true ? path.join(process.cwd(), config_.autoPageDir || "") : undefined;
283
+ const safePath = path.normalize(pathname).replace(/^(\.\.[\/\\])+/, '');
284
+ const filePath = pagesDir ? path.join(pagesDir, safePath + ".tsx") : undefined;
285
+ const fileExists = filePath ? fs.existsSync(filePath) : true;
249
286
  res.writeHead(200, { "Content-Type": "application/json" });
250
287
  res.end(JSON.stringify({
251
288
  fileExists,
252
- filePath
289
+ filePath: (filePath ? filePath : "Cannot find file because autoPage is disabled.")
253
290
  }));
254
291
  }
255
292
  });
@@ -302,7 +339,7 @@ export default class App {
302
339
  const notFoundPath = path.join(__dirname, '404.js');
303
340
  if (fs.existsSync(notFoundPath)) {
304
341
  try {
305
- let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload);
342
+ let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload, (config_.autoPage != false));
306
343
  res.setHeader("Content-Type", "text/html");
307
344
  res.writeHead(404);
308
345
  html = html.replace("<script>", "<script>\nwindow.__status_code__ = 404;");
@@ -357,19 +394,25 @@ async function start() {
357
394
  console.log(JSON.stringify(config));
358
395
  const PORT = config.port ?? 3000;
359
396
  const showPanel = config.devMode !== false;
397
+ const autoPaging = config.autoPage !== false;
360
398
  const compiler = config.compilerType === 'babel' ? 'babel' : 'esbuild';
361
399
  const hotReload = config.hotReload === true;
362
400
  const pagesDir = config.autoPage === true ? path.join(process.cwd(), config.autoPageDir || "") : undefined;
363
401
  const publicDir = config.autoFile === true ? path.join(process.cwd(), config.autoFileDir || "") : undefined;
364
402
  const apiDir = pagesDir ? path.join(pagesDir, "api") : undefined;
365
403
  const server = createServer(async (req, res) => {
404
+ //const body = await getJsonBody(req) as any;
405
+ const actuallyShowPanel = showPanel; /* && (config.dat != undefined ? (body.dat == config.dat || (Array.isArray(config.dat) && config.dat.includes(body.dat))) : true)*/
366
406
  const r = augmentRes(res);
367
407
  const { url = "/", method } = req;
368
408
  // Strip query string, hash, trailing slash
369
409
  let pathname = url.split("?")[0].split("#")[0];
370
410
  if (pathname !== "/" && pathname.endsWith("/"))
371
411
  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") {
412
+ /*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") {
413
+ totalRequests++;
414
+ }*/
415
+ if (!pathname.includes('/__authtics_host_apis__/')) {
373
416
  totalRequests++;
374
417
  }
375
418
  // ── 1. Registered routes (from app.get/post/etc.) ──────────────────────
@@ -444,7 +487,7 @@ async function start() {
444
487
  const htmlPath = pagesDir ? path.join(pagesDir, `${urlPath}.html`) : undefined;
445
488
  if (tsxPath && fs.existsSync(tsxPath)) {
446
489
  try {
447
- const html = await renderPage(tsxPath, url, showPanel, compiler, hotReload);
490
+ const html = await renderPage(tsxPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
448
491
  res.setHeader("Content-Type", "text/html");
449
492
  return res.end(html);
450
493
  }
@@ -465,7 +508,7 @@ async function start() {
465
508
  const appPath = path.join(process.cwd(), appTsxPath);
466
509
  if (fs.existsSync(appPath)) {
467
510
  try {
468
- const html = await renderPage(appPath, url, showPanel, compiler, hotReload);
511
+ const html = await renderPage(appPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
469
512
  res.setHeader("Content-Type", "text/html");
470
513
  return res.end(html);
471
514
  }
@@ -480,7 +523,7 @@ async function start() {
480
523
  const notFoundPath = path.join(__dirname, '404.js');
481
524
  if (fs.existsSync(notFoundPath)) {
482
525
  try {
483
- let html = await renderPage(notFoundPath, url, showPanel, compiler, hotReload);
526
+ let html = await renderPage(notFoundPath, url, actuallyShowPanel, compiler, hotReload, autoPaging);
484
527
  res.setHeader("Content-Type", "text/html");
485
528
  res.writeHead(404);
486
529
  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 ?? '';
@@ -194,12 +194,14 @@ export default function DevPanel() {
194
194
  const [isSsr, setIsSsr] = useState(false);
195
195
  const cpuUsage = useRef(0);
196
196
  const heapUsage = useRef(0);
197
+ const [datMatch, setDatMatch] = useState(false);
197
198
  const [compilerType, setCompilerType] = useState("?");
198
199
  const [errorDetail, setErrorDetail] = useState(undefined);
199
200
  const [httpVersion, setHttpVersion] = useState("v?.?");
200
201
  const [errorBoxOpenable, setErrorBoxOpenable] = useState(false);
201
202
  const [uptime, setUptime] = useState("00:00:00:00");
202
203
  const [requests, setRequests] = useState(0);
204
+ const [hostVersion, setHostVersion] = useState("Loading...");
203
205
  const [users, setUsers] = useState(0);
204
206
  const [token, setToken] = useState(null);
205
207
  const [tokenLength, setTokenLength] = useState(0);
@@ -476,6 +478,20 @@ useEffect(() => {
476
478
  setPath(data.filePath);
477
479
  }
478
480
  };
481
+ const getDatMatching = async () => {
482
+ const resp = await fetch('/__authtics_host_apis__/get-dat-matching', {
483
+ method: 'POST',
484
+ headers: { 'Content-Type': 'application/json' },
485
+ body: JSON.stringify({ dat: localStorage.getItem('dat') })
486
+ });
487
+ if (resp.status === 200) {
488
+ const data = await resp.json();
489
+ setDatMatch(data.isMatching);
490
+ if (!data.isMatching) {
491
+ doc?.getElementById('authtics-dev-panel-root')?.remove();
492
+ }
493
+ }
494
+ };
479
495
  const isSSR = async () => {
480
496
  const resp = await fetch('/__authtics_host_apis__/get-is-ssr', {
481
497
  method: 'POST',
@@ -499,6 +515,17 @@ useEffect(() => {
499
515
  heapUsage.current = data.heapUsed;
500
516
  }
501
517
  };
518
+ const getHostVersion = async () => {
519
+ const resp = await fetch('/__authtics_host_apis__/get-host-ver', {
520
+ method: 'POST',
521
+ headers: { 'Content-Type': 'application/json' },
522
+ body: JSON.stringify({ dat: localStorage.getItem('dat') })
523
+ });
524
+ if (resp.status === 200) {
525
+ const data = await resp.json();
526
+ setHostVersion(data.version);
527
+ }
528
+ };
502
529
  const getCompilerType = async () => {
503
530
  const resp = await fetch('/__authtics_host_apis__/get-compiler', {
504
531
  method: 'POST',
@@ -559,6 +586,8 @@ useEffect(() => {
559
586
  getHttpVersion();
560
587
  isSSR();
561
588
  userSettings();
589
+ getHostVersion();
590
+ getDatMatching();
562
591
  setInterval(() => {
563
592
  getUsage();
564
593
  }, 250);
@@ -1088,15 +1117,6 @@ useEffect(() => {
1088
1117
  border: '1px solid #eee',
1089
1118
  fontSize: '12px',
1090
1119
  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
1120
  }, 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
1121
  padding: '6px 8px',
1102
1122
  borderBottom: '1px solid #ddd',
@@ -1113,7 +1133,7 @@ useEffect(() => {
1113
1133
  border: '1px solid #eee',
1114
1134
  fontSize: '12px',
1115
1135
  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: {
1136
+ }, children: [_jsx("span", { style: { fontSize: '12px', color: '#333' }, children: "Version" }), _jsxs("span", { style: { fontSize: '12px', color: 'blue' }, children: ["v", hostVersion] })] }), _jsxs("div", { style: {
1117
1137
  display: 'flex',
1118
1138
  justifyContent: 'space-between',
1119
1139
  padding: '6px 10px',
@@ -1133,7 +1153,7 @@ useEffect(() => {
1133
1153
  color: '#333',
1134
1154
  cursor: 'pointer',
1135
1155
  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: {
1156
+ }, 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
1157
  padding: '6px 8px',
1138
1158
  borderBottom: '1px solid #ddd',
1139
1159
  background: '#fff',
@@ -1195,7 +1215,7 @@ useEffect(() => {
1195
1215
  gap: '6px',
1196
1216
  color: '#fff',
1197
1217
  flexDirection: 'row',
1198
- }, children: [_jsx(CircleX, { size: 12 }), "Invalid Developer Access Token (DAT)"] }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) })] })] })) }) }), compilerType !== "?" ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1218
+ }, children: [_jsx(CircleX, { size: 12 }), "Invalid Developer Access Token (DAT)"] }) })) : (_jsx(_Fragment, {})), _jsx(PanelButton, { onClick: () => { restart(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Restart App" }) }), _jsx(PanelButton, { onClick: () => { shutDown(); }, fullWidth: true, style: { color: '#fff', justifyContent: 'center', height: '32px', background: '#ba4e4e' }, children: _jsx("span", { style: { display: 'flex', alignItems: 'center', gap: '6px', textAlign: 'center' }, children: "Shut Down App" }) })] })] })) }) }), datMatch ? (_jsxs("div", { onClick: () => setOpen(o => !o), style: {
1199
1219
  display: 'flex',
1200
1220
  flexDirection: 'row',
1201
1221
  alignItems: 'center',
@@ -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.8",
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
- }